【UNITY 3D】第三人称相机的代码实现
一个游戏,少不了摄像机的参与。摄像机,总体来说分为了两大类别:上帝视角,也就是俗称的第三人称视角,以一种凌驾于游戏object的方式存在,玩家跟上帝一般俯瞰整个游戏;主角视角,第一人称视角,以主角的角度观看游戏的发展状态;观察视角,关注于某个物体的视角,这个视角在一些密室逃脱类游戏里经常有。
下面我们来实现一下第三人称相机,
因为不习惯Cinemachine插件,所以自己手写了一个。
eg:其实只是因为我菜不知道怎么用......
相机跟随角色
相机跟随很容易实现

只需将camera作为子物件放在player上即可。
相机随鼠标移动
让我们新建一个C#脚本,并将其加入到Camera中
public class CameraController : MonoBehaviour
{
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
private float mouseX, mouseY;
public float mouseSensitivity;//鼠标灵敏度
public Transform target;//父物体,即player,在脚本界面将player托人即可
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
float nowFlip = transform.localEulerAngles.x + mouseY * mouseSensitivity * Time.deltaTime;
if (nowFlip < 60 || nowFlip > 300) //相机围绕角色上下旋转的角度限定
{
transform.RotateAround(target.transform.position, transform.right, mouseY * mouseSensitivity * Time.deltaTime);//上下旋转
}
transform.RotateAround(target.transform.position, Vector3.up, mouseX * mouseSensitivity * Time.deltaTime);//左右旋转
}
}
角色朝向随镜头方向改变
接下来我们想让Player在移动时,w方向始终朝向镜头方向,且模型朝向随键盘输入的移动方向改变,
下面我们对C#脚本进行完善
//将其相应进行添加进行
private float hMove;
private float vMove;
private Vector3 rot, myRot, myPos;
void LateUpdate() //角色跟随键盘操作转向,放到Lateupdate中防止了Player模型抖动
{
hMove = Input.GetAxis("Horizontal") ;
vMove = Input.GetAxis("Vertical") ;
myRot = transform.eulerAngles;
myPos = transform.position;
rot = target.eulerAngles;
//根据Horizontal与Vertical来判断Player朝向
if (vMove > 0)
if (hMove == 0)
{
rot.y = transform.eulerAngles.y;
}
else
{
rot.y = transform.eulerAngles.y + Mathf.Atan2(hMove, vMove) * 180 / Mathf.PI;
if (rot.y < 0)
rot.y += 360;
else if (rot.y >= 360)
rot.y -= 360;
}
else if (vMove < 0)
if (hMove == 0)
{
rot.y = transform.eulerAngles.y + 180;
if (rot.y >= 360)
rot.y -= 360;
}
else
{
rot.y = transform.eulerAngles.y + Mathf.Atan2(hMove, vMove) * 180 / Mathf.PI;
if (rot.y < 0)
rot.y += 360;
else if (rot.y >= 360)
rot.y -= 360;
}
else
if (hMove > 0)
{
rot.y = transform.eulerAngles.y + 90;
if (rot.y >= 360)
rot.y -= 360;
}
else if (hMove < 0)
{
rot.y = transform.eulerAngles.y - 90;
if (rot.y < 0)
rot.y += 360;
}
target.eulerAngles = rot;
transform.eulerAngles = myRot;
transform.position = myPos;
}
接下来在你的控制角色移动的脚本中加入下面的代码
private Vector3 rot, myRot, myPos;
public Transform cam;//将相机拖入
void move()//检测移动操作后使角色朝向更改为相机朝向,并执行移动操作
//使角色移动操作不会受到影响
{
if (Input.GetAxis("Horizontal")!= 0 || Input.GetAxis("Vertical") != 0)
{
myRot = cam.eulerAngles;
myPos = cam.position;
rot = transform.eulerAngles;
rot.y = transform.eulerAngles.y;
transform.eulerAngles = rot;
cam.eulerAngles = myRot;
cam.position = myPos;
}
//
//这里写你原本角色move操作的代码
//
}
鼠标滚轮实现场景缩放
让我们在camera脚本中继续添加如下代码
public float m_sSpeed;//滚轮灵敏度
public float m_maxDistance, m_minDistance;//最大,最小视野距离
void Update()
{
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
float m_distance = Input.GetAxis("Mouse ScrollWheel") * m_sSpeed;
Vector3 oldPos = transform.localPosition;
Vector3 newPos = transform.position + transform.forward * m_distance;
transform.position = newPos;
if (transform.localPosition.magnitude >= m_maxDistance || transform.localPosition.magnitude <= m_minDistance)
transform.localPosition = oldPos;
}
}
完整代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CameraController : MonoBehaviour
{
private float mouseX, mouseY;
public float mouseSensitivity;
public Transform target;
public float m_sSpeed;
public float m_maxDistance, m_minDistance;
private float hMove;
private float vMove;
private Vector3 rot, myRot, myPos;
void LateUpdate()
{
hMove = Input.GetAxis("Horizontal");
vMove = Input.GetAxis("Vertical");
myRot = transform.eulerAngles;
myPos = transform.position;
rot = target.eulerAngles;
if (vMove > 0)
if (hMove == 0)
{
rot.y = transform.eulerAngles.y;
}
else
{
rot.y = transform.eulerAngles.y + Mathf.Atan2(hMove, vMove) * 180 / Mathf.PI;
if (rot.y < 0)
rot.y += 360;
else if (rot.y >= 360)
rot.y -= 360;
}
else if (vMove < 0)
if (hMove == 0)
{
rot.y = transform.eulerAngles.y + 180;
if (rot.y >= 360)
rot.y -= 360;
}
else
{
rot.y = transform.eulerAngles.y + Mathf.Atan2(hMove, vMove) * 180 / Mathf.PI;
if (rot.y < 0)
rot.y += 360;
else if (rot.y >= 360)
rot.y -= 360;
}
else
if (hMove > 0)
{
rot.y = transform.eulerAngles.y + 90;
if (rot.y >= 360)
rot.y -= 360;
}
else if (hMove < 0)
{
rot.y = transform.eulerAngles.y - 90;
if (rot.y < 0)
rot.y += 360;
}
target.eulerAngles = rot;
transform.eulerAngles = myRot;
transform.position = myPos;
}
// Update is called once per frame
void Update()
{
mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;
float nowFlip = transform.localEulerAngles.x + mouseY * mouseSensitivity * Time.deltaTime;
if (nowFlip < 60 || nowFlip > 300)
{
transform.RotateAround(target.transform.position, transform.right, mouseY * mouseSensitivity * Time.deltaTime);
}
transform.RotateAround(target.transform.position, Vector3.up, mouseX * mouseSensitivity * Time.deltaTime);
//鼠标滚轮场景缩放;
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
float m_distance = Input.GetAxis("Mouse ScrollWheel") * m_sSpeed;
Vector3 oldPos = transform.localPosition;
Vector3 newPos = transform.position + transform.forward * m_distance;
transform.position = newPos;
if (transform.localPosition.magnitude >= m_maxDistance || transform.localPosition.magnitude <= m_minDistance)
transform.localPosition = oldPos;
}
}
}
注意不要忘记修改你的人物操作代码!!!!!代码在角色朝向随镜头方向改变中!!!
最终效果

看起来还是很不错的、emmmmm

浙公网安备 33010602011771号