Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Raycast Miss, How to run ComponentSystem after subscene is loaded?

Discussion in 'Physics for ECS' started by entropin_unity, Jan 11, 2020.

  1. entropin_unity

    entropin_unity

    Joined:
    Dec 31, 2019
    Posts:
    1
    Hi, I have a basic system that creates a grid of cubes, before every cube is instantiated, I would like to do a RayCast to determine the Y coordinate to place the box. But the raycast only returns a hit after a few seconds, the first time the system runs it can't find any colliders, so I'm guessing that the system is run before the subscene is created so i can't find the floor colliders.

    How can I fix this?

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Mathematics;
    3. using Unity.Physics;
    4. using Unity.Physics.Systems;
    5. using Unity.Transforms;
    6. using UnityEngine;
    7.  
    8. public struct RotateTractorInfo : IComponentData
    9. {
    10.     public float Speed;
    11.     public Vector3 lastKnownLocation;
    12.     public Vector3 teleportPoss;
    13. }
    14.  
    15. [UpdateAfter(typeof(RequestSceneLoaded))]
    16. public class RotateTractorSpawnerSystem : ComponentSystem
    17. {
    18.     // Start is called before the first frame update
    19.     void Start()
    20.     {
    21.  
    22.     }
    23.  
    24.     // Update is called once per frame
    25.     void Update()
    26.     {
    27.  
    28.     }
    29.  
    30.     protected override void OnUpdate()
    31.     {
    32.  
    33.         var collisionWorld = World.GetOrCreateSystem<BuildPhysicsWorld>().PhysicsWorld.CollisionWorld;
    34.  
    35.         float horizone = 2.0f;
    36.         float spacing  = 4.0f;
    37.         Entities.ForEach((Entity entity, ref RotateTractorInitData spawnerData) =>
    38.         {
    39.             float spaceStepsX = 0;
    40.             float spaceStepsZ = 0;
    41.             for (int x = 0; x < spawnerData.NumXCubes; ++x)
    42.             {
    43.                 float posX = spaceStepsX - (spawnerData.NumXCubes / 2);
    44.                 spaceStepsX += spacing;
    45.  
    46.                 spaceStepsZ = 0;
    47.                 for (int z = 0; z < spawnerData.NumZCubes; ++z)
    48.                 {
    49.                     float posZ = spaceStepsZ - (spawnerData.NumZCubes / 2);
    50.                     spaceStepsZ += spacing;
    51.                     // Actually create a rotating cube entity from the prefab.
    52.                     var rotatingCubeEntity = EntityManager.Instantiate(spawnerData.RotatingCubePrefabEntity);
    53.  
    54.                     var initPosition = new float3(posX, horizone, posZ);
    55.                     var adjustedPosition = adjustForGroundLevel(collisionWorld, initPosition);
    56.  
    57.                     // Set the position of the rotating cube.
    58.                     EntityManager.SetComponentData(rotatingCubeEntity, new Translation { Value = adjustedPosition });
    59.                     EntityManager.AddComponentData(rotatingCubeEntity, new RotateTractorInfo { Speed = spawnerData.RotationSpeed, lastKnownLocation = new float3(0f, 0f, 0f) });
    60.                     EntityManager.AddComponentData(rotatingCubeEntity, new Tractorbeam.Information { TractorLocation = new Vector3(posX, horizone, posZ) });
    61.                 }
    62.             }
    63.  
    64.             // We should destroy this spawner entity because if we don't, the spawner will run again on the next frame
    65.             // and spawn another NumCubes rotating cubes!
    66.             EntityManager.DestroyEntity(entity);
    67.         });
    68.     }
    69.  
    70.     float3 adjustForGroundLevel(CollisionWorld collisionWorld, float3 poss)
    71.     {
    72.         float3 aimDir = new float3(0f, -1f, 0f);
    73.         float beamDistance = 100f;
    74.  
    75.  
    76.         var staticGeomFilter = CollisionFilter.Default;
    77.         staticGeomFilter.CollidesWith = 1 << 0;
    78.  
    79.         var closestHit = new Unity.Physics.RaycastHit();
    80.         RaycastInput castInput = new RaycastInput
    81.         {
    82.             Start = poss,
    83.             End = poss + aimDir * beamDistance,
    84.             Filter = CollisionFilter.Default
    85.         };
    86.  
    87.  
    88.             if (collisionWorld.CastRay(castInput, out closestHit))
    89.             {
    90.             //Dose not hit here unit a few hundred loops
    91.             return closestHit.Position;
    92.         }
    93.  
    94.         return poss;
    95.     }
    96. }