三、编写角色控制器脚本并挂到Player对象上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// 玩家角色控制器
/// </summary>
public class PlayerController : MonoBehaviour
{
private NavMeshAgent agent;
private Animator animator;
private Transform mTransform;
private AnimationState animationState = AnimationState.idle;
private void Awake()
{
mTransform = transform;
if (agent == null)
agent = this.GetComponent<NavMeshAgent>();
if (animator == null)
animator = this.GetComponent<Animator>();
}
void Start()
{
animator.CrossFade(animationState.ToString(), 0.5f, 0, 0);
}
void Update()
{
//导航到鼠标点击位置
if (Input.GetMouseButtonDown(0))
{
Vector3 mousePosition = Input.mousePosition;
Ray ray = Camera.main.ScreenPointToRay(mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
agent.SetDestination(hit.point);
if (animationState != AnimationState.walk)
{
animationState = AnimationState.walk;
animator.CrossFade(animationState.ToString(), 0.3f, 0, 0);
}
}
}
//到达终点后切换成空闲状态
if (animationState == AnimationState.walk &&
Vector3.Distance(mTransform.position, agent.destination) < 0.01f)
{
animationState = AnimationState.idle;
animator.CrossFade(animationState.ToString(), 0.5f, 0, 0);
}
//通过按键切换到其他动作
if (Input.GetKeyDown(KeyCode.A))
{
if (animationState != AnimationState.attack)
{
animationState = AnimationState.attack;
animator.CrossFade(animationState.ToString(), 0.2f, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.S))
{
if (animationState != AnimationState.active)
{
animationState = AnimationState.active;
animator.CrossFade(animationState.ToString(), 0.2f, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.F))
{
if (animationState != AnimationState.passive)
{
animationState = AnimationState.passive;
animator.CrossFade(animationState.ToString(), 0.2f, 0, 0);
}
}
else if (Input.GetKeyDown(KeyCode.D))
{
if (animationState != AnimationState.dead)
{
animationState = AnimationState.dead;
animator.CrossFade(animationState.ToString(), 0.2f, 0, 0);
}
}
}
}
public enum AnimationState
{
idle,
walk,
attack,
active,
passive,
dead
}
四、编写摄像机跟随脚本并挂到Camera对象上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// 摄像机跟随玩家
/// </summary>
public class FollowCamera : MonoBehaviour
{
public Transform player;
public bool fixCamera;
private Transform mTransform;
private Vector3 originPosition;
private Vector3 offset;
private float distance;
private bool rightMouseDown;
private Vector3 mouseLastPosition;
private Vector3 playerHeadPosition;
private float agentHeight;
void Awake()
{
NavMeshAgent agent = player.GetComponent<NavMeshAgent>();
agentHeight = agent.height;
mTransform = transform;
originPosition = mTransform.position;
//offset相对于头顶坐标
playerHeadPosition = player.position;
playerHeadPosition.y += agentHeight;
offset = originPosition - playerHeadPosition;
distance = Vector3.Distance(originPosition, playerHeadPosition);
}
void Update()
{
if (fixCamera)
{
//自动跟随
playerHeadPosition = player.position;
playerHeadPosition.y += agentHeight;
mTransform.position = playerHeadPosition + offset;
//支持鼠标右键旋转镜头
if (Input.GetMouseButtonDown(1))
{
rightMouseDown = true;
mouseLastPosition = Input.mousePosition;
}
if (Input.GetMouseButtonUp(1))
rightMouseDown = false;
if (rightMouseDown)
{
Vector3 mousePosition = Input.mousePosition;
float deltaX = mousePosition.x - mouseLastPosition.x;
mTransform.RotateAround(player.position, Vector3.up, deltaX);
mouseLastPosition = mousePosition;
offset = mTransform.position - playerHeadPosition;
}
//支持鼠标滚轮推拉镜头
Vector2 mouseScrollDelta = Input.mouseScrollDelta;
if (mouseScrollDelta.y > 0) //镜头拉近
{
if (Vector3.Magnitude(offset) > distance * 0.5f)
offset *= 0.9f;
}
else if (mouseScrollDelta.y < 0) //镜头拉远
{
if (Vector3.Magnitude(offset) < distance * 2)
offset *= 1.1f;
}
}
else
{
//自动跟随&旋转镜头
Vector3 back = -player.forward;
Vector3 camPos = player.position + back * distance;
camPos.y = originPosition.y;
mTransform.position = camPos;
mTransform.LookAt(player);
}
}
}