我正在创建一个涉及炮塔的游戏,它需要“指向”(即旋转)鼠标。这是在三维环境中,但在鸟瞰图中。所以为了我的目的,我们处于二维环境中。
这是我的代码:
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#脚本。
答案 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
可以访问这些变量的地方)和:
toRotation
(xDeg
可以一边计算)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;
}
}