c# - Unity C# : Camera Control Using Automatic Positioning & Mouse Look

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

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

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

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

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

编辑:更新了代码以提供两种控制相机的方法,并添加了建议的代码以重置当前的 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);

        }

    }

}

最佳答案

更新: 试试这个

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 重置为其当前的欧拉角值。我在 LateUpdate() 中向想要的 lookAround 位置添加了位置 Lerp

编辑:

Though I still haven't fixed the smooth zooming of the mouse look when right mouse button is initially held down

试试这个改变

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

关于c# - Unity C# : Camera Control Using Automatic Positioning & Mouse Look,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50647337/

相关文章:

python - 计算相机内在参数时获取复数

c# - LINQ 如何在 using 语句中延迟执行

C# 代码将使用 for 循环创建的文本框的值传递到另一个页面

c# - 如何获得特定长度的最大数量

c# - 在具有外部Visual Studio版本的Windows(2017)上,无法为PC Standalone生成Unity5项目

c# - 如何使用 TryParseHtmlString 将十六进制转换为颜色(RGBA)

c# - 如何使用按钮统一打开和关闭声音

android - 改变声音的音调但不改变其播放速度unity3d

Android webview 允许使用当前的 Android Studio 访问相机

android - OpenCV Android - 人像模式下的精致相机