Search Unity

Prevent translation overshooting

Discussion in 'Entity Component System' started by Radu392, Oct 22, 2019.

  1. Radu392

    Radu392

    Joined:
    Jan 6, 2016
    Posts:
    210
    Code (CSharp):
    1.         [BurstCompile]
    2.         struct ManageBulletsJob : IJobForEachWithEntity<Bullet, Translation, Rotation> {
    3.             public EntityCommandBuffer.Concurrent commandBuffer;
    4.             [ReadOnly] public float deltaTime;
    5.             public void Execute(Entity entity, int index, ref Bullet bullet, ref Translation translation, ref Rotation rotation) {
    6.                 if (!bullet.disabled) {
    7.                     float3 dest = bullet.destination;
    8.                     float3 pos = translation.Value;
    9.                     float3 targetDir = math.normalize(dest - pos);
    10.                     targetDir.z = 0;
    11.                     translation.Value += targetDir * bullet.moveSpeed * deltaTime;
    12.                     float z = math.atan2(targetDir.y, targetDir.x);
    13.                     rotation.Value = quaternion.Euler(0,0,z);
    14.                     if (math.distancesq(pos, dest) < 0.2f) {
    15.                         // reached target, destroy yourself
    16.                             bullet.disabled = true;
    17.                         commandBuffer.DestroyEntity(index, entity);
    18.                     }
    19.                 }
    20.             }
    21.         }
    So this code works fine when the Time.timeScale is set to 1. However, I'm now looking to implement a speedup feature into my game and I want to set the timeScale to 10. Every one of my systems works as expected except the job posted above. When I do that, not only do bullets overshoot the target, but they also switch direction when they reach the target for a single frame.

    In the picture, the target is the orange square.


    Unity_2019-10-22_10-42-37.png
    One frame later:
    Unity_2019-10-22_10-43-11.png

    Then one frame later they finally disappear. I think they do so because they overshot their target, so they have to turn back until they hit that 0.2 distance req. I don't want to increase that number any higher because it would just cause artifacts on other time scales and would still be frame dependent, whereas I need a frame independent solution.

    In normal monobehavior code, you'd just turn on Continuous collision detection on your rigidbody, but even if there is such a way with dots physics, I'd rather avoid using physics completely. How do you handle such a case using just math? How can I tell if the translation.Value has gone past the destination? Because if I knew that, then I could just simply set its position to the destination then destroy the bullet.

    Edit: Solved by following this example:

    https://stackoverflow.com/questions...s-between-two-points-drawn-on-a-straight-line
     
    Last edited: Oct 22, 2019
  2. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,685
    You already know how much distance it fly in this frame, just check if sqr length of this vector greater than sqr length of your pos-dist. This is pretty common :)
     
  3. calabi

    calabi

    Joined:
    Oct 29, 2009
    Posts:
    232
    I had the same problem in a job. I just used math.distance and checked if it was greater than and reset it back within the limits.