Search Unity

Trouble with rotation via job

Discussion in 'Entity Component System' started by MostHated, Feb 8, 2019.

  1. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Hello all,
    Thanks to the help of some great folks on here, I am well on my way to getting all my vehicles working well in ECS. I seem to be having an issue though with trying to get the rotation working properly.

    In my non-ecs wheel script, I was using the following and it was working fine (though looking back at it now, is a less than efficient way to go about it, but that's whatever, lol).
    Code (CSharp):
    1.         void Move()
    2.         {
    3.             vehicle.position += vehicle.forward * speed * Time.deltaTime;
    4.             RotateTowardsDest(currentWaypoint.transform.position);
    5.  
    6.             foreach (GameObject wheel in wheels)
    7.             {
    8.                 var spin = wheel.GetComponent<Transform>();
    9.                 spin.Rotate(spinSpeed / 60 * 360 * Time.deltaTime, 0, 0);
    10.             }
    11.         }
    I tried to use similar to what I was using before since it worked well, here was what I came up with:

    Code (CSharp):
    1.         struct WheelSpinJob : IJobProcessComponentData<Position, Rotation, WheelSpin>
    2.         {
    3.             public float dT;
    4.             public float rotX;
    5.  
    6.             public void Execute(ref Position position, ref Rotation rotation, ref WheelSpin wheelSpin)
    7.             {
    8.                 // This was just something I had tried first to see if it made a difference
    9.                 //rotX += math.mul(wheelSpin.speed / 60 * wheelSpin.direction, dT);
    10.                 //rotation.Value = quaternion.Euler(rotX,0,0);
    11.              
    12.                 // Direction currently just set to 360
    13.                 rotation.Value = quaternion.Euler(wheelSpin.speed / 60 * wheelSpin.direction * dT, 0, 0);
    14.             }
    15.         }
    16.  
    17.         protected override JobHandle OnUpdate(JobHandle inputDeps)
    18.         {
    19.             var job = new WheelSpinJob
    20.             {
    21.                 dT = Time.deltaTime
    22.             };
    23.             return job.Schedule(this, inputDeps);
    24.         }
    25.     }
    In my setup of the vehicle, I am doing the following below. The values of vehicleWheelSpeed as well as vehicleWheelDirection are both set in the inspector and then passed into the WheelSpin component which then each wheel has that component attached.
    Code (CSharp):
    1.                 wheels = manager.GetAllEntities();
    2.                 for (int i = 0; i < wheels.Length; i++)
    3.                 {
    4.                     if (manager.HasComponent<WheelSpin>(wheels[i]))
    5.                     {
    6.                         manager.SetComponentData(wheels[i], new WheelSpin { direction = vehicleWheelSpeed, speed = vehicleWheelDirection});
    7.                     }
    8.                 }
    The main issue I seem to be running into is, I have been trying different values in the spin speed, if I use a low value, such as 5 or so, this happens: It just seems to sort of, sit there and twitch.

    This is speed set to 5


    Then here is 10, in which it seems like... it does spin once, now and then? It is really fast though.


    If I use any sort of higher value, say something like 50 up to even 600, it seems to just always look the same speed: This is 75



    So while it does look like it may be spining faster, as I mentioned it seems to make no difference if I set it to 50 or 600, it just looks the same. It might not even be spinning, it might just be twitching fast enough to look like its spinning, lol.

    So I am not sure if this might have something to do with the way I am trying to do this job, or the math now that it's using Unity.Mathematics, does anyone have any ideas? I would certainly like to be able to have a much nicer and more smooth turning action if possible.

    Thanks all!
    -MH
     
  2. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    rotation.Value = quaternion.Euler(wheelSpin.speed / 60 * wheelSpin.direction * dT, 0, 0);


    is wrong. Image if dt was the same value every frame, let's say 0.02, your rotation would be the exact same value every frame. You're not applying any rotation, just setting the angle. Need a multiply in there.
     
  3. Deleted User

    Deleted User

    Guest

    Speaking of rotation
    https://puu.sh/CJ47x/031e9236b1.gif

    wtf is going on here.

    Code (CSharp):
    1.     struct DragJob : IJobProcessComponentDataWithEntity<InputData, Position, Rotation>
    2.     {
    3.         [ReadOnly]public ComponentDataFromEntity<SelectedData> selected;
    4.  
    5.         public float3 mousePosition;
    6.  
    7.         public void Execute(Entity entity, int index, ref InputData input, ref Position pos, ref Rotation rot)
    8.         {
    9.             if (selected[entity].IsSelected)
    10.             {
    11.                 float3 newRotation = math.mul(quaternion.AxisAngle(new float3(0, 1, 0), mousePosition.x), pos.Value - pos.Value) + pos.Value;
    12.                 rot.Value = new quaternion(new float4(newRotation, 1.0f));
    13.             }
    14.         }
    15.     }
    My idea is to have this applied to touch drag type scenarios, this worked in the older method of ECS with the ComponentSystem instead because I could use Transform but looking at the new direction of it in this manner.

    the angle provided in AxisAngle is the Vector3.up

    While mouse is held, and cube is selected... Add rotation based on its screen pos... Its supposed to be the same as doing transform.RotateAround
     
  4. MostHated

    MostHated

    Joined:
    Nov 29, 2015
    Posts:
    1,235
    Just an update. After, well, far too long I finally got it figured out. >_<


    Code (CSharp):
    1. rotation.Value = math.mul(math.normalize(rotation.Value), quaternion.AxisAngle(new float3(1, 0, 0), wheelSpin.speed * dT));
     
    HellFireKoder likes this.
  5. Micz84

    Micz84

    Joined:
    Jul 21, 2012
    Posts:
    451
    One suggestion when you use IJobProcessComponentData use ReadOnly annotation for components you are only reading data from.
     
    MostHated likes this.