【问题标题】:Unity C#: Camera Control Using Automatic Positioning & Mouse LookUnity C#:使用自动定位和鼠标查看的相机控制
【发布时间】:2018-06-01 16:06:53
【问题描述】:

我通常不在这里发帖,但现在我花了几个小时试图弄清楚这一点,我已经在网上搜索过,但找不到答案。我希望有人可以在这里帮助我。我是新手,这是我第一次尝试在 Unity C# 中结合两种类型的 第三人称摄像机控制 跟随玩家运动:

  1. 当玩家移动时,相机会捕捉到预定义的位置和旋转(不看鼠标)
  2. 当鼠标按钮被按住时,鼠标注视会激活,因此无论玩家的位置是否发生变化,相机都会根据鼠标移动而旋转

它几乎可以正常工作,只是我似乎无法将鼠标外观重置为其第一个预定义设置。播放器释放鼠标按钮后,#1 的代码启动,因此相机似乎回到了默认视图。但是做进一步的鼠标看,我注意到相机总是返回到它被停用的最后一个位置和旋转。即使在玩家激活他的第一个鼠标外观之前,我也需要它回到原来的预定义位置和旋转,这样它就不会让玩家迷失方向。

我尝试了几个代码,但无法让它工作,所以我删除了非工作行,只发布了我认为适用的行。请参考我下面的代码。如果有人可以帮助我,将不胜感激。提前致谢!

编辑:更新了代码以具有两种控制相机的方法,并添加了重置当前 X 和 Y 值的建议代码。注释/取消注释每个要测试的方法调用。但是我仍然有无法平滑鼠标外观缩放的问题。

最终编辑:我再次更新了下面的代码,对其进行了清理,并包含了建议的更改。代码现在应该可以完全正常工作并且没有抖动。感谢您的帮助! :-)

最后的最终编辑:添加了鼠标滚轮的“视野缩放”,因此完成了代码。

using UnityEngine;
using System.Collections;

public class PlayerViewController : MonoBehaviour {

    // General Vars
    public Transform targetFollow;
    private bool lookAround = false;

    // For SmoothDampFollow
    public Vector3 followDefaultDistance = new Vector3 (0f, 12.0f, -20f);
    public float followDistanceDamp = 0.2f;
    public Vector3 followVelocity = Vector3.one;

    // For Camera Orbit
    public float orbitDistance = 20.0f;
    public float orbitDamp = 5.0f;
    private const float angleMinY = 7.0f;
    private const float angleMaxY = 50.0f;    
    private float currentX = 7.0f;
    private float currentY = 50.0f;

    // For Zooming Field Of View
    public float FOVmin = 50.0f;
    public float FOVmax = 100.0f;
    public float mouseWheelSpeed = 5.0f;

    void Update () {

        if (Input.GetMouseButtonDown (1)) {

            currentX = transform.eulerAngles.y;
            currentY = transform.eulerAngles.x;

        }

        if (Input.GetMouseButton (1)) {

            lookAround = true;

        } else {

            lookAround = false;

        }

        ZoomFOV ();

    }

    void FixedUpdate () {

        if (lookAround) {

            CameraOrbit ();

        } else {

            SmoothDampFollow ();

        }

    }

    void ZoomFOV () {

        if (Input.GetAxis ("Mouse ScrollWheel") > 0) {

            GetComponent<Camera> ().fieldOfView =  GetComponent<Camera> ().fieldOfView - mouseWheelSpeed;

            if (GetComponent<Camera> ().fieldOfView <= FOVmin) { GetComponent<Camera> ().fieldOfView = FOVmin; }

        } else if (Input.GetAxis ("Mouse ScrollWheel") < 0) {

            GetComponent<Camera> ().fieldOfView = GetComponent<Camera> ().fieldOfView + mouseWheelSpeed;

            if (GetComponent<Camera> ().fieldOfView >= FOVmax) { GetComponent<Camera> ().fieldOfView = FOVmax; }

        }

    }

    void SmoothDampFollow () {

        if (!targetFollow) {

            return;

        } else {

            Vector3 wantedPosition = targetFollow.position + (targetFollow.rotation * followDefaultDistance);
            transform.position = Vector3.SmoothDamp (transform.position, wantedPosition, ref followVelocity, followDistanceDamp);
            transform.LookAt (targetFollow, targetFollow.up);

        }

    }

    void CameraOrbit () {

        if (!targetFollow) {

            return;

        } else {

            currentX += Input.GetAxis ("Mouse X");
            currentY += Input.GetAxis ("Mouse Y");
            currentY = Mathf.Clamp (currentY, angleMinY, angleMaxY);
            Vector3 dir = new Vector3 (0, 0, -orbitDistance);
            Quaternion rotation = Quaternion.Euler (currentY, currentX, 0);
            Vector3 wantedPosition = targetFollow.position + rotation * dir;
            transform.position = Vector3.Lerp (transform.position, wantedPosition, Time.deltaTime * orbitDamp);
            transform.LookAt (targetFollow.position);

        }

    }

}

【问题讨论】:

    标签: c# unity3d camera controls right-mouse-button


    【解决方案1】:

    更新: 试试这个

    void LateUpdate()
    {
    
        if (lookAround)
        {
    
            currentX += Input.GetAxisRaw("Mouse X");
            currentY += Input.GetAxisRaw("Mouse Y");
            currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
            Vector3 dir = new Vector3(0, 0, -distance);
            Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
    
            Vector3 wantedPosition = target.position + rotation * dir;
            transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
    
            camTransform.LookAt(target.position);
    
        }
            ...
    

    void Update()
    {
        // Here
        if (Input.GetMouseButtonDown(1))
        {
            currentX = transform.eulerAngles.y;
            currentY = transform.eulerAngles.x;
        }
        if (Input.GetMouseButton(1))
        { 
            ...
    

    我所做的是在 Update() 中按下鼠标时将 currentX 和 currentY 重置为它们当前的 eulerangle 值。我已经在 LateUpdate() 中的想要的 lookAround 位置添加了 Lerp 位置

    编辑:

    虽然我还没有修复最初按住鼠标右键时鼠标外观的平滑缩放

    试试这个改变

    void CameraOrbit()
    {
        currentX += Input.GetAxisRaw("Mouse X");
        currentY += Input.GetAxisRaw("Mouse Y");
        currentY = Mathf.Clamp(currentY, angleMinY, angleMaxY);
        Vector3 dir = new Vector3(0, 0, -distance);
        Quaternion rotation = Quaternion.Euler(currentY, currentX, 0);
    
        // -->
        Vector3 wantedPosition = target.position + rotation * dir;
        transform.position = Vector3.Lerp(transform.position, wantedPosition, Time.deltaTime * damping);
        // <--
    
        camTransform.LookAt(target.position);
    }
    

    【讨论】:

    • 实际上,我认为它是第一次起作用,因为播放器从未按住鼠标右键,因此采用了上面设置的原始 currentX 和 currentY 私有默认值。我尝试通过在lookAround为false时添加相同的默认值来重置更新下的currentX和currentY,但在播放器开始移动后它仍然不起作用。
    • 尝试了新的代码行,它们终于可以工作了,但动作变得非常紧张。在播放器移动时以鼠标外观模式查看侧面时尤其明显。所以我坚持使用 LateUpdate 中的旧代码,但在 Update 部分中使用了您的 transform.eulerAngles.x & y 代码,现在可以正确重置鼠标外观中的起始视图。现在的另一个问题是如何在按住鼠标右键时将跳跃的相机变焦转换为平滑的东西。尝试使用 Lerp,但在达到预期的缩放级别后无法结束,导致相机抖动。
    • 我在做更多研究后修改了上面的代码。我已经包含了两种类型的相机控件,只是为了测试抖动并将它们分成两种方法以清晰起见:SmoothDampFollow 和之前的 SmoothFollow。但是我发现将这些代码放在 FixedUpdate 下而不是 LateUpdate 下会以某种方式消除玩家移动时的抖动。 CameraOrbit 没有任何抖动,和以前一样流畅。虽然我还没有修复最初按住鼠标右键时鼠标外观的平滑缩放。
    • 很好,它起作用了,不再紧张!我不得不返回 GetMouseButtonDown 代码部分。更新了上面的最终工作代码并对其进行了一些清理。感谢所有的帮助,非常感谢!
    • 添加了“鼠标滚轮缩放视野”等代码完成。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-07
    • 2014-06-26
    • 2012-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多