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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM