Unity3d任务模型自动寻路(人员疏散)
1.工程里导入下载好的人物模型
如果出现人物颜色为黑色,可以调整其材质,黑色部分改为白色。
2.烘培(修改路面为可行走)。
把Navigation窗口打开,
选中地面(需要行走的地方),勾选Navigation Ststic,选择Navigation Area为Walkable,点击Bake。
3.实现人物模型在路面上行走。
(没有这一步人物也可以在路面行走,但是需要通过鼠标或者键盘来操控,如果需要完成自动寻路功能的话,就必须使用)
选中人物,选择Nav Mesh Agent。
新建一个C#脚本womenRun,代码如下:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using UnityEngine.AI;
public class womenRun : MonoBehaviour
{
private NavMeshAgent agent;
void CameraRotateToLookAt(Transform target, float rotateSpeed)
{
//取得目标物体相对于相机的法向量
Vector3 normalize = Vector3.Cross(this.transform.forward, target.transform.position - this.transform.position);
float angles = Vector3.Angle(this.transform.position, target.transform.position);
//以该法向量为轴进行旋转
this.transform.Rotate(normalize, Time.deltaTime * rotateSpeed, Space.Self);
Debug.Log(angles);
if (angles == 0)
{
rotateSpeed = 0;
}
}
void Start()
{
agent = GetComponent<NavMeshAgent>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Vector3 point = hit.point;
// transform.LookAt (new Vector3 (point.x, transform.position.y, point.z));
CameraRotateToLookAt(hit.transform, 1.0f);
}
agent.SetDestination(hit.point);
}
}
}
把脚本挂在人物身上,即完成鼠标点击位置,人物可以自己走过去。
4.增加人物动画
在1位置上选中需要添加动画的模型;
在2位置上添加一个Take001;
在3位置上改变名字,并在4位置上调整时间;
在5位置上勾选LoopTime。(如果不勾选,人物动作不能重复)
完成如图:
新建人物控制器:
双击进入Animator Controller,新建2个空状态,修改其名称,对应添加motion。(先)
场景人物的Animator组件中控制器选中之前新建的人物控制器,并勾选Apply Root Motion。
修改脚本代码如下:(红色部分为新添加的)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using UnityEngine.AI;
public class womenRun : MonoBehaviour
{
private NavMeshAgent agent;
private Animator animator;
void CameraRotateToLookAt(Transform target, float rotateSpeed)
{
//取得目标物体相对于相机的法向量
Vector3 normalize = Vector3.Cross(this.transform.forward, target.transform.position - this.transform.position);
float angles = Vector3.Angle(this.transform.position, target.transform.position);
//以该法向量为轴进行旋转
this.transform.Rotate(normalize, Time.deltaTime * rotateSpeed, Space.Self);
Debug.Log(angles);
if (angles == 0)
{
rotateSpeed = 0;
}
}
void Start()
{
agent = GetComponent<NavMeshAgent>();
animator = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
Vector3 point = hit.point;
// transform.LookAt (new Vector3 (point.x, transform.position.y, point.z));
CameraRotateToLookAt(hit.transform, 1.0f);
}
agent.SetDestination(hit.point);
animator.Play("run");
}
}
}