Unity C#:使用自动定位的摄像机控制&鼠标外观

时间:2018-06-01 16:06:53

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

我通常不会在这里发帖,但现在我花了几个小时试图解决这个问题,而且我已经搜索了网但却找不到答案。我希望有人能在这里帮助我。我是新手,这是我第一次尝试将两种类型的第三人称相机控制结合在 Unity C#中的玩家运动之后:

  1. 相机在播放器移动时捕捉到预定位置和旋转(无鼠标外观)
  2. 当按住鼠标按钮时,鼠标外观会激活,因此无论玩家的位置是否正在改变,相机都会根据鼠标移动进行旋转
  3. 它几乎可以工作,除了我似乎无法将鼠标外观重置为其首次预定义的设置。播放器释放鼠标按钮后,#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);
    
            }
    
        }
    
    }
    

1 个答案:

答案 0 :(得分:0)

更新: 试试这个

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()

中添加了一个位置Lerp到想要的lookAround位置

编辑:

  

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

尝试此更改

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