【Unity】角色沿路线移动/朝着目标移动
先在场景中放置一连串物体作为角色移动路线的关键点,可以把关键点的触发器Trigger拉得大一些方便角色接触到(如酷跑/赛车类项目可以把关键点的触发器做成拦截整个道路的墙面形状)。让角色从开始位置朝着第一个目标点移动,当角色碰触到第一个目标点的触发器时,更新角色朝向第二个目标点移动,依此类推。
其他实现办法:
- 使用iTweenPath和iTweenEvent脚本
- 目前Unity2017版本中,自带的官方案例中有AI按照路线自动运动的场景,之后继续学习看看。
private Transform[] line; // 场景中的一个个关键点,用于组成行动路线 private int pointIndex = 0; // 当前移动到了路线line上的第几个关键点 private Transform m_transform; private Vector3 HTagetPos; // 目标物体在player水平方向的坐标 private Vector3 NextPoint; // 当前路线点到下个路线点的方向 private Vector3 LookDirection; // 自身到目标的方向 private Quaternion targetlook; void Start () { m_transform = transform; HTagetPos= line[pointIndex].position; HTagetPos.y = m_transform.position.y; NextPoint= (line [pointIndex + 1].position - line [pointIndex].position).normalized; // 指向下一个关键点的单位向量 } void Update() { if (!gameManager.Pause) // 游戏是否暂停 { moveforward(); } } // 角色向前移动 void moveforward(){ nextpoint(); LookDirection = HTagetPos - m_transform.position; targetlook = Quaternion.LookRotation (LookDirection); m_transform.Translate (Vector3.forward * Time.deltaTime * speed); // 角色向目标点移动 m_transform.rotation = Quaternion.Slerp(m_transform.rotation, targetlook, Time.deltaTime * speed); // 角色朝向目标点 } // 额外加个判定,用来防止速度太快OnTriggerEnter不起作用的情况出现 // 或者把角色身上的Rigidbody的碰撞检测由默认离散的改为连续的(Continuous) void nextpoint(){ if (pointIndex + 1 < line.Length) { if(Vector3.Dot(DirPointNext,m_transform.forward) < 0.2f){ pointIndex++; HTagetPos= line[pointIndex].position; HTagetPos.y = m_transform.position.y; if (pointIndex + 2 < line.Length) { NextPoint= (line[pointIndex + 1].position - line[pointIndex].position).normalized; // 指向下一个关键点的单位向量 } } } } // 角色碰触到关键点的触发器后,更新下一个目标点的位置 void OnTriggerEnter(Collider other){ // 到达当前路线点时,改为下个目标点 if(other.transform == line[pointIndex]){ if (pointIndex < line.Length - 1) { pointIndex++; HTagetPos = line[pointIndex].position; HTagetPos.y = m_transform.position.y; if (pointIndex + 2 < line.Length) { NextPoint = (line[pointIndex + 1].position - line[pointIndex].position).normalized; } } else { gameManager.Pause = true; gameManager.gameover(); } } }