Hello everyone. I am new to Unity DOTS and I need to learn how to create terrain. After I had seen that Using Unity Terrain with DOTS workflow thread, I tried to do the same thing as Avol done there (2 page). But I got some error which I poorly understand and do not know what to do with it
Here is the full text of it:
AssertionException: Assertion failure. Value was False
Expected: True
UnityEngine.Assertions.Assert.Fail (System.String message, System.String userMessage) (at :0)
UnityEngine.Assertions.Assert.IsTrue (System.Boolean condition, System.String message) (at :0)
UnityEngine.Assertions.Assert.IsTrue (System.Boolean condition) (at :0)
Unity.Physics.Math+ScaledMTransform…ctor (Unity.Mathematics.RigidTransform transform, System.Single uniformScale) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Base/Math/Physics_Transform.cs:109)
Unity.Physics.RigidBody+RigidBodyUtil.CastRay[T] (Unity.Entities.BlobAssetReference1[T] bodyCollider, Unity.Entities.Entity rbEntity, Unity.Physics.RaycastInput input, T& collector, Unity.Mathematics.RigidTransform worldFromBody, System.Single unifromScale) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/RigidBody/RigidBody.cs:110) Unity.Physics.RigidBody.CastRay[T] (Unity.Physics.RaycastInput input, T& collector) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/RigidBody/RigidBody.cs:92) Unity.Physics.Broadphase+BvhLeafProcessor.RayLeaf[T] (Unity.Physics.RaycastInput input, System.Int32 rigidBodyIndex, T& collector) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/World/Broadphase.cs:624) Unity.Physics.BoundingVolumeHierarchy.Raycast[TProcessor,TCollector] (Unity.Physics.RaycastInput input, TProcessor& leafProcessor, TCollector& collector) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/Geometry/BoundingVolumeHierarchy.cs:373) Unity.Physics.Broadphase.CastRay[T] (Unity.Physics.RaycastInput input, Unity.Collections.NativeArray
1[T] rigidBodies, T& collector) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/World/Broadphase.cs:534)
Unity.Physics.CollisionWorld.CastRay[T] (Unity.Physics.RaycastInput input, T& collector) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/World/CollisionWorld.cs:338)
Unity.Physics.QueryWrappers.RayCast[T] (T& target, Unity.Physics.RaycastInput input, Unity.Physics.RaycastHit& closestHit) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/Queries/Collidable.cs:664)
Unity.Physics.CollisionWorld.CastRay (Unity.Physics.RaycastInput input, Unity.Physics.RaycastHit& closestHit) (at ./Library/PackageCache/com.unity.physics@1.0.11/Unity.Physics/Collision/World/CollisionWorld.cs:318)
MovementJob.Execute (Unity.Transforms.LocalTransform& transform, MovementComponent& movementComponent) (at Assets/Scripts/Player/MovementSystem.cs:72)
MovementJob.Execute (Unity.Entities.ArchetypeChunk& chunk, System.Int32 chunkIndexInQuery, System.Boolean useEnabledMask, Unity.Burst.Intrinsics.v128& chunkEnabledMask) (at Unity.Entities.SourceGen.JobEntityGenerator/Unity.Entities.SourceGen.JobEntity.JobEntityGenerator/Temp/GeneratedCode/Assembly-CSharp/MovementSystem__JobEntity_4119310620.g.cs:34)
MovementJob.Unity.Entities.IJobChunk.Execute (Unity.Entities.ArchetypeChunk& chunk, System.Int32 unfilteredChunkIndex, System.Boolean useEnabledMask, Unity.Burst.Intrinsics.v128& chunkEnabledMask) (at :0)
Unity.Entities.JobChunkExtensions+JobChunkProducer1[T].ExecuteInternal (Unity.Entities.JobChunkExtensions+JobChunkWrapper
1[T]& jobWrapper, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/IJobChunk.cs:412)
Unity.Entities.JobChunkExtensions+JobChunkProducer1[T].Execute (Unity.Entities.JobChunkExtensions+JobChunkWrapper
1[T]& jobWrapper, System.IntPtr additionalPtr, System.IntPtr bufferRangePatchData, Unity.Jobs.LowLevel.Unsafe.JobRanges& ranges, System.Int32 jobIndex) (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/IJobChunk.cs:359)
Unity.Jobs.JobHandle:ScheduleBatchedJobsAndComplete(JobHandle&)
Unity.Jobs.JobHandle:Complete()
MovementSystem:OnUpdate(SystemState&) (at Assets/Scripts/Player/MovementSystem.cs:34)
MovementSystem:__codegen__OnUpdate(IntPtr, IntPtr)
Unity.Entities.<>c__DisplayClass9_0:b__0(IntPtr, IntPtr) (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/SystemBaseRegistry.cs:256)
Unity.Entities.UnmanagedUpdate_0000158C$BurstDirectCall:wrapper_native_indirect_000001D9106A1AE0(IntPtr&, Void*)
Unity.Entities.UnmanagedUpdate_0000158C$BurstDirectCall:Invoke(Void*)
Unity.Entities.WorldUnmanagedImpl:UnmanagedUpdate(Void*) (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/WorldUnmanaged.cs:828)
Unity.Entities.WorldUnmanagedImpl:UpdateSystem(SystemHandle) (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/WorldUnmanaged.cs:894)
Unity.Entities.ComponentSystemGroup:UpdateAllSystems() (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/ComponentSystemGroup.cs:729)
Unity.Entities.ComponentSystemGroup:OnUpdate() (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/ComponentSystemGroup.cs:693)
Unity.Entities.SystemBase:Update() (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/SystemBase.cs:418)
Unity.Entities.DummyDelegateWrapper:TriggerUpdate() (at ./Library/PackageCache/com.unity.entities@1.0.11/Unity.Entities/ScriptBehaviourUpdateOrder.cs:526)
Here is the code where error refers if I double click it
/// <summary> Constructor. </summary>
///
/// <param name="transform"> The transform. </param>
/// <param name="uniformScale"> The uniform scale. </param>
public ScaledMTransform(RigidTransform transform, float uniformScale)
{
Transform = new MTransform(transform);
UnityEngine.Assertions.Assert.IsTrue(uniformScale != 0.0f);
m_Scale = uniformScale;
}
And here are my own pretty simple code:
public partial struct MovementSystem : ISystem
{
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<MovementComponent>();
}
public void OnUpdate(ref SystemState state)
{
var moveJob = new MovementJob { time = SystemAPI.Time.DeltaTime, collisionWorld = SystemAPI.GetSingleton<PhysicsWorldSingleton>().CollisionWorld };
JobHandle a = moveJob.Schedule(state.Dependency);
a.Complete();
}
public void OnDestroy(ref SystemState state)
{
}
}
public partial struct MovementJob : IJobEntity
{
public float time;
public CollisionWorld collisionWorld;
public void Execute(ref LocalTransform transform, in MovementComponent movementComponent)
{
if (math.distancesq(movementComponent.target, transform.Position) < 1f)
return;
RaycastInput rayDown = new RaycastInput
{
Start = transform.Position,
End = transform.Position + math.mul(transform.Rotation, new float3(0f, -100f, 0f)),
Filter = new CollisionFilter
{
BelongsTo = ~0u,
CollidesWith = 1u << 7,
GroupIndex = 0
}
};
if (collisionWorld.CastRay(rayDown, out Unity.Physics.RaycastHit closestHit))
{
transform.Position.y = closestHit.Position.y + 1;
//transform.Rotation = Quaternion.Euler(closestHit.SurfaceNormal);
//Debug.Log(closestHit.SurfaceNormal);
}
else
{
Debug.Log("ERROR: Terrain under unit is not found");
}
float3 tempDir = movementComponent.target - transform.Position;
tempDir.y = 0;
float3 dir = math.normalize(tempDir);
transform.Position += dir * time * movementComponent.speed;
}
}
public class TerrainAuthoring : MonoBehaviour
{
[SerializeField] LayerMask belongsToLayers;
[SerializeField] LayerMask collidesWithLayers;
[SerializeField] int groupIndex;
private void Awake()
{
if (!TryGetComponent(out Terrain terrain))
{
Debug.Log("Terrain component was not found");
return;
}
CollisionFilter filter = new CollisionFilter
{
BelongsTo = (uint)belongsToLayers.value,
CollidesWith = (uint)collidesWithLayers.value,
GroupIndex = groupIndex
};
PhysicsCollider terrainCollider = CreateTerrainCollider(terrain.terrainData, filter);
EntityManager entityManager = World.DefaultGameObjectInjectionWorld.EntityManager;
Entity terrainEntity = entityManager.CreateEntity();
Debug.Log("Created Entity");
entityManager.AddComponent<PhysicsCollider>(terrainEntity);
Debug.Log("Added PhysicsCollider");
entityManager.SetComponentData<PhysicsCollider>(terrainEntity, terrainCollider);
Debug.Log("Setted PhysicsCollider");
entityManager.AddComponent<LocalToWorld>(terrainEntity);
Debug.Log("Added LocalToWorld");
entityManager.AddComponent<LocalTransform>(terrainEntity);
Debug.Log("Added LocalTransform");
entityManager.AddComponent<PhysicsWorldIndex>(terrainEntity);
Debug.Log("Added PhysicsWorldIndex");
}
private PhysicsCollider CreateTerrainCollider (TerrainData terrainData, CollisionFilter collisionFilter)
{
int resolution = terrainData.heightmapResolution;
int2 size = new int2(resolution, resolution);
Vector3 scale = terrainData.heightmapScale;
Debug.Log(scale);
NativeArray<float> heights = new NativeArray<float>(resolution * resolution, Allocator.Temp);
float[,] temporaryHeightsMatrice = terrainData.GetHeights(0, 0, resolution, resolution);
for (int j = 0; j < size.y; j++)
for (int i = 0; i < size.x; i++)
{
var h = temporaryHeightsMatrice[i, j];
heights[j + i * size.x] = h;
}
Debug.Log("Check");
PhysicsCollider collider = new PhysicsCollider
{
Value = Unity.Physics.TerrainCollider.Create(heights, size, scale, Unity.Physics.TerrainCollider.CollisionMethod.Triangles)
};
Debug.Log("Check2");
heights.Dispose();
Debug.Log("Check3");
return collider;
}
}
And here is the hierarchy, character components and terrain components (maybe my mistake is there, I don`t know :()
Because all debugs in TerrainAuthoring appear in Console, I suggest that terrain entity was at least created. But when MovingSystem is trying to Raycast it, some problem appears. But what is it and how to solve it?..