繁体   English   中英

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

[英]How to make a Game Object point towards the mouse in Unity? (C#)

我正在创建一个涉及转塔的游戏,它需要“指向”鼠标(即旋转)。 它在3D环境中,但可以鸟瞰。 因此,出于我的目的,我们处于二维环境中。

这是我的代码:

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是2个连续帧之间的时间, Time.deltaTime * lerpSpeed它会每帧更改一次。

因此,要使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. 每次移动时都设置为toRotation (可以沿侧面计算xDeg
  2. fromRotation删除,而是像这样调用Lerp: Lerp(transform.rotation, toRotation,Time.deltaTime * lerpSpeed)

输入和旋转计算不正确。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM