【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();
        }
    }
}

 

posted @ 2017-08-08 16:23  霍莉雪特  阅读(10117)  评论(0编辑  收藏  举报