【问题标题】:Unity Rotation of Parent object along 1 Axis父对象沿 1 轴的统一旋转
【发布时间】:2020-03-03 05:11:28
【问题描述】:

我正在开发一款游戏,我目前的障碍是相机旋转。我想让鼠标控制相机,当相机转动时,我也想旋转播放器。但是,我使用的代码会随着播放器完全旋转播放器对象,导致播放器像这样转动:

向前旋转的玩家不仅看起来很奇怪,而且会导致地形出现裁剪问题。如何使我的代码仅沿一个轴旋转播放器,同时允许相机沿任何轴旋转(以允许观众环顾四周,而不会向上或向下旋转播放器对象)。

这是旋转播放器的代码:

Quaternion QT = Quaternion.Euler(_LocalRotation.y, _LocalRotation.x, 0);
    this._XForm_Parent.rotation = Quaternion.Lerp(this._XForm_Parent.rotation, QT, Time.deltaTime * OrbitDampening);

    if (this._XForm_Camera.localPosition.z != this._CameraDistance * -1f)
    {
        this._XForm_Camera.localPosition = new Vector3(0f, 0f, Mathf.Lerp(this._XForm_Camera.localPosition.z, this._CameraDistance * -1f, Time.deltaTime * ScrollDampening));
    }

这是我正在使用的完整脚本:

using System.Collections;

使用 System.Collections.Generic; 使用 UnityEngine;

公共类 CameraOrbit : MonoBehaviour {

protected Transform _XForm_Camera;
protected Transform _XForm_Parent;

protected Vector3 _LocalRotation;
protected float _CameraDistance = 10f;

public float MouseSensitivity = 4f;
public float ScrollSensitvity = 2f;
public float OrbitDampening = 10f;
public float ScrollDampening = 6f;

public bool CameraDisabled = false;


// Use this for initialization
void Start()
{
    this._XForm_Camera = this.transform;
    this._XForm_Parent = this.transform.parent;
}


void LateUpdate()
{
    if (Input.GetKeyDown(KeyCode.LeftShift))
        CameraDisabled = !CameraDisabled;

    if (!CameraDisabled)
    {
        //Rotation of the Camera based on Mouse Coordinates
        if (Input.GetAxis("Mouse X") != 0 || Input.GetAxis("Mouse Y") != 0)
        {
            _LocalRotation.x += Input.GetAxis("Mouse X") * MouseSensitivity;
            _LocalRotation.y += Input.GetAxis("Mouse Y") * MouseSensitivity;

            //Clamp the y Rotation to horizon and not flipping over at the top
            if (_LocalRotation.y < 0f)
                _LocalRotation.y = 0f;
            else if (_LocalRotation.y > 90f)
                _LocalRotation.y = 90f;
        }
        //Zooming Input from our Mouse Scroll Wheel
        if (Input.GetAxis("Mouse ScrollWheel") != 0f)
        {
            float ScrollAmount = Input.GetAxis("Mouse ScrollWheel") * ScrollSensitvity;

            ScrollAmount *= (this._CameraDistance * 0.3f);

            this._CameraDistance += ScrollAmount * -1f;

            this._CameraDistance = Mathf.Clamp(this._CameraDistance, 1.5f, 100f);
        }
    }
    //Actual Camera Rig Transformations
    Quaternion QT = Quaternion.Euler(_LocalRotation.y, _LocalRotation.x, 0);
    this._XForm_Parent.rotation = Quaternion.Lerp(this._XForm_Parent.rotation, QT, Time.deltaTime * OrbitDampening);

    if (this._XForm_Camera.localPosition.z != this._CameraDistance * -1f)
    {
        this._XForm_Camera.localPosition = new Vector3(0f, 0f, Mathf.Lerp(this._XForm_Camera.localPosition.z, this._CameraDistance * -1f, Time.deltaTime * ScrollDampening));
    }


}

}

我的阶层图: (请注意,Player 是一个空对象,包含我所有的脚本和物理组件,而 GFXs 组件只是模型,其中包含一个没有任何物理组件的动画组件。)

【问题讨论】:

    标签: c# unity3d


    【解决方案1】:

    听起来您想要的基本上是围绕其局部 Y 轴旋转播放器,直到它面向与相机相同的方向。您可以使用Vector3.SignedAngle 并通过您关心的轴来了解事物是否朝向相同的方向。这是一些示例代码,应该可以帮助您。

    float turnThresholdDegrees = 15;
    float playerTurnSpeed = 1;
    
    // Get delta angle in degrees on the Y axis between the direction player is facing and the direction camera is facing
    float angleDelta = Vector3.SignedAngle(player.transform.forward, camera.transform.forward, Vector3.up);
    
    // Calculate a rotation speed, clamping it to 0 when the angle delta is < some threshold
    float rotateSpeed = Mathf.Abs(angleDelta) > turnThresholdDegrees ? Mathf.Sign(angleDelta) * playerTurnSpeed : 0;
    
    // Rotate the player around its local Y axis by the rotation speed
    player.transform.Rotate(0, rotateSpeed * Time.deltaTime, 0, Space.Self);
    

    【讨论】:

    • 行 float rotateSpeed = Mathf.Abs(angleDelta) > turnThresholdDegrees : Mathf.Sign(angleDelta) * playerTurnSpeed : 0;抛出一堆错误。您能解释一下我将如何使用此代码使玩家旋转(Y 轴)与相机旋转(Y 轴)匹配吗?
    • 有什么错误?我在没有编译器的情况下写了这个,所以可能会有一些错别字。这应该是非常兼容的,您只需要更改事物的名称即可引用您的相机/播放器转换。因此,在您当前尝试旋转播放器以匹配相机的地方,您应该放置此代码(在必要时替换名称)
    • 这是它的图片 Visual Studio 代码:imgur.com/a/2nYazt2
    • 哎呀,我不小心放了一个:应该有一个?,float rotateSpeed = Mathf.Abs(angleDelta) &gt; turnThresholdDegrees ? Mathf.Sign(angleDelta) * playerTurnSpeed : 0;对此感到抱歉!
    • 顺便说一句,那行只是float rotateSpeed = 0; if (Mathf.Abs(angleDelta) &gt; turnThresholdDegrees) rotateSpeed = Mathf.Sign(angleDelta);的简写
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    相关资源
    最近更新 更多