如果只是單單這樣移動又有點過於死板,而且即使物體旋轉方向不同也還是會沿著正交線移動,就如同上圖,雖然物體有轉了個方向,但還是會沿著藍色的向量移動。
所以我希望物體先沿著原本向量移動(下圖),並且同時物體是逐漸旋轉至目標方向,所以此時需要自己目前前進的向量,再加上原本的正交線向量來求得中間橘色的這條向量,此時只要讓物體以這向量移動就可以達到逐漸轉向的目的。
這個方法乍聽之下好像很合理,但是實際上運作的時候就會發現一個問題。
那就是物體本身沒有轉往目標方向,所以原本如果預期的逐漸轉向反而是往斜向直走而已,因此在這邊需要做個物體的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