首页 > 代码库 > [Unity3D 版本5.X]实现一个跟随摄像机,聚焦到客户端主角身上
[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; } } //-----------------------------------------------------------------
[Unity3D 版本5.X]实现一个跟随摄像机,聚焦到客户端主角身上
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。