制作大型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 发表过

