一:任务需求
二:制作步骤:
要点1:动画控制器
- 创建动画控制器(把对应的动作链接起来)
要点2: 刚体
- 人物-添加刚体(按如下参数设置 如果勾选 is Kinematic 可能会造成穿模现象)
要点3:相机位置的摆放
- 相机(3个):是人物的子节点
- 第一人称 相机要在人物头部前面的位置
- 第三人称 相机在人物后方 看大家自己的喜好设置
- 主摄像机
- 第一人称相机 与 第三人称相机在开始前隐藏,通过代码控制在开始后默认第一人称/第三人称。
- 脚本挂载在人物上
源代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class peoplemove2 : MonoBehaviour
{
//角色的移动速度与相机的旋转速度
private float moveSpeed = 1f;
private float spinSpeed = 1f;
//角色的Transform组件与相机的Transform组件
private Transform m_transform;
private Transform cam_transform;
//第一人称相机的Transform组件与第三人称相机的Transform组件
private Transform tf_transform;
private Transform tt_transform;
//第一人称相机与第三人称相机 --设为公共可以方便再操作面板直接拖动可以使用 但是要使用的脚本或者拖动对象比较多的话建议数组查找对象
public GameObject tfirst;
public GameObject tthrid;
private Vector3 dir;
//角色的动画树组件
private Animator ani;
private void Start()
{
cam_transform = Camera.main.transform;
//这里都是赋值 因为需要两个位置(主摄像机=第一人称相机位置/第三人称相机位置)因此 这里每一个相机位置都要有声明一个变量接收
m_transform = this.transform;
tf_transform = tfirst.transform;
tt_transform = tthrid.transform;
//获取脚本对象的动画树组件
//控制面板每一个组件都可以这样获取你需要的组件名称只需要修改即可;
//语法:变量名 = GetComponent<对应你需要的组件名称>();
ani = GetComponent<Animator>();
//这里默认启用 第三人称相机的方法
first();
}
private void Update()
{
//将光标限制在游戏窗口 按Esc退出
Cursor.lockState = CursorLockMode.Locked;
//鼠标是否隐藏
Cursor.visible = true;
PlayRun();
CameraSpin();
keywordevent();
}
//人物移动
public void PlayRun()
{
float x = Input.GetAxis("Horizontal") * Time.deltaTime * moveSpeed;
float y = Input.GetAxis("Vertical") * Time.deltaTime * moveSpeed;
transform.Translate(x, 0, y);
dir = new Vector3(x, 0, y);
if (dir != Vector3.zero)
{
if (Input.GetKeyDown(KeyCode.J))
{
ani.SetInteger("people", 3);
}
else
{
ani.SetInteger("people", 1);
}
}
else
{
ani.SetInteger("people", 0);
}
}
//人物旋转 +相机旋转
public void CameraSpin()
{
//鼠标上移
float mouX = Input.GetAxis("Mouse X");
//鼠标下移
float mouY = Input.GetAxis("Mouse Y");
//左右旋转(人体旋转,因为相机的位置与她相同)
m_transform.Rotate(new Vector3(0, mouX, 0) * spinSpeed);
//上下旋转(上下旋转,人体不动,所以这时候就只有相机的旋转角度改变)
cam_transform.Rotate(new Vector3(-mouY, 0, 0) * spinSpeed);
//限制旋转角度 --45度
if (CheckAngle(cam_transform.localEulerAngles.x) < -45f)
{
cam_transform.localEulerAngles = new Vector3(-45, 0, 0);
}
if (CheckAngle(cam_transform.localEulerAngles.x) > 30)
{
cam_transform.localEulerAngles = new Vector3(30, 0, 0);
}
}
//由于使用欧拉角,需要将角度转换为显示面板的角度,比较直观
public float CheckAngle(float value)
{
// Debug.Log("v" + value);
float angle = value - 180;
if (angle > 0)
{
return angle - 180;
}
return angle + 180;
}
//第一人称
public void first()
{
tfirst.SetActive(true);
//警用第三人称相机, 把主相机给到第一人称相机
tthrid.SetActive(false);
cam_transform = tf_transform;
cam_transform.position = tf_transform.position;
Debug.Log("tfirst" + tfirst.transform.position);
}
//第三人称
public void third()
{
tthrid.SetActive(true);
//警用第一人称相机, 把主相机给到第三人称相机
tfirst.SetActive(false);
cam_transform = tt_transform;
cam_transform.position = tt_transform.position;
}
//键盘事件 把所有键盘事件写在一个方法内 也可以按照类型分开写 按自己代码风格写即可
private void keywordevent()
{
//人物状态切换
if (dir == Vector3.zero)
{
if (Input.GetKeyDown(KeyCode.H))
{
ani.SetInteger("people", 1);
Debug.Log("pao");
}
else if (Input.GetKeyDown(KeyCode.J))
{
ani.SetInteger("people", 2);
Debug.Log("tiao");
}
else
{
ani.SetInteger("people", 0);
}
}
//相机切换
if (Input.GetKey(KeyCode.I))
{
first();
tfirst.SetActive(true);
Debug.Log("第一人称启动");
}
if (Input.GetKey(KeyCode.O))
{
third();
tthrid.SetActive(true);
Debug.Log("第三人称启动");
}
}
}