zoukankan      html  css  js  c++  java
  • [Unity3D 版本5.X]实现一个跟随摄像机,聚焦到客户端主角身上

    游戏中的摄像机,都是聚焦到客户端主角身上。

    为了实现这个功能,我写了两个脚本,第一个脚本用来控制客户端主角的位置和旋转,使用WSAD键控制主角的前后左右移动,使用鼠标右键控制主角的旋转。

    第二个脚本是根据客户端主角的transform,设置摄像机的transform,使得摄像机聚焦在主角身上。

    这两个脚本都是设置成客户端主角的组件。

    第一个脚本 FiMainPlayerMoveCtrl.cs

    //-----------------------------------------------------------------  
    //1,客户端主角的移动控制,使用WSAD键控制上下左右移动,使用鼠标右键控制旋转。  
    //2,左手坐标系。  
    //3,欧拉角使用的单位是角度,不是弧度。  
    //-----------------------------------------------------------------  
    using System.Collections;  
    using System.Collections.Generic;  
    using UnityEngine;  
    //-----------------------------------------------------------------  
    public class FiMainPlayerMoveCtrl : MonoBehaviour  
    {  
        public float moveSpeed = 30.0f;  
        public float rotateSpeed = 0.2f;  
        public float mouseWheelSpeed = 50.0f;  
      
        public static Vector3 kUpDirection = new Vector3(0.0f, 1.0f, 0.0f);  
      
        //记录角色的旋转角度。  
        //以上方向为轴的旋转角度。  
        private float m_fEulerAngleUpDir = 0.0f;  
        //以右方向为轴的旋转角度。  
        //这个欧拉角不会施加在角色身上,当摄像机聚焦在本角色上时,会施加到摄像机上。  
        private float m_fEulerAngleRightDir = 0.0f;  
        //当摄像机聚焦在本角色上时,记录本角色与摄像机之间的直线距离。  
        private float m_fDistanceFromCamera = 100.0f;  
      
        //控制角色旋转的成员变量。  
        private float m_fLastMousePosX = 0.0f;  
        private float m_fLastMousePosY = 0.0f;  
        private bool m_bMouseRightKeyDown = false;  
      
        //记录本帧内Transform是否发生了变化。  
        //当摄像机聚焦在本角色上时,只有本Transform发生了变化,才更新摄像机的Transform。  
        private bool m_bTransformChanged = false;  
      
        //-----------------------------------------------------------------  
        void Start()  
        {  
            Vector3 kEulerAngles = transform.eulerAngles;  
            m_fEulerAngleRightDir = kEulerAngles.x;  
            m_fEulerAngleUpDir = kEulerAngles.y;  
        }  
        //-----------------------------------------------------------------  
        void Update()  
        {  
            m_bTransformChanged = false;  
      
            //判断旋转  
            if (Input.GetMouseButtonDown(1)) //鼠标右键刚刚按下了  
            {  
                if (m_bMouseRightKeyDown == false)  
                {  
                    m_bMouseRightKeyDown = true;  
                    Vector3 kMousePos = Input.mousePosition;  
                    m_fLastMousePosX = kMousePos.x;  
                    m_fLastMousePosY = kMousePos.y;  
                }  
            }  
            else if (Input.GetMouseButtonUp(1)) //鼠标右键刚刚抬起了  
            {  
                if (m_bMouseRightKeyDown == true)  
                {  
                    m_bMouseRightKeyDown = false;  
                    m_fLastMousePosX = 0;  
                    m_fLastMousePosY = 0;  
                }  
            }  
            else if (Input.GetMouseButton(1)) //鼠标右键处于按下状态中  
            {  
                if (m_bMouseRightKeyDown)  
                {  
                    Vector3 kMousePos = Input.mousePosition;  
                    float fDeltaX = kMousePos.x - m_fLastMousePosX;  
                    float fDeltaY = kMousePos.y - m_fLastMousePosY;  
                    m_fLastMousePosX = kMousePos.x;  
                    m_fLastMousePosY = kMousePos.y;  
      
                    m_fEulerAngleRightDir -= (fDeltaY * rotateSpeed);  
                    m_fEulerAngleUpDir -= -(fDeltaX * rotateSpeed);  
      
                    Vector3 kNewEuler = new Vector3(0.0f, m_fEulerAngleUpDir, 0.0f);  
                    transform.eulerAngles = kNewEuler;  
      
                    m_bTransformChanged = true;  
                }  
            }  
      
            //判断位移  
            float fMoveDeltaX = 0.0f;  
            float fMoveDeltaZ = 0.0f;  
            float fDeltaTime = Time.deltaTime;  
            if (Input.GetKey(KeyCode.A))  
            {  
                fMoveDeltaX -= moveSpeed * fDeltaTime;  
            }  
            if (Input.GetKey(KeyCode.D))  
            {  
                fMoveDeltaX += moveSpeed * fDeltaTime;  
            }  
            if (Input.GetKey(KeyCode.W))  
            {  
                fMoveDeltaZ += moveSpeed * fDeltaTime;  
            }  
            if (Input.GetKey(KeyCode.S))  
            {  
                fMoveDeltaZ -= moveSpeed * fDeltaTime;  
            }  
            if (fMoveDeltaX != 0.0f || fMoveDeltaZ != 0.0f)  
            {  
                Vector3 kForward = transform.forward;  
                Vector3 kRight = Vector3.Cross(kUpDirection, kForward);  
                Vector3 kNewPos = transform.position;  
                kNewPos += kRight * fMoveDeltaX;  
                kNewPos += kForward * fMoveDeltaZ;  
                //把Y值设置成0,只能在平面上移动。  
                kNewPos.y = 0.0f;  
                transform.position = kNewPos;  
      
                m_bTransformChanged = true;  
            }  
      
            float fWheel = Input.GetAxis("Mouse ScrollWheel");  
            if (fWheel != 0.0f)  
            {  
                m_fDistanceFromCamera -= fWheel * mouseWheelSpeed;  
                m_bTransformChanged = true;  
            }  
        }  
        //-----------------------------------------------------------------  
        public float GetEulerAngleRightDir()  
        {  
            return m_fEulerAngleRightDir;  
        }  
        //-----------------------------------------------------------------  
        public float GetEulerAngleUpDir()  
        {  
            return m_fEulerAngleUpDir;  
        }  
        //-----------------------------------------------------------------  
        public float GetDistanceFromCamera()  
        {  
            return m_fDistanceFromCamera;  
        }  
        //-----------------------------------------------------------------  
        public bool IsTransformChanged()  
        {  
            return m_bTransformChanged;  
        }  
    }  
    //-----------------------------------------------------------------  

    第二个脚本 FiCameraControl.cs

    //-----------------------------------------------------------------  
    //1,摄像机要聚焦在GameObjectA上,那么就把本脚本作为一个组件,添加到GameObjectA中。  
    //2,GameObjectA中必须包含 FiMainPlayerMoveCtrl 组件。  
    //3,左手坐标系。  
    //-----------------------------------------------------------------  
    using System.Collections;  
    using System.Collections.Generic;  
    using UnityEngine;  
    //-----------------------------------------------------------------  
    public class FiCameraControl : MonoBehaviour  
    {  
        //本Object必须有一个 FiMainPlayerMoveCtrl 组件。  
        private FiMainPlayerMoveCtrl m_kMainPlayerMoveCtrl = null;  
        //摄像机的 Transform 组件。  
        private Transform m_kMainCameraTransform = null;  
      
        //记录是否为第一帧。  
        //如果是第一帧,必须更新摄像机的Transform,使得摄像机聚焦在本Object上。  
        private bool m_bFirstFrame = true;  
      
        //-----------------------------------------------------------------  
        void Start()  
        {  
            m_kMainPlayerMoveCtrl = GetComponent<FiMainPlayerMoveCtrl>();  
            m_kMainCameraTransform = Camera.main.transform;  
            m_bFirstFrame = true;  
        }  
        //-----------------------------------------------------------------  
        void Update()  
        {  
              
        }  
        //-----------------------------------------------------------------  
        void LateUpdate()  
        {  
            if (m_kMainPlayerMoveCtrl == null)  
            {  
                return;  
            }  
            if (m_kMainPlayerMoveCtrl.IsTransformChanged() == false)  
            {  
                if (m_bFirstFrame == false)  
                {  
                    return;  
                }  
            }  
            m_bFirstFrame = false;  
      
            //设置摄像机的旋转。  
            float fEulerAngleRightDir = m_kMainPlayerMoveCtrl.GetEulerAngleRightDir();  
            float fEulerAngleUpDir = m_kMainPlayerMoveCtrl.GetEulerAngleUpDir();  
            Vector3 kEulerAngle = new Vector3(fEulerAngleRightDir, fEulerAngleUpDir, 0.0f);  
            m_kMainCameraTransform.eulerAngles = kEulerAngle;  
      
            //设置摄像机的位置。  
            Vector3 kPos = transform.position;  
            float fDistance = m_kMainPlayerMoveCtrl.GetDistanceFromCamera();  
            kPos -= m_kMainCameraTransform.forward * fDistance;  
            m_kMainCameraTransform.position = kPos;     
        }  
    }  
    //-----------------------------------------------------------------  
  • 相关阅读:
    安装go语言开发环境
    【Graph】399. Evaluate Division(Medium)
    【Divide and Conquer】53.Maximum Subarray(easy)
    int数组交并差集
    Git强制覆盖本地文件
    Git手动合并
    [转]关于BETA、RC、ALPHA、Release、GA等版本号的意义
    [置顶] java处理office文档与pdf文件(二)
    [置顶] 左联接数据不统一问题
    将博客搬至CSDN
  • 原文地址:https://www.cnblogs.com/oilcode/p/6927964.html
Copyright © 2011-2022 走看看