Search Unity

Why my Job freeze the Unity silently

Discussion in 'Data Oriented Technology Stack' started by Emre_U, Mar 26, 2018.

  1. Emre_U

    Emre_U

    Joined:
    Jan 27, 2015
    Posts:
    49
    I tried to use the Jobs with Entities but looks like I am doing something horrible and The Unity just freeze on me. For example, you can easily forget to add Unity.Collections; and it will not complain. I would love if anyone can point me what is wrong. I suspect I can not handle Rotation like that, but I can't think why? Or why it is freezing. This is supposed to be another thread right? (Unity Vers. 2018.1.0b12 - from Welcome post, VS 2017 Community).


    Code (CSharp):
    1.  
    2. using Unity.Jobs;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Transforms;
    6. using Unity.Rendering;
    7. using Unity.Collections;
    8.  
    9.  
    10. // I know BootTime is working correct as I am using a ComponentSystem to play with entities' position. But after 1 frame Unity Freeze. I have only added below JobComponent System and Freezing start.
    11.  
    12. public sealed class BootTime
    13. {
    14.  
    15.     public static EntityArchetype PlayerArchetype;
    16.  
    17.     public static MeshInstanceRenderer PlayerLook;
    18.  
    19.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
    20.     public static void Init()
    21.     {
    22.         var entityManager = World.Active.GetOrCreateManager<EntityManager>();
    23.  
    24.         PlayerArchetype = entityManager.CreateArchetype(typeof(Position3D),typeof(TransformMatrix),typeof(Position),typeof(Rotation));
    25.  
    26.         PlayerLook = GetLookFromPrototype("PlayerRenderPrototype");
    27.  
    28.         for (int i = 0; i < 50; i++)
    29.         {
    30.             var player = entityManager.CreateEntity(PlayerArchetype);
    31.  
    32.             entityManager.AddSharedComponentData(player, PlayerLook);
    33.  
    34.         }
    35.      
    36.     }
    37.  
    38.  
    39.  
    40.     private static MeshInstanceRenderer GetLookFromPrototype(string protoName)
    41.     {
    42.         var proto = GameObject.Find(protoName);
    43.         Debug.Log(proto.name + " this is the name found");
    44.         var result = proto.GetComponent<MeshInstanceRendererComponent>().Value;
    45.         Object.Destroy(proto);
    46.         return result;
    47.     }
    48. }
    49.  
    50. // Looks like this should be the traitor, but why? Ofcourse it can be anything. I have no clue I am writing 64 to the last schedule forexample :D
    51.  
    52. public class SystemhereWithJob : JobComponentSystem
    53. {
    54.     [ComputeJobOptimization]
    55.     public struct GoGrazy : IJobProcessComponentData<Rotation>
    56.     {
    57.  
    58.  
    59.         public void Execute(ref Rotation rotation)
    60.         {
    61.  
    62.             rotation.Value = Random.rotation;
    63.         }
    64.     }
    65.  
    66.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    67.     {
    68.         var job = new GoGrazy { };
    69.         return job.Schedule(this, 64, inputDeps);
    70.     }
    71. }

    Edit : Only after 4 mins I found it :D But I think Compiler should have shout on it !
    Code (CSharp):
    1. public void Execute(ref Rotation rotation)
    2.         {
    3.  
    4.             rotation.Value = Random.rotation;
    5.         }

    Looks like this is unacceptable and it will crash Unity even though it will do it very silent.

    The correct way of doing it is:

    Code (CSharp):
    1. public class SystemhereWithJob : JobComponentSystem
    2. {
    3.     [ComputeJobOptimization]
    4.     public struct GoGrazy : IJobProcessComponentData<Rotation>
    5.     {
    6.         public Quaternion randomRot;
    7.  
    8.         public void Execute(ref Rotation rotation)
    9.         {
    10.  
    11.             rotation.Value = randomRot;
    12.         }
    13.     }
    14.  
    15.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    16.     {
    17.         var job = new GoGrazy { randomRot = Random.rotation };
    18.         return job.Schedule(this, 64, inputDeps);
    19.     }
    20. }
    Notice how I created a randomRot Quaternion, and it is supplied to job at Schedule part.

    I mean it makes sense. On another thread you should not call Random.value from main Unity thread but maybe a warning would be better when Jobs go final instead of silent freezing.
     
    Last edited: Mar 26, 2018
  2. GabrieleUnity

    GabrieleUnity

    Unity Technologies

    Joined:
    Sep 4, 2012
    Posts:
    116
    Absolutely. We are working on compiler augmentation and static analysis to catch these issues at compile time and warn the users accordingly.
     
  3. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    4,721
    It should throw an exception. I can reproduce the issue, thanks, we will look into it.