Unity - 製作沿著正交線(perpendicular line)移動的物件

  這次來製作的是可以沿著正交線移動的物件,舉例來說以物體的右方來去判斷,往正右方射出Raycast,如果這條線有打中Collider就去取得擊中那個點的資訊,取得該點的法向量後,再使用向量外積來取得正交線的向量(藍色箭頭),此時如果直接讓物體以這向量來移動的話就可以達到目的了。




  如果只是單單這樣移動又有點過於死板,而且即使物體旋轉方向不同也還是會沿著正交線移動,就如同上圖,雖然物體有轉了個方向,但還是會沿著藍色的向量移動。

  所以我希望物體先沿著原本向量移動(下圖),並且同時物體是逐漸旋轉至目標方向,所以此時需要自己目前前進的向量,再加上原本的正交線向量來求得中間橘色的這條向量,此時只要讓物體以這向量移動就可以達到逐漸轉向的目的。


  這個方法乍聽之下好像很合理,但是實際上運作的時候就會發現一個問題。
  
  那就是物體本身沒有轉往目標方向,所以原本如果預期的逐漸轉向反而是往斜向直走而已,因此在這邊需要做個物體的rotation讓物體會逐漸轉向橘色向量所指的方向,當然這邊使用內插計算避免一瞬間就轉到目標方向。


--
  最後我希望可以固定物體與旁邊牆面的距離,因為上面逐漸轉向的關係,轉的次數越多物體就會逐漸接近或遠離牆面,這不是希望發生的一件事,所以稍微多一個瑣碎的步驟,就是使用取得的法向量(紅色),以物體的座標往相反去取得最近的另一個牆面的點,接著再用這個點的資訊加上我設定好的距離長度,就可以求得距離牆面的理想距離位置(橘色線段所指的點)。



  最後使用這個理想位置的座標加上原本正交線的向量(藍色),就可以得到下一步理想的預期位置的座標了(綠色Target),接著只要讓物體逐漸朝著該點移動同時逐漸轉向面對該點,也就是綠色線段這條向量,就可以讓物體沿著正交線移動同時又可以跟牆面保持安全距離了。


--
實作測試(隨意擺設幾個方塊,然後Component放在球上)



--
Code的部分
public float movingSpeed = 0.01f;
public float turnSpeed = 0.05f;
public float fixedDist = 2.0f;

void WallDetect() {
    RaycastHit hit;
    if (!Physics.Raycast(transform.position, transform.TransformPoint(Vector3.right) - transform.position, out hit))
        return;

    Vector3 perp = Vector3.Cross(hit.normal, Vector3.up);
    Vector3 targetDir = Vector3.Project(transform.forward, perp).normalized;
    Vector3 currentDir = transform.TransformPoint (Vector3.forward) - transform.position;

    RaycastHit hit2;
    if (Physics.Raycast (transform.position, -hit.normal, out hit2)) {
        Vector3 fixedPos = hit2.point + hit.normal * fixedDist;
        Vector3 predictPos = fixedPos + targetDir;
        transform.position = Vector3.MoveTowards (transform.position, predictPos, movingSpeed);
        transform.rotation = Quaternion.Lerp(transform.rotation, Quaternion.LookRotation (predictPos - transform.position), turnSpeed);
    }
}

No comments:

Post a Comment