[英]How to rotate a quanternion and calculate direction vector in Unity (ECS)
我開始使用 ECS 並且我有一個旋轉組件(四元數)和一個平移組件(float3)。 我正在編寫一個系統來處理用戶輸入和旋轉和/或向前移動播放器。
問題是我不知道該怎么做。 我認為缺乏現有的 API。
// Before it was easy
if (Input.GetKey(KeyCode.W))
var newPostion = new Vector3(player.Position.x, player.Position.y, 0.3f)
+ _playerTransform.up * Time.deltaTime * PlayerSpeed;
if (Input.GetKey(KeyCode.A))
_playerTransform.Rotate(new Vector3(0, 0, PlayerRotationFactor));
// now it is not - that's part of the system's code
Entities.With(query).ForEach((Entity entity, ref Translation translation, ref Rotation rotation) =>
{
float3 tmpTranslation = translation.Value;
quaternion tmpRotation = rotation.Value;
if (Input.GetKey(KeyCode.W))
// how to retrieve forward vector from the quaternion
tmpTranslation.y += Time.deltaTime * PlayerSpeed;
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
// this always set the same angle
tmpRotation = quaternion.RotateZ(PlayerRotationFactor);
// ECS need this
var newTranslation = new Translation { Value = tmpTranslation };
PostUpdateCommands.SetComponent(entity, newTranslation);
var newRotation = new Rotation { Value = tmpRotation };
PostUpdateCommands.SetComponent(entity, newRotation);
});
要從四元數中獲取向量,您可以將其與正向向量相乘,例如:
if (Input.GetKey(KeyCode.W))
{
Vector forward = tmpRotation * float3(0,0,1);
tmpTranslation += forward * Time.deltaTime * PlayerSpeed;
}
對於旋轉部分,正如您所說的// this always set the same angle
。 看起來您正在創建一個新的靜態角度。 嘗試更改以當前角度相乘,就像四元數相乘以合並一樣。 例:
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
tmpRotation = mul(tmpRotation, quaternion.RotateZ(PlayerRotationFactor));
}
旁注:我還是Unity ECS的新手,我還沒有測試以上代碼。
// correct forward
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
float3 forwardVector = math.mul(rotation.Value, new float3(0, 1, 0));
newTranslation += forwardVector * Time.deltaTime * PlayerSpeed;
}
// correct rotation
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
quaternion newRotation = math.mul(rotation.Value, quaternion.RotateZ(PlayerRotationFactor * Time.deltaTime));
// insert new value to the component
PostUpdateCommands.SetComponent(entity, new Rotation { Value = newRotation });
}
// thx akaJag
該代碼沒有使用應有的委托變量引用。
在PostUpdateCommands
(或EntityManager
或任何其他CommandBufferSystem
)中設置組件是完全沒有必要的,因為平移/旋轉是直接存在的 - 在委托函數中 - 由 ref 操作。
又名:
rotation.Value = newRotation
translation.Value = newTranslation
不是
EntityManager(CommandBuffer).SetComponentData(entity, new Rotation{ Value = newRotation})
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.