制作大型MMO项目中的相机视角操作
发表于2017-09-30
今天闲下来给大家实现个大型MMORPG项目中都会用到的功能
1.相机跟随玩家
2.左右滑动屏幕 旋转相机
3.上下滑动屏幕或使用鼠标滚轮 缩放相机及调整相机视野
上效果图:
角色移动脚本:
using UnityEngine; using System.Collections; public class MoveController : MonoBehaviour { Transform camera; Animator ani; NavMeshAgent nav; float h, v; Vector3 moveVec; // Use this for initialization void Start () { camera = Camera.main.transform; ani = GetComponent(); nav = GetComponent (); } // Update is called once per frame void Update () { h = Input.GetAxis("Horizontal"); v = Input.GetAxis("Vertical"); moveVec = new Vector3(h, 0, v); if (h != 0 || v != 0) { ani.SetBool("Run", true); // 根据摄像机方向 进行移动 moveVec = Quaternion.Euler(0, camera.eulerAngles.y, 0) * moveVec; nav.Move(moveVec * Time.deltaTime * 5); RotatePlayer(); } else { ani.SetBool("Run", false); } } private void RotatePlayer() { Vector3 vec = Quaternion.Euler(0, 0, 0) * moveVec; Quaternion qua = Quaternion.LookRotation(vec); transform.rotation = Quaternion.Lerp(transform.rotation, qua, Time.deltaTime * 100); } }
相机控制脚本:
using UnityEngine; public class ThirdCamera : MonoBehaviour { public Transform target = null; // 目标玩家 [SerializeField] [Range(0, 360)] float horizontalAngle = 270f; // 水平角度 [SerializeField] [Range(0, 20)] float initialHeight = 2f; // 人物在视野内屏幕中的位置设置 [SerializeField] [Range(10, 90)] float initialAngle = 40f; // 初始俯视角度 [SerializeField] [Range(10, 90)] float maxAngle = 50f; // 最高俯视角度 [SerializeField] [Range(10, 90)] float minAngle = 35f; // 最低俯视角度 float initialDistance; // 初始化相机与玩家的距离 根据角度计算 [SerializeField] [Range(1, 100)] float maxDistance = 20f; // 相机距离玩家最大距离 [SerializeField] [Range(1, 100)] float minDistance = 5f; // 相机距离玩家最小距离 [SerializeField] [Range(1, 100)] float zoomSpeed = 50; // 缩放速度 [SerializeField] [Range(1f, 200)] float swipeSpeed = 50; // 左右滑动速度 float scrollWheel; // 记录滚轮数值 float tempAngle; // 临时存储摄像机的初始角度 Vector3 tempVector = new Vector3(); void Start() { InitCamera(); } void Update() { ZoomCamera(); SwipeScreen(); } void LateUpdate() { FollowPlayer(); RotateCamera(); } ////// 初始化 相机与玩家距离 /// void InitCamera() { tempAngle = initialAngle; initialDistance = Mathf.Sqrt((initialAngle - minAngle) / Calculate()) minDistance; initialDistance = Mathf.Clamp(initialDistance, minDistance, maxDistance); } ////// 相机跟随玩家 /// void FollowPlayer() { float upRidus = Mathf.Deg2Rad * initialAngle; float flatRidus = Mathf.Deg2Rad * horizontalAngle; float x = initialDistance * Mathf.Cos(upRidus) * Mathf.Cos(flatRidus); float z = initialDistance * Mathf.Cos(upRidus) * Mathf.Sin(flatRidus); float y = initialDistance * Mathf.Sin(upRidus); transform.position = Vector3.zero; tempVector.Set(x, y, z); tempVector = tempVector target.position; transform.position = tempVector; tempVector.Set(target.position.x, target.position.y initialHeight, target.position.z); transform.LookAt(tempVector); } ////// 缩放相机与玩家距离 /// void ZoomCamera() { scrollWheel = GetZoomValue(); if (scrollWheel != 0) { tempAngle = initialAngle - scrollWheel * 2 * (maxAngle - minAngle); tempAngle = Mathf.Clamp(tempAngle, minAngle, maxAngle); } if (tempAngle != initialAngle) { initialAngle = Mathf.Lerp(initialAngle, tempAngle, Time.deltaTime * 10); initialDistance = Mathf.Sqrt((initialAngle - minAngle) / Calculate()) minDistance; initialDistance = Mathf.Clamp(initialDistance, minDistance, maxDistance); } } float Calculate() { float dis = maxDistance - minDistance; float ang = maxAngle - minAngle; float line = ang / (dis * dis); return line; } bool isMousePress = false; Vector2 oldMousePos; Vector2 newMousePos; Vector2 mousePosOffset; ////// 滑动屏幕 旋转相机和缩放视野 /// public void SwipeScreen() { if (Input.GetMouseButtonDown(0)) { oldMousePos = Vector2.zero; isMousePress = true; } else if(Input.GetMouseButtonUp(0)) { mousePosOffset = Vector2.zero; isMousePress = false; } if (!isMousePress) return; newMousePos = Input.mousePosition; if(oldMousePos != Vector2.zero) { mousePosOffset = newMousePos - oldMousePos; } oldMousePos = newMousePos; } ////// 获取缩放视野数值 1.鼠标滚轮 2.屏幕上下滑动 /// ///float GetZoomValue() { float zoomValue = 0; // 使用鼠标滚轮 if (Input.GetAxis("Mouse ScrollWheel") != 0) { zoomValue = Input.GetAxis("Mouse ScrollWheel"); } else if (mousePosOffset != Vector2.zero) { zoomValue = mousePosOffset.y * Time.deltaTime * zoomSpeed * 0.01f; } return zoomValue; } float xVelocity = 0; /// /// 旋转相机 /// void RotateCamera() { horizontalAngle = Mathf.SmoothDamp(horizontalAngle, horizontalAngle mousePosOffset.x * Time.deltaTime * swipeSpeed, ref xVelocity, 0.1f); } }
相机参数已测试参考值:
项目使用版本:Unity5.3.4 GitHub下载地址:
https://github.com/654306663/CameraOperate
- 本文固定链接: http://www.u3d8.com/?p=1235
- 转载请注明: 网虫虫 在 u3d8.com 发表过