让摄像机实现上楼,模拟人在上楼,用到了这个unity内置的寻路插件NavMesh.通过这个,可以实现确定一个目标点,角色会自动寻路过去。
这是unity官网中的一个图,关于角色可行走的路线。
以该场景为例子。
先选中我可行走的区域,比如楼梯,在右方navvigation处勾选Navigation Static,(Generate offMeshLinks决定的是两个不相邻的障碍物之间是否可以直接跨越)在Navigation Area处选择walkable,进行bake。
Bake时这些参数要注意,
- Agent Radius defines how close the agent center can get to a wall or a ledge.
- Agent Height defines how low the spaces are that the agent can reach.
- Max Slope defines how steep the ramps are that the agent walk up.
- Step Height defines how high obstructions are that the agent can step on.
烘焙结束后,可见可行的区域都变成了蓝色。
路径确定了,接下来就是对于角色的控制了,点击角色,给他一个component,,接着给它添加一个移动的脚本就实现了
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class navmove : 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);
}
}
}
其中
CameraRotateToLookAt(Transform target,float rotateSpeed)
该函数是让摄像机缓慢的转动,不会猛地一转,让眼睛很不舒服。
将脚本添加给角色,就完成了。
!!!容易出现的问题:
1,"SetDestination" can only be called on an active agent that has been placed on a NavMesh。
NavMeshAgent不在NavMesh上,或场景调整后未及时烘焙。
2,在脚本中使用NavMeshAgent时,要注意命名空间using unityengine.AI;