我已经尝试了一段时间,以使2D玩家能够像子弹一样一直向前移动(在这种情况下,向前是GameObject的局部X轴,因为这就是角色的方式),并且只有在您触摸屏幕上的某个点时才会改变方向,在这种情况下,它应该会平滑地开始朝该点旋转。
我遇到的一个问题是,我无法使角色在以前面对的最后一个方向上以恒定的速度平稳地移动,而我发现的另一个问题是角色正在转动错误的轴,而不是一直基于Z轴旋转,而是始终沿Y轴旋转,这使得子画面对于相机是不可见的。
这是我现在拥有的代码:
Vector3 lastTouchPoint;
private void Start()
{
lastTouchPoint = transform.position;
}
void Update()
{
if (Input.touchCount > 0)
{
// The screen has been touched so store the touch
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
{
// If the finger is on the screen, move the object smoothly to the touch position
lastTouchPoint = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10));
}
}
transform.position = Vector3.Lerp(transform.position, lastTouchPoint, Time.deltaTime);
//Rotate towards point
Vector3 targetDir = lastTouchPoint - transform.position;
transform.LookAt(lastTouchPoint);
}
谢谢!
答案 0 :(得分:0)
保持角色以恒定的速度平稳移动
您可能不了解Lerp
的实际含义:在给定因子的两个位置之间进行插值,其中0
完全表示第一个位置,1
表示最后一个位置和例如0.5f
的意思是两个位置之间的中心。
如果两个位置之间的距离越远,则导致速度越快,并且变得越来越慢。在某些情况下,尤其是与您的情况一样小的因素,该对象甚至可能从未真正到达目标位置。
将其与动态因子Time.deltaTime
一起使用是没有意义的,因为该值会每帧更改一次,并在0,017
周围某个地方抖动(假定为60 FPS)。
您宁愿以固定的恒定速度使用Vector3.MoveTowards
// set via the Inspector
public float speedInUnitsPerSecond = 1;
...
transform.position = Vector3.MoveTowards(transform.position, lastTouchPoint, Time.deltaTime * speedInUnitsPerSecond);
如果您想继续移动,请但是在到达触摸位置后停止。
如果您想继续沿正确的方向移动,则无论如何都可以存储方向而不是位置,并使用简单的Transform.Translate
// set via the Inspector
public float speedInUnitsPerSecond = 1;
private Vector2 lastDirection;
privtae void Update()
{
...
// If the finger is on the screen, move the object smoothly to the touch position
var touchPosition = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10));
lastDirection = (touchPosition - transform.position).normalized;
...
// move with constant speed in the last direction
transform.Translate(lastDirection * Time.deltaTime * speedInUnitsPerSecond);
...
}
角色绕错误的轴旋转,而不是基于Z轴旋转,而是始终沿Y轴旋转
请注意,Transform.LookAt
有一个optional第二个参数worldUp
,默认情况下为Vector3.up
,因此绕全局Y
轴旋转!
由于您希望绕Z
轴旋转,因此应该通过
transform.LookAt(lastTouchPoint, Vector3.forward);
我不知道您的课程设置,但请注意
LookAt
旋转变换,使正向向量指向
worldPosition
。
正如您所描述的,也可能不希望对象的前向矢量指向目标位置,而是实际上是对象正确的(X)向量!
您可以通过直接设置transform.right
来实现此目的,例如
transform.right = (lastTouchPoint - transform.position).normalized;
或
transform.right = lastDirection;
实际上只需设置一次旋转就足够了,也就是它改变的那一刻
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
{
// If the finger is on the screen, move the object smoothly to the touch position
lastTouchPoint = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10));
transform.right = (lastTouchPoint - transform.position).normalized;
}
或
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved)
{
// If the finger is on the screen, move the object smoothly to the touch position
var touchPosition = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10));
lastDirection = (touchPosition - transform.position).normalized;
transform.right = lastDirection;
}
答案 1 :(得分:0)
我最终使用代码从另一个帖子中顺利轮换找到了自己的问题的答案。这是代码:
Vector3 lastTouchPoint;
Vector3 direction;
Vector3 vectorToTarget;
//Character controller variables
public float moveSpeed = 5f;
public float angularSpeed = 3f;
private void Start()
{
lastTouchPoint = transform.position;
}
void Update()
{
if (Input.touchCount > 0)
{
// The screen has been touched so store the touch
Touch touch = Input.GetTouch(0);
if (touch.phase == TouchPhase.Began)
{
// If the finger is on the screen, move the object smoothly to the touch position
lastTouchPoint = Camera.main.ScreenToWorldPoint(new Vector3(touch.position.x, touch.position.y, 10));
direction = lastTouchPoint - transform.position;
vectorToTarget = lastTouchPoint - transform.position;
}
}
transform.position += direction.normalized * moveSpeed * Time.deltaTime;
float angle = Mathf.Atan2(vectorToTarget.y, vectorToTarget.x) * Mathf.Rad2Deg;
Quaternion q = Quaternion.AngleAxis(angle, Vector3.forward);
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * angularSpeed);
}