如何使游戏对象统一指向鼠标?(C#)

如何使游戏对象统一指向鼠标?(C#),c#,unity3d,C#,Unity3d,我正在创建一个涉及炮塔的游戏,它需要“指向”(即旋转)鼠标。它是在三维环境中,但在鸟瞰下。因此,就我而言,我们处于二维环境中 这是我的密码: using UnityEngine; using System.Collections; public class Turret : MonoBehaviour { // Use this for initialization void Start () { } int speed; float friction; float lerpSpee

我正在创建一个涉及炮塔的游戏,它需要“指向”(即旋转)鼠标。它是在三维环境中,但在鸟瞰下。因此,就我而言,我们处于二维环境中

这是我的密码:

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脚本。

我认为这是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
可以访问这些变量的地方)并:

  • 每次应移动时设置旋转(
    xDeg
    可沿侧面计算)
  • 从旋转中删除
    ,改为如下调用Lerp:
    Lerp(transform.rotation、toRotation、Time.deltaTime*lerpSpeed)

  • 输入和旋转计算不正确

    xDeg -= Input.GetAxis ("Mouse X"); yDeg += Input.GetAxis ("Mouse Y"); 
    toRotation = Quaternion.Euler(yDeg,xDeg,0); 
    
    你在做一个自上而下的游戏。所以我假设你试图瞄准鼠标点在二维平面上的位置,也就是地面。您不应基于鼠标轴获取输入,而应考虑鼠标光标的位置

    也就是说,您可以使用此方法来实现您的目标:

    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;
            }
        }
    }
    
    更好地在FixeUpdate中计算平滑,使其独立于每秒帧数。因此,它在每种计算机配置上都以相同的速度旋转:

    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;
        }
    }
    

    我可以让旋转快一点吗?当然可以。只需从inspector中更改RotationMoothingCoef参数。