如何在Unity中使游戏对象指向鼠标? (C#)

时间:2015-04-05 13:32:12

标签: c# unity3d

我正在创建一个涉及炮塔的游戏,它需要“指向”(即旋转)鼠标。这是在三维环境中,但在鸟瞰图中。所以为了我的目的,我们处于二维环境中。

这是我的代码:

using UnityEngine;
using System.Collections;

public class Turret : MonoBehaviour {

// Use this for initialization
void Start () {

}

int speed;  float friction;  float lerpSpeed ; private float xDeg ; 
private float yDeg; private Quaternion fromRotation; private Quaternion toRotation;

void Update () { 
    xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y"); 
    fromRotation = transform.rotation; 
    toRotation = Quaternion.Euler(yDeg,xDeg,0); 
    transform.rotation = Quaternion.Lerp(fromRotation,toRotation,Time.deltaTime * lerpSpeed); 
}
}

如果你能告诉我我做错了什么,或者给我正确的代码,那就太好了!请注意,我使用的是C#脚本。

2 个答案:

答案 0 :(得分:0)

我认为这是Unity初学者的一个常见错误(因为我第一次也错了)。

正如您现在可能知道的那样,每个新帧都会调用Update()方法。 因此,您计算鼠标所在的每个新帧(在您的代码中),如何旋转并调用Lerp。

你可能会错过的是Lerp如何工作,并且通过每帧进行一步来插值运动,即每次调用Lerp它会旋转(在你的情况下)一段时间。您的时间间隔为Time.deltaTime * lerpSpeed,因为Time.deltaTime是两个连续帧之间的时间,所以每帧都会更改。

因此,为了使Lerp正常工作(==平滑插值),您必须使用相同的开始和结束位置调用它并完成它们之间的插值(从0到1调用Lerp,并按照您的意愿使用多个间隔)。

我建议您做的是移动此代码:

xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y"); 
fromRotation = transform.rotation; 
toRotation = Quaternion.Euler(yDeg,xDeg,0); 

到另一个地方(Update可以访问这些变量的地方)和:

  1. 每次移动时设置toRotationxDeg可以一边计算)
  2. 删除fromRotation,然后像这样调用Lerp: Lerp(transform.rotation, toRotation,Time.deltaTime * lerpSpeed)

答案 1 :(得分:0)

输入和旋转计算不正确。

xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y"); 
toRotation = Quaternion.Euler(yDeg,xDeg,0); 

你正在进行一场自上而下的比赛。因此,我假设您正在尝试瞄准2D平面上的鼠标点,即地面。您应该不是基于鼠标轴来获取输入,而是考虑鼠标光标所在的位置。

话虽如此,您可以使用此方法来实现目标:

public class CharacterInput : MonoBehaviour
{
    public Transform CharacterTransform;

    void Update()
    {
        var groundPlane = new Plane(Vector3.up, -CharacterTransform.position.y);
        var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        float hitDistance;

        if (groundPlane.Raycast(mouseRay, out hitDistance))
        {
            var lookAtPosition = mouseRay.GetPoint(hitDistance);
            CharacterTransform.LookAt(lookAtPosition, Vector3.up);
        }
    }
}

顺利旋转:

public class CharacterInput : MonoBehaviour
{
    public Transform CharacterTransform;
    public float RotationSmoothingCoef = 0.1f;

    void Update()
    {
        var groundPlane = new Plane(Vector3.up, -CharacterTransform.position.y);
        var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        float hitDistance;

        if (groundPlane.Raycast(mouseRay, out hitDistance))
        {
            var lookAtPosition = mouseRay.GetPoint(hitDistance);
            var targetRotation = Quaternion.LookRotation(lookAtPosition - CharacterTransform.position, Vector3.up);
            var rotation = Quaternion.Lerp(CharacterTransform.rotation, targetRotation, RotationSmoothingCoef);
            CharacterTransform.rotation = rotation;
        }
    }
}

更好地计算FixedUpdate中的平滑,使其独立于每秒帧数。因此它在每个计算机配置上以相同的速度旋转:

public class CharacterInput : MonoBehaviour
{
    public Transform CharacterTransform;
    public float RotationSmoothingCoef = 0.01f;

    private Quaternion targetRotation;

    void Update()
    {
        var groundPlane = new Plane(Vector3.up, -CharacterTransform.position.y);
        var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
        float hitDistance;

        if (groundPlane.Raycast(mouseRay, out hitDistance))
        {
            var lookAtPosition = mouseRay.GetPoint(hitDistance);
            targetRotation = Quaternion.LookRotation(lookAtPosition - CharacterTransform.position, Vector3.up);
        }
    }

    void FixedUpdate()
    {
        var rotation = Quaternion.Lerp(CharacterTransform.rotation, targetRotation, RotationSmoothingCoef);
        CharacterTransform.rotation = rotation;
    }
}