Gương xoay


9

Tôi xoay nhân vật trò chơi của mình để xem mục tiêu bằng mã sau:

        transform.rotation = Quaternion.Slerp(startQuaternion, lookQuaternion, turningNormalizer*turningSpeed/10f)

startQu Parention là vòng quay hiện tại của nhân vật khi có mục tiêu mới.

lookQu Parention là hướng mà nhân vật nên nhìn và nó được đặt như thế này:

    destinationVector = currentWaypoint.transform.position - transform.position;
    lookQuaternion = Quaternion.LookRotation(destinationVector, Vector3.up);

TurnN normalizer chỉ được Time.deltaTimetăng lên và turningSpeedlà một giá trị tĩnh được đưa ra trong trình chỉnh sửa.

Vấn đề là trong khi hầu hết các nhân vật quay đầu, thì nó lại gặp vấn đề khi phải làm gần 180 độ. Sau đó, nó đôi khi jitter và phản ánh xoay vòng:

nhập mô tả hình ảnh ở đây

Trong hình ảnh được vẽ kém này, nhân vật (bên phải) bắt đầu quay về phía vòng tròn bên trái. Thay vì chỉ xoay qua trái hoặc phải, nó bắt đầu "điệu nhảy gương" này:

  1. Nó bắt đầu xoay về phía đối diện mới
  2. Sau đó, nó đột nhiên chộp vào cùng một góc nhưng ở phía bên kia và tiếp tục quay

Nó thực hiện việc "phản chiếu" này rất lâu cho đến khi nó nhìn vào mục tiêu. Đây có phải là một điều với quernions, slerping / lerping hoặc cái gì khác?

EDIT1: Rõ ràng vấn đề không phát sinh từ chính việc xoay vòng. Vấn đề có nhiều khả năng là nhân vật di chuyển về phía mặt trong khi nó xoay. Khi giới hạn góc, giữa đối diện và mục tiêu, khi nhân vật được phép di chuyển sẽ giảm và đôi khi loại bỏ xoay xoay / phản chiếu.

Điều này tất nhiên đặt ra nhiều câu hỏi hơn, tại sao nhân vật không thể di chuyển và xoay cùng một lúc mà không gặp vấn đề gì? Mã được sử dụng cho phong trào:

transform.Translate(Vector3.forward * runningSpeed/10f * Time.deltaTime);

Có phải 'lookQu Parention' đang được cập nhật mọi khung hình? Nếu vậy, thì suy đoán của tôi sẽ là một số không chính xác nhỏ đang dẫn đến một loại jitter nơi người chơi 'overshoots' giao diện xoay và do đó hướng đi mới để nhìn là chỉ trên khác bên của 'trực tiếp đằng sau' ... .
Steven Stadnicki

Câu trả lời:


5

Mỗi hướng trong không gian 3D có thể được biểu thị bằng 2 nhóm đơn vị riêng biệt q-q(phủ định thành phần q). Chẳng hạn, hướng được biểu thị bằng ma trận danh tính 3x3 Icó thể được biểu thị bằng 2 bậc bốn:

 q:  { 0,  0,  0},  1
-q:  {-0, -0, -0}, -1

Cả hai đều đại diện cho cùng một hướng trong không gian 3D, sản phẩm chấm của họ là chính xác -1, mỗi cái nằm ở bán cầu kia, chính xác ở phía đối diện của siêu cầu.

Kết quả mà bạn quan sát thấy khi slerp có cung tròn dài hơn để xoay, là khi trượt giữa 2 bậc bốn không nằm trong cùng một bán cầu. Nếu điều đó xảy ra, chỉ cần phủ nhận một trong số chúng trước khi làm chậm chúng, thì slerp sẽ lấy cung ngắn hơn.

Sản phẩm chấm là một công cụ dễ dàng để tìm hiểu xem điều đó có xảy ra hay không. Nếu sản phẩm chấm của cả hai phần tử nhỏ hơn 0, thì chúng không nằm trong cùng một bán cầu. Vì vậy, nếu sản phẩm chấm của cả hai ít hơn 0, chỉ cần loại bỏ thành phần thông minh khác trước khi làm chậm chúng.


Tôi tự hỏi nếu tôi hiểu bạn chính xác khi tôi đã thử nó với điều này if(Quaternion.Dot (lookQuaternion, startQuaternion) < 0) { startQuaternion = Quaternion.Inverse(startQuaternion); }Nhưng nó đã không sửa vấn đề. Xin lỗi vì định dạng kém, tôi dường như không thể chế ngự phần bình luận này.
Esa

Hầu như, nhưng không Inverse, đó là một hoạt động khác hơn Negate. if(Quaternion.Dot (lookQuaternion, q) < 0) { q.x = -q.x; q.y = -q.y; q.z = -q.z; q.w = -q.w; }Tôi không sử dụng C #, nhưng từ vẻ ngoài của docu, có vẻ như bạn cũng có thể sử dụng Hàm phủ định trực tiếp.
Maik

if(Quaternion.Dot (lookQuaternion, startQuaternion) < 0) { startQuaternion = Quaternion.Negate(startQuaternion); }
Maik

Tôi sợ những điều này đã không khắc phục vấn đề. Tôi đã cập nhật câu hỏi.
Esa

Vâng đó có lẽ là một hỗn hợp của các lỗi khác nhau. Đơn giản hóa thiết lập thử nghiệm của bạn, kiểm tra từng thứ một, không dịch và xoay cùng một lúc. Trước tiên hãy chắc chắn rằng một cái hoạt động, sau đó là cái kia, và sau đó cả hai cùng nhau. Chỉ tập trung vào xoay đầu tiên, sử dụng một số giá trị định hướng nổi tiếng, như bắt đầu ở 170 độ, di chuyển xuống 0, xem nó sai ở đâu và đăng nó ở đây
Maik Semder

1

Vấn đề của bạn là bởi vì hai vectơ đó tạo thành tứ phân vị của bạn tạo ra 180 độ, vì vậy câu hỏi nên được đặt ra khi nội suy cung nào cần phải thực hiện? vòng cung trên hay vòng dưới ??

Đây là những gì về cơ bản gây ra phản chiếu, mỗi khi bạn đang nội suy, nó sẽ đi theo hướng khác trong khi vẫn duy trì góc.

Theo liên kết này .

Khi theta là 180 độ, kết quả không được xác định vì không có hướng xoay ngắn nhất, tôi không nghĩ tình huống này được xử lý chính xác, sẽ tốt hơn nếu chúng ta chọn một trục tùy ý là bình thường đối với qa hoặc qb, tôi sẽ đánh giá cao bất kỳ ý tưởng cho cách tốt nhất để làm điều này.

Những gì bạn cần làm là nội suy bậc bốn bắt đầu của bạn với một bậc bốn trung gian (để xác định cung nào sẽ thực hiện) và khi đạt được, hãy sử dụng tứ phân vị trung gian để tiếp tục đến bậc bốn mục tiêu thực tế.


1

Vấn đề tôi nghi ngờ bạn đang thấy không liên quan gì đến mã của bạn, mà là vấn đề cơ bản với phép nội suy dọc theo bề mặt của một hình cầu (trong trường hợp này là đối với viewDirection). Giữa (gần như) bất kỳ hai điểm nào trên một quả cầu có một vòng tròn lớn duy nhất - ví dụ, tùy ý sửa điểm 'bắt đầu' của chúng ta ở cực bắc, vòng tròn lớn sẽ là kinh tuyến mà điểm cuối nằm trên. Nội suy từ điểm này sang điểm khác di chuyển dọc theo vòng tròn lớn này.

Bây giờ, đối với hầu hết các điểm trên một hình cầu, các điểm gần đó tương ứng với các vòng tròn lớn gần đó; ví dụ, các kinh tuyến mà Los Angeles và Phoenix nằm trên khá gần nhau. Nhưng khi điểm đến là cực âm của điểm ban đầu - cực nam đến cực bắc của điểm bắt đầu - sẽ không còn một vòng tròn lớn nào xuyên qua cả hai, mà thay vào đó là tất cả các vòng tròn lớn đi qua nhau. Tệ hơn, điều này có nghĩa là các điểm gần cực nam không phải là 'hầu hết các điểm'; hai điểm gần nhau và cả hai gần cực nam có thể có kinh tuyến cực kỳ khác nhau.

Tôi nghi ngờ rằng những gì bạn đang thấy là một biểu hiện của sự không ổn định này trong kinh tuyến - hay nói cách khác, cung nội suy. Khi mục tiêu nhìn trực tiếp phía sau nhân vật, thì những thứ như sự thiếu chính xác của đơn hàng đầu tiên trong 'Tích hợp Euler' của vị trí của nhân vật và cách thay đổi khung hình theo hướng nhìn sẽ dẫn đến những điều này một cách điên cuồng các cung nội suy khác nhau từ khung này sang khung khác và điều này có thể sẽ dẫn đến 'lảo đảo' mà bạn đang thấy.

Theo như những gì cần làm với nó, điều tốt nhất nảy ra trong đầu là không tính toán lại hướng nhìn của 'mục tiêu' mỗi khung hình; thay vào đó, hãy sử dụng cùng một khung cho một số khung, sau đó tính toán một khung mới và sử dụng khung đó cho một số khung, v.v. Nếu cần, bạn thậm chí có thể nội suy từ một mục tiêu sang mục tiêu tiếp theo trên một vài khung hình để hướng chuyển động không thay đổi quá đột ngột.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.