Search Unity

Question about quaterions rotation

Discussion in 'Entity Component System' started by pKondzior, Nov 5, 2021.

  1. pKondzior

    pKondzior

    Joined:
    Dec 1, 2013
    Posts:
    1
    Hi, I`m having a problem with understanding how quaternion rotation works. I have turret and projectile, that i want to shoot from it. The turret can rotate in any direction.

    Projectile:
    upload_2021-11-5_18-41-29.png

    Turret:
    upload_2021-11-5_18-42-25.png

    I have my FixedRateSpawnerSystem for creating projectiles:
    Code (CSharp):
    1. Entities
    2.         .ForEach((in ProjectileSpawnerComponent spawner, in LocalToWorld localToWorld, in Rotation localRotation) =>
    3.         {
    4.             var projectileEntity = ecb.Instantiate(spawner.Prefab);
    5.  
    6.             var spawnPos = localToWorld.Position;
    7.             var rotation = localToWorld.Rotation;
    8.  
    9.             var halfPi =  Unity.Mathematics.math.PI / 2;
    10.             var rotationQuaterion = quaternion.RotateZ(halfPi);
    11.             var normalizedRotation = math.normalize(rotation);
    12.             var newRotation = math.mul(normalizedRotation, rotationQuaterion);
    13.  
    14.             // var lookRotationSafe = quaternion.LookRotationSafe(localToWorld.Forward, localToWorld.Right);
    15.  
    16.             ecb.SetComponent(projectileEntity, new Translation { Value = spawnPos });
    17.             ecb.SetComponent(projectileEntity, new Rotation { Value = newRotation });
    18.             ecb.SetComponent(projectileEntity, new ProjectileComponent
    19.             {
    20.                 SpawnTime = spawnTime,
    21.                 SpawnPos = spawnPos,
    22.             });
    23.         })
    But this rotation, creates weird bugs, on 90 and -90 degrees:
    upload_2021-11-5_18-46-55.png

    I can fix that just by using quaternion.LookRotationSafe:

    Code (CSharp):
    1. Entities
    2.         .ForEach((in ProjectileSpawnerComponent spawner, in LocalToWorld localToWorld, in Rotation localRotation) =>
    3.         {
    4.             var projectileEntity = ecb.Instantiate(spawner.Prefab);
    5.  
    6.             var spawnPos = localToWorld.Position;
    7.             var rotation = localToWorld.Rotation;
    8.  
    9.             //var halfPi =  Unity.Mathematics.math.PI / 2;
    10.             //var rotationQuaterion = quaternion.RotateZ(halfPi);
    11.             //var normalizedRotation = math.normalize(rotation);
    12.             //var newRotation = math.mul(normalizedRotation, rotationQuaterion);
    13.  
    14.              var lookRotationSafe = quaternion.LookRotationSafe(localToWorld.Forward, localToWorld.Right);
    15.  
    16.             ecb.SetComponent(projectileEntity, new Translation { Value = spawnPos });
    17.             ecb.SetComponent(projectileEntity, new Rotation { Value = lookRotationSafe });
    18.             ecb.SetComponent(projectileEntity, new ProjectileComponent
    19.             {
    20.                 SpawnTime = spawnTime,
    21.                 SpawnPos = spawnPos,
    22.             });
    23.         })
    That's, produces, result I wanted:
    upload_2021-11-5_18-48-56.png

    My question is what I`m missing or do not understand, about the first method?
     
  2. Krajca

    Krajca

    Joined:
    May 6, 2014
    Posts:
    347
    It's hard to tell but I think you should not normalize old rotation.