介绍
我目前正在尝试创建一个脚本(Unity 中的 C# 脚本)来控制 GameObject 的指向和单击行为。
从本质上讲,玩家最终将通过简单地点击屏幕来控制热气球,由此对象将开始加速并朝着点击位置移动。当在点击位置的特定距离处,热气球应该开始向相反方向加速(因此减速)并完全停止在点击位置。
我已经创建了一个功能齐全的注释脚本(在这篇文章的底部找到),它只是将一个游戏对象以恒定的速度移动到点击的位置,然后,当在特定距离内时,它开始减速直到停在该点。
我还创建了一个单独且功能齐全的脚本,该脚本在加速时向点击位置移动(获得那种小行星推力行为)。这也可以在帖子底部找到。
问题
现在我面临的问题是我已经工作了很长时间来找到一个解决方案,您可以将这两种行为作为一个工作脚本来实现,即热气球具有加速行为,而还减速并停在目标位置,就像在这里找到的这个视觉示例一样:
问题
然后我的问题变成:
你如何才能使到达行为不仅使用恒定速度,而且还包括方程中的加速度?我试图研究这个问题并尝试自己的解决方案,但我所做的一切似乎都没有按照应有的方式工作。
脚本附件
具有到达行为的恒定速度的指向和单击移动
using UnityEngine;
using System.Collections;
public class PlayerControl : MonoBehaviour
{
// Fields
Transform cachedTransform;
Vector3 currentMovementVector;
Vector3 lastMovementVector;
Vector3 currentPointToMoveTo;
Vector3 velocity;
int movementSpeed;
Vector3 clickScreenPosition;
Vector3 clickWorldPosition;
float slowingDistance = 8.0f;
Vector3 desiredVelocity;
float maxSpeed = 1000.0f;
// Use this for initialization
void Start ()
{
cachedTransform = transform;
currentMovementVector = new Vector3(0, 0);
movementSpeed = 50;
currentPointToMoveTo = new Vector3(0, 0);
velocity = new Vector3(0, 0, 0);
}
// Update is called once per frame
void Update ()
{
// Retrive left click input
if (Input.GetMouseButtonDown(0))
{
// Retrive the click of the mouse in the game world
clickScreenPosition = Input.mousePosition;
clickWorldPosition = Camera.main.ScreenToWorldPoint(new Vector3(clickScreenPosition.x, clickScreenPosition.y, 0));
currentPointToMoveTo = clickWorldPosition;
currentPointToMoveTo.z = 0;
// Calculate the current vector between the player position and the click
Vector3 currentPlayerPosition = cachedTransform.position;
// Find the angle (in radians) between the two positions (player position and click position)
float angle = Mathf.Atan2(clickWorldPosition.y - currentPlayerPosition.y, clickWorldPosition.x - currentPlayerPosition.x);
// Find the distance between the two points
float distance = Vector3.Distance(currentPlayerPosition, clickWorldPosition);
// Calculate the components of the new movemevent vector
float xComponent = Mathf.Cos(angle) * distance;
float yComponent = Mathf.Sin(angle) * distance;
// Create the new movement vector
Vector3 newMovementVector = new Vector3(xComponent, yComponent, 0);
newMovementVector.Normalize();
currentMovementVector = newMovementVector;
}
float distanceToEndPoint = Vector3.Distance(cachedTransform.position, currentPointToMoveTo);
Vector3 desiredVelocity = currentPointToMoveTo - cachedTransform.position;
desiredVelocity.Normalize();
if (distanceToEndPoint < slowingDistance)
{
desiredVelocity *= movementSpeed * distanceToEndPoint/slowingDistance;
}
else
{
desiredVelocity *= movementSpeed;
}
Vector3 force = (desiredVelocity - currentMovementVector);
currentMovementVector += force;
cachedTransform.position += currentMovementVector * Time.deltaTime;
}
}
使用加速度但没有到达行为的指向和单击移动
using UnityEngine;
using System.Collections;
public class SimpleAcceleration : MonoBehaviour
{
Vector3 velocity;
Vector3 currentMovementVector;
Vector3 clickScreenPosition;
Vector3 clickWorldPosition;
Vector3 currentPointToMoveTo;
Transform cachedTransform;
float maxSpeed;
// Use this for initialization
void Start ()
{
velocity = Vector3.zero;
currentMovementVector = Vector3.zero;
cachedTransform = transform;
maxSpeed = 100.0f;
}
// Update is called once per frame
void Update ()
{
// Retrive left click input
if (Input.GetMouseButtonDown(0))
{
// Retrive the click of the mouse in the game world
clickScreenPosition = Input.mousePosition;
clickWorldPosition = Camera.main.ScreenToWorldPoint(new Vector3(clickScreenPosition.x, clickScreenPosition.y, 0));
currentPointToMoveTo = clickWorldPosition;
// Reset the z position of the clicking point to 0
currentPointToMoveTo.z = 0;
// Calculate the current vector between the player position and the click
Vector3 currentPlayerPosition = cachedTransform.position;
// Find the angle (in radians) between the two positions (player position and click position)
float angle = Mathf.Atan2(clickWorldPosition.y - currentPlayerPosition.y, clickWorldPosition.x - currentPlayerPosition.x);
// Find the distance between the two points
float distance = Vector3.Distance(currentPlayerPosition, clickWorldPosition);
// Calculate the components of the new movemevent vector
float xComponent = Mathf.Cos(angle) * distance;
float yComponent = Mathf.Sin(angle) * distance;
// Create the new movement vector
Vector3 newMovementVector = new Vector3(xComponent, yComponent, 0);
newMovementVector.Normalize();
currentMovementVector = newMovementVector;
}
// Calculate velocity
velocity += currentMovementVector * 2.0f * Time.deltaTime;
// If the velocity is above the allowed limit, normalize it and keep it at a constant max speed when moving (instead of uniformly accelerating)
if (velocity.magnitude >= (maxSpeed * Time.deltaTime))
{
velocity.Normalize();
velocity *= maxSpeed * Time.deltaTime;
}
// Apply velocity to gameobject position
cachedTransform.position += velocity;
}
}