Unity 2D C# 如何在单击时使对象面向坐标
Unity 2D C# How can I can make object facing coordinates on click
我想为 unity (2D) 制作一个简单的 C# 脚本。我想按照我用鼠标单击的方向缓慢旋转一个对象(图像)。我一直在寻找它,只找到了如何在已知方向上缓慢旋转它,以及如何在我点击的地方旋转,但速度并不慢。我试图将这两种机制结合起来,但没有任何效果。这是我当前的代码:
Vector2 direction = new Vector2(0.0f, 0.0f);
void Update()
{
if (Input.GetMouseButtonDown(0))
{
destinationX = clicked('x');
destinationY = clicked('Y');
direction = new Vector2(clicked('x') - transform.position.x, clicked('y') - transform.position.y);
}
transform.Rotate(new Vector3() * Time.deltaTime * 10.2f, Space.World);
transform.position += transform.forward * Time.deltaTime * 0.2f;
}
float clicked(char axis)
{
if (axis == 'x')
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
}
else
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition).y;
}
}
我知道它变得非常混乱,我不知道是否所有东西都被使用了,因为我在寻找答案时失去了理智(这就是我来这里的原因)。
请帮忙,谢谢!
您可以使用Quaternion.Lerp平滑地旋转对象。
transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, Time.time * speed);
您也可以使用Vector3.Lerp作为职位
您正在将 new Vector3()
作为参数传递给 Rotate
。
这等于使用 new Vector3(0,0,0)
所以无论你乘以什么它都会保持 0,0,0
=> 你没有在任何轴上旋转对象。
您可能更想使用例如Mathf.Atan2
这将为您提供 Z 旋转,以便查看相对于对象位置 (== 方向)的位置 X、Y 。
返回值的单位是 弧度 ,因此您还必须将其乘以 Mathf.Rad2Deg
。
现在知道 Z 轴上所需的角度,您可以使用 Quaternion.Euler
从该角度生成 Quaternion
并存储它(= targetRotation)。
最后,您可以使用 Quaternion.RotateTowards
以 线速度 顺畅地旋转目标旋转而不会过冲。
// Adjust these via the Inspector
// In angle per second
[SerializeField] private float rotationSpeed = 10.2f;
// In Units per second
[SerializeField] private float movementSpeed = 0.2f;
// If possible assign via the Inspector
[SerializeField] private Camera _camera;
private void Awake ()
{
// As fallback get ONCE
if(!_camera) _camera = Camera.main;
targetRotation = transform.rotation;
}
private Quaternion targetRotation;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
// Instead of 4 repeated calls store this ONCE
// directly use Vector2, you don't care about the Z axis
Vector2 destination = _camera.ScreenToWorldPoint(Input.mousePosition);
// directly use the Vector2 substraction for getting the direction vector without the Z axis
Vector2 direction = destination - (Vector2)transform.position;
// Use Atan2 to get the target angle in radians
// therefore multiply by Rad2Deg to get degrees
var zAngle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
// Store the target rotation
targetRotation = Quaternion.Euler(0,0, zAngle);
}
// Rotate smoothly with linear rotationSpeed against the targetRotation
// this prevents any overshooting
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
// In 2D you most probably do not want to move forward which is the Z axis but rather e.g. right on the X axis
transform.position += transform.right * Time.deltaTime * movementSpeed;
}
我想为 unity (2D) 制作一个简单的 C# 脚本。我想按照我用鼠标单击的方向缓慢旋转一个对象(图像)。我一直在寻找它,只找到了如何在已知方向上缓慢旋转它,以及如何在我点击的地方旋转,但速度并不慢。我试图将这两种机制结合起来,但没有任何效果。这是我当前的代码:
Vector2 direction = new Vector2(0.0f, 0.0f);
void Update()
{
if (Input.GetMouseButtonDown(0))
{
destinationX = clicked('x');
destinationY = clicked('Y');
direction = new Vector2(clicked('x') - transform.position.x, clicked('y') - transform.position.y);
}
transform.Rotate(new Vector3() * Time.deltaTime * 10.2f, Space.World);
transform.position += transform.forward * Time.deltaTime * 0.2f;
}
float clicked(char axis)
{
if (axis == 'x')
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition).x;
}
else
{
return Camera.main.ScreenToWorldPoint(Input.mousePosition).y;
}
}
我知道它变得非常混乱,我不知道是否所有东西都被使用了,因为我在寻找答案时失去了理智(这就是我来这里的原因)。
请帮忙,谢谢!
您可以使用Quaternion.Lerp平滑地旋转对象。
transform.rotation = Quaternion.Lerp(from.rotation, to.rotation, Time.time * speed);
您也可以使用Vector3.Lerp作为职位
您正在将 new Vector3()
作为参数传递给 Rotate
。
这等于使用 new Vector3(0,0,0)
所以无论你乘以什么它都会保持 0,0,0
=> 你没有在任何轴上旋转对象。
您可能更想使用例如Mathf.Atan2
这将为您提供 Z 旋转,以便查看相对于对象位置 (== 方向)的位置 X、Y 。
返回值的单位是 弧度 ,因此您还必须将其乘以 Mathf.Rad2Deg
。
现在知道 Z 轴上所需的角度,您可以使用 Quaternion.Euler
从该角度生成 Quaternion
并存储它(= targetRotation)。
最后,您可以使用 Quaternion.RotateTowards
以 线速度 顺畅地旋转目标旋转而不会过冲。
// Adjust these via the Inspector
// In angle per second
[SerializeField] private float rotationSpeed = 10.2f;
// In Units per second
[SerializeField] private float movementSpeed = 0.2f;
// If possible assign via the Inspector
[SerializeField] private Camera _camera;
private void Awake ()
{
// As fallback get ONCE
if(!_camera) _camera = Camera.main;
targetRotation = transform.rotation;
}
private Quaternion targetRotation;
void Update()
{
if (Input.GetMouseButtonDown(0))
{
// Instead of 4 repeated calls store this ONCE
// directly use Vector2, you don't care about the Z axis
Vector2 destination = _camera.ScreenToWorldPoint(Input.mousePosition);
// directly use the Vector2 substraction for getting the direction vector without the Z axis
Vector2 direction = destination - (Vector2)transform.position;
// Use Atan2 to get the target angle in radians
// therefore multiply by Rad2Deg to get degrees
var zAngle = Mathf.Atan2(direction.x, direction.y) * Mathf.Rad2Deg;
// Store the target rotation
targetRotation = Quaternion.Euler(0,0, zAngle);
}
// Rotate smoothly with linear rotationSpeed against the targetRotation
// this prevents any overshooting
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, rotationSpeed * Time.deltaTime);
// In 2D you most probably do not want to move forward which is the Z axis but rather e.g. right on the X axis
transform.position += transform.right * Time.deltaTime * movementSpeed;
}