考虑碰撞的情况下控制人物的行走
在考虑碰撞的情况下,控制人物在场景中移动一般有两种方法,一种是利用刚体Rigidbody,然后通过施加力或者改变速度来控制人物的移动,另外一种方法就是利用unity自带的character controller来方便的调用函数直接控制行走。
由于character controller内部好像自带类似于刚体的属性,所以使用这个组件的话就不需要添加刚体了。当然胶囊体碰撞器Capsule Collider还是需要的。
首先添加Capsule Collider组件,根据自己人物模型的大小调整好碰撞器的高度、半径以及中心,然后添加character controller组件,根据Capsule Collider来调整它高度、半径以及中心。
如图:

然后在人物上添加脚本:
using UnityEngine;
using System.Collections;
public class PlayerVillageMove : MonoBehaviour {
// 设置成单例模式,便于调用
public static PlayerVillageMove _instance;
// 角色控制器
CharacterController controller;
// 动画
private Animator anim;
// 移动速度
public float speed = f;
private void Awake() {
_instance = this;
controller = this.GetComponent<CharacterController>();
anim = this.GetComponent<Animator>();
}
private void Update() {
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
if (Mathf.Abs(h) > f || Mathf.Abs(v) > f) {
// 打开奔跑动画
anim.SetBool("Move", true);
// 这里旋转人物使他朝向我们想移动的方向
transform.rotation = Quaternion.LookRotation(new Vector3(-h, , -v));
Vector3 movedir = new Vector3(-h, -, -v);
// 用角色控制器让他移动
controller.Move(movedir * speed);
} else {
// 切换到静止动画
anim.SetBool("Move", false);
}
}
}
这样人物就可以通过wsad控制人物的行走了。
利用Navmesh Agent设置人物自动寻路
上面实现了人物的控制行走,下面来实现人物的自动寻路,这里使用unity自带的Navmesh Agent插件。
首先需要烘焙一下场景:
把地图和和所有的障碍物全选起来,在inspector面板上勾选static(要保证navigation staitic被勾选)。
随后点击菜单栏的window,选择Naviation,再选择bake,这样就可以了。
添加Navmesh Agent组件,同样的,根据胶囊体碰撞器调整半径和高度。
添加脚本:
using UnityEngine;
using System.Collections;
public class PlayerAutoMove : MonoBehaviour {
private NavMeshAgent agent;
public float minDistance = f;
public Transform target;
private Animator anim;
private void Awake() {
agent = this.GetComponent<NavMeshAgent>();
anim = this.GetComponent<Animator>();
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.K)) {
SetDestination(target.position);
}
if (agent.enabled) {
// 这里要注意特判一下等于0的情况
if (agent.remainingDistance != && agent.remainingDistance < minDistance) {
agent.Stop();
agent.enabled = false;
PlayerVillageMove._instance.enabled = true;
anim.SetBool("Move", false);
}
}
}
public void SetDestination(Vector3 targetPos) {
// 寻路的时候把键盘控制行走的脚本屏蔽掉
PlayerVillageMove._instance.enabled = false;
agent.enabled = true;
anim.SetBool("Move", true);
agent.SetDestination(targetPos);
}
}
上面代码中在agent.remainingDistance上要特判一下等于0的情况,这是因为在SetDestination之后,会有一个计算路径的过程,在这个过程中agent.remainingDistance是被默认为0的,所以要把这个过程的特判一下,不然有可能会出现寻路的时候站在原地不动的情况。