Không, đây không phải là lỗi động cơ hoặc tạo tác của một đại diện xoay cụ thể (những điều này cũng có thể xảy ra, nhưng hiệu ứng này áp dụng cho mọi hệ thống đại diện cho các phép quay, bao gồm các bậc bốn).
Bạn đã khám phá ra một thực tế thực tế về cách thức hoạt động của vòng quay trong không gian ba chiều và nó rời khỏi trực giác của chúng ta về các biến đổi khác như dịch thuật:
Khi chúng tôi soạn các phép quay trên nhiều trục, kết quả chúng tôi nhận được không chỉ là tổng giá trị / giá trị ròng mà chúng tôi áp dụng cho mỗi trục (như chúng tôi có thể mong đợi cho bản dịch). Thứ tự mà chúng ta áp dụng các phép quay thay đổi kết quả, vì mỗi vòng quay sẽ di chuyển các trục mà các phép quay tiếp theo được áp dụng (nếu xoay quanh trục cục bộ của đối tượng) hoặc mối quan hệ giữa đối tượng và trục (nếu xoay quanh thế giới trục).
Việc thay đổi mối quan hệ trục theo thời gian có thể gây nhầm lẫn cho trực giác của chúng ta về việc mỗi trục được "cho là" để làm gì. Cụ thể, một số kết hợp nhất định của xoay vòng ngáp và cao độ cho kết quả tương tự như xoay vòng!
Bạn có thể xác minh rằng mỗi bước quay chính xác về trục mà chúng tôi yêu cầu - không có trục trặc động cơ hoặc tạo tác trong ký hiệu của chúng tôi can thiệp hoặc đoán thứ hai đầu vào của chúng tôi - tính chất hình cầu (hoặc siêu đối xứng / tứ phương) chỉ có nghĩa là biến đổi của chúng tôi xung quanh "lên nhau. Chúng có thể trực giao cục bộ, cho các phép quay nhỏ, nhưng khi chúng chồng chất lên nhau, chúng ta thấy chúng không trực giao trên toàn cầu.
Điều này là ấn tượng và rõ ràng nhất đối với các góc quay 90 độ như những người ở trên, nhưng các trục rình rập leo qua nhiều góc quay nhỏ, như đã được chứng minh trong câu hỏi.
Vậy thì chúng ta làm gì với nó?
Nếu bạn đã có một hệ thống xoay cao độ, một trong những cách nhanh nhất để loại bỏ cuộn không mong muốn là thay đổi một trong các phép quay để hoạt động trên trục chuyển đổi toàn cầu hoặc cha mẹ thay vì trục cục bộ của đối tượng. Bằng cách đó, bạn không thể bị lây nhiễm chéo giữa hai trục - một trục vẫn được kiểm soát tuyệt đối.
Đây là một chuỗi tương tự cao độ đã trở thành một cuộn trong ví dụ trên, nhưng bây giờ chúng ta áp dụng ngáp của mình quanh trục Y toàn cầu thay vì của đối tượng
Vì vậy, chúng tôi có thể sửa máy ảnh của người đầu tiên với câu thần chú "Sân địa phương, Yaw toàn cầu":
void Update() {
float speed = lookSpeed * Time.deltaTime;
transform.Rotate(0f, Input.GetAxis("Horizontal") * speed, 0f, Space.World);
transform.Rotate(-Input.GetAxis("Vertical") * speed, 0f, 0f, Space.Self);
}
Nếu bạn kết hợp các phép quay của mình bằng cách nhân, bạn sẽ lật thứ tự trái / phải của một trong các phép nhân để có được hiệu ứng tương tự:
// Yaw happens "over" the current rotation, in global coordinates.
Quaternion yaw = Quaternion.Euler(0f, Input.GetAxis("Horizontal") * speed, 0f);
transform.rotation = yaw * transform.rotation; // yaw on the left.
// Pitch happens "under" the current rotation, in local coordinates.
Quaternion pitch = Quaternion.Euler(-Input.GetAxis("Vertical") * speed, 0f, 0f);
transform.rotation = transform.rotation * pitch; // pitch on the right.
(Thứ tự cụ thể sẽ phụ thuộc vào các quy ước nhân trong môi trường của bạn, nhưng left = more global / right = more local là một lựa chọn phổ biến)
Điều này tương đương với việc lưu trữ tổng số ngáp ròng và tổng độ cao bạn muốn dưới dạng các biến float, sau đó luôn luôn áp dụng tất cả kết quả ròng cùng một lúc, xây dựng một ma trận định hướng hoặc ma trận mới duy nhất từ các góc này (miễn là bạn tiếp tục totalPitch
kẹp):
// Construct a new orientation quaternion or matrix from Euler/Tait-Bryan angles.
var newRotation = Quaternion.Euler(totalPitch, totalYaw, 0f);
// Apply it to our object.
transform.rotation = newRotation;
hoặc tương đương ...
// Form a view vector using total pitch & yaw as spherical coordinates.
Vector3 forward = new Vector3(
Mathf.cos(totalPitch) * Mathf.sin(totalYaw),
Mathf.sin(totalPitch),
Mathf.cos(totalPitch) * Mathf.cos(totalYaw));
// Construct an orientation or view matrix pointing in that direction.
var newRotation = Quaternion.LookRotation(forward, new Vector3(0, 1, 0));
// Apply it to our object.
transform.rotation = newRotation;
Sử dụng sự phân chia toàn cầu / cục bộ này, các phép quay không có cơ hội kết hợp và ảnh hưởng lẫn nhau, bởi vì chúng được áp dụng cho các bộ trục độc lập.
Ý tưởng tương tự có thể giúp nếu đó là một đối tượng trong thế giới mà chúng ta muốn xoay. Đối với một ví dụ như toàn cầu, chúng ta thường muốn đảo ngược nó và áp dụng ngáp của mình cục bộ (để nó luôn xoay quanh các cực của nó) và ném trên toàn cầu (vì vậy, nó hướng tới / ra khỏi tầm nhìn của chúng ta, thay vì hướng về / ra khỏi Úc , bất cứ nơi nào nó chỉ ...)
Hạn chế
Chiến lược lai toàn cầu / cục bộ này không phải lúc nào cũng đúng. Ví dụ: trong trò chơi có chuyến bay / bơi 3D, bạn có thể muốn chỉ thẳng lên / xuống thẳng mà vẫn có toàn quyền điều khiển. Nhưng với thiết lập này, bạn sẽ nhấn khóa gimbal - trục ngáp của bạn (toàn cầu) trở thành song song với trục cuộn của bạn (chuyển tiếp cục bộ) và bạn không có cách nào để nhìn sang trái hoặc phải mà không vặn.
Thay vào đó, những gì bạn có thể làm trong các trường hợp như thế này là sử dụng các phép quay cục bộ thuần túy như chúng tôi đã bắt đầu trong câu hỏi ở trên (để các điều khiển của bạn cảm thấy giống nhau cho dù bạn đang tìm kiếm ở đâu), ban đầu sẽ cho phép một số cuộn vào - nhưng sau đó chúng tôi sửa cho nó
Ví dụ: chúng ta có thể sử dụng các phép quay cục bộ để cập nhật vectơ "chuyển tiếp" của mình, sau đó sử dụng vectơ chuyển tiếp đó cùng với một vectơ "lên" tham chiếu để xây dựng hướng cuối cùng của chúng ta. (Ví dụ, sử dụng phương pháp Quancyion.LookRotation của Unity hoặc xây dựng thủ công ma trận trực giao từ các vectơ này) Bằng cách điều khiển vectơ lên, chúng tôi điều khiển cuộn hoặc xoắn.
Đối với ví dụ về chuyến bay / bơi, bạn sẽ muốn áp dụng các hiệu chỉnh này dần dần theo thời gian. Nếu quá đột ngột, chế độ xem có thể mất đi một cách mất tập trung. Thay vào đó, bạn có thể sử dụng vectơ hiện tại của người chơi và gợi ý nó theo chiều dọc, từng khung hình, cho đến khi tầm nhìn của họ vượt ra ngoài. Áp dụng điều này trong một lượt đôi khi có thể ít buồn nôn hơn so với vặn máy ảnh trong khi các điều khiển của người chơi không hoạt động.