通常3D游戏视角控制有第一人称视角和第三人称视角,其中各有优劣。
第一人称身历其境,但是视野受限,有些人会感觉比较晕。
第三人称视野范围较大,能看清周边全局信息。
在程序设计上,实际第一人称视角比较容易实现,直接将相机放到人物眼睛位置处即可以了。
第三人称视角就相对复杂一些。
常见功能有:
1、鼠标滚轮对视野进行远近缩放。
2、按住鼠标右键时,左右滑动时能控制人物的旋转。
3、按住鼠标右键时,上下滑动时能控制上下视角观察人物。
4、相机跟随人物的移动。
5、旋转和跟随,有一定的缓动效果。
下面实现一下这些功能。
人物移动控制脚本,挂载在角色身上,要求要有角色控制器组件:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class moveController : MonoBehaviour
{
public float speed = 3; //人物移动速度
public float rotatinDamping = 4; //人物旋转的速度
public float mouse1RotateDamping = 4;
public bool cameraIsRotate = true; //判断相机是否跟随人物旋转(点击鼠标左键可观看角色)
private float h1; //点击鼠标右键,存储鼠标X方向位移
private float h2; //点击鼠标左键,存储鼠标X方向位移
float currentOnClickMouse1AngleY = 0; //鼠标右击时人物当前的Y轴度数
float currentCameraAngleY = 0; //鼠标左击时相机当前的Y轴度数
public GameObject cam; //人物后面的相机
private CharacterController characterContro; //角色控制器组件
// Use this for initialization
void Start()
{
characterContro = this.GetComponent<CharacterController>();
cam = GameObject.FindGameObjectWithTag("MainCamera");
}
// Update is called once per frame
void Update()
{
forwardOrBack();
rotate();
mouseControllerRotation();
}
/// <summary>
/// 向前向后移动
/// </summary>
void forwardOrBack()
{
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
characterContro.Move(transform.forward * speed * Time.deltaTime);
}
else
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
characterContro.Move(-transform.forward * speed * Time.deltaTime);
}
}
/// <summary>
/// 按左右旋转
/// </summary>
void rotate()
{
if (Input.GetKey(KeyCode.D))
{
transform.Rotate(Vector3.up * rotatinDamping);
}
if (Input.GetKey(KeyCode.A))
{
transform.Rotate(-Vector3.up * rotatinDamping);
}
}
/// <summary>
/// 鼠标控制旋转
/// </summary>
void mouseControllerRotation()
{
if (Input.GetMouseButtonDown(1))
{
currentOnClickMouse1AngleY = transform.eulerAngles.y;
h1 = 0;
}
if (Input.GetMouseButton(1))
{
h1 += Input.GetAxis("Mouse X") * mouse1RotateDamping;
transform.eulerAngles = new Vector3(transform.eulerAngles.x, h1 + currentOnClickMouse1AngleY, transform.eulerAngles.z);
}
if (Input.GetMouseButtonDown(0))
{
currentCameraAngleY = cam.transform.eulerAngles.y;
h2 = 0;
}
if (Input.GetMouseButton(0))
{
// float currentOnClickMouse1Angle = transform.eulerAngles.y;
cameraIsRotate = false;
h2 += Input.GetAxis("Mouse X") * mouse1RotateDamping;
cam.transform.eulerAngles = new Vector3(cam.transform.eulerAngles.x, h2 + currentCameraAngleY, cam.transform.eulerAngles.z);
}
else
{
cameraIsRotate = true;
}
}
}
相机控制脚本,挂载在Camera上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cameraController : MonoBehaviour
{
private moveController mc; //获取人物控制组件
Transform target; //相机跟随的目标位置
public float rotationDamping = 6; //相机跟随人物的旋转速度
public float zoomSpeed = 4; //鼠标滚轮滑动速度
private float h1; //点击鼠标右键,存储鼠标Y方向位移
private float distance = 0; //相机和目标的距离
//private float height = 1f; //相机和目标的高度
//private float heightDamping = 1;
// Vector3 offsetPosition;
// Use this for initialization
void Start()
{
target = GameObject.FindGameObjectWithTag("Player").transform;
mc = target.gameObject.GetComponent<moveController>();
distance = Vector3.Distance(new Vector3(0, 0, target.position.z), new Vector3(0, 0, transform.position.z));
//offsetPosition = target.position - transform.position;
}
// Update is called once per frame
void Update()
{
//transform.position = target.position - offsetPosition;
flowTarget();
zoomView();
UpAndDownView();
}
/// <summary>
/// 相机跟随人物移动旋转
/// </summary>
void flowTarget()
{
float wantedRotationAngle = target.eulerAngles.y; //要达到的旋转角度
//float wantedHeight = target.position.y + height; //要达到的高度
float currentRotationAngle = transform.eulerAngles.y; //当前的旋转角度
float currentHeight = transform.position.y; //当前的高度
if (mc.cameraIsRotate)
{
currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, rotationDamping * Time.deltaTime);
}
// currentHeight = Mathf.Lerp(currentHeight, wantedHeight, heightDamping * Time.deltaTime); //由当前高度达到要达到的高度
Quaternion currentRotation = Quaternion.Euler(transform.eulerAngles.x, currentRotationAngle, 0);
// float currentRotation=1; //防止主角回头摄像机发生旋转, 这里不用
Vector3 ca = target.position - currentRotation * Vector3.forward * distance; //tt是相机的位置
// transform.position = target.position-currentRotation * Vector3.forward * distance;
transform.position = new Vector3(ca.x, transform.position.y, ca.z); //最后得到的相机位置
transform.rotation = currentRotation; //最后得到相机的旋转角度
// transform.LookAt(target.position);
}
/// <summary>
/// 滚轮控制缩放
/// </summary>
void zoomView()
{
float scrollWheel = Input.GetAxis("Mouse ScrollWheel") * zoomSpeed;
distance -= scrollWheel;
if (distance > 5.6f)
{
distance = 5.6f;
}
if (distance < 0.9f)
{
distance = 0.9f;
}
}
/// <summary>
/// 摄像头上下视角
/// </summary>
void UpAndDownView()
{
if (Input.GetMouseButton(1))
{
h1 = Input.GetAxis("Mouse Y") * rotationDamping;
Vector3 originalPosition = transform.position;
Quaternion originalRotation = transform.rotation;
transform.RotateAround(target.position, -target.right, h1); //决定因素position和rotation
float x = transform.eulerAngles.x;
if (x < -10 || x > 80)
{
transform.position = originalPosition;
transform.rotation = originalRotation;
}
}
}
}
网友评论