#Trouble with implementing unity.physics with ECS using DOTS stack

1 messages · Page 1 of 1 (latest)

somber harbor
#

Hello I am having trouble implementing a working physics solution for my enemies, I want to add a physics rigid body and collider to them, unsure what I am doing wrong as I can't seen to get them to collide with each other and instead they just go right through each other. here is my code:

using UnityEngine;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Physics;
class EnemyAuthoring : MonoBehaviour
{
    public float3 TargetPosition;
    public float Speed;
}

 class EnemyBaker : Baker<EnemyAuthoring>
{
    public override void Bake(EnemyAuthoring authoring)
    {
        var entity = GetEntity(TransformUsageFlags.None);
        AddComponent(entity, new Enemy
        {
            CurrentPosition = float3.zero,
            TargetPosition = authoring.TargetPosition,
            Entity = entity,
            PhysicsVelocity = new PhysicsVelocity { Linear = float3.zero },
            PhysicsMass = PhysicsMass.CreateDynamic(MassProperties.UnitSphere, 1.0f),
            PhysicsCollider = new PhysicsCollider { Value = Unity.Physics.SphereCollider.Create(new SphereGeometry { Radius = 8.0f, Center = float3.zero }) }
        });

        AddComponent(entity, new LocalTransform
        {
            Position = float3.zero,
            Rotation = quaternion.identity,
            Scale = 1.0f
        });

    }
}
mellow vale
#

it's a lot easier if you have a MonoBehaviour prefab for your enemies and you add the Physics Shape and Physics Body authoring components there

somber harbor
# mellow vale You need to add the physics components as components on the entity, not as membe...

thanks for the response, I have a prefab enemy but they are controlled by different ECS, there is no monoBehaviour besides this one on the enemy prefab, as I am trying to spawning many thousands, there is an ECS that spawns the enemies, one that moves them and this one which adds components, so I have to add a physics body and physics shape each as a seperate component the same way I added the LocalTransform component ?

mellow vale
#

what do you mean by "different ECS"?

somber harbor
#

well I have one component system that spawns the enemies and one that adds the components to them, which is this code, the code above is the script attached to each enemy, I had a look at that documentation but there didn't seem to be anything in it about how to create the physics bodies and shapes in the code they had as an example, I tried to do this but it also didn't work:

        AddComponent(entity, PhysicsMass.CreateDynamic(MassProperties.UnitSphere, 1.0f));
        AddComponent(entity, new PhysicsVelocity
        {
            Linear = float3.zero
        });

        AddComponent(entity, new PhysicsCollider
        {
            Value = Unity.Physics.SphereCollider.Create(new SphereGeometry { Radius = 8.0f, Center = float3.zero })
        });
#
using Unity.Entities;
using Unity.Transforms;
using Unity.Burst;
using UnityEngine;


[BurstCompile]
public partial struct SpawnerSystem : ISystem
{
    public static int counter = 0;
    public void OnCreate(ref SystemState state) { }

    public void OnDestroy(ref SystemState state) { }

    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        foreach (RefRW<EnemySpawner> spawner in SystemAPI.Query<RefRW<EnemySpawner>>())
        {
            ProcessSpawner(ref state, spawner);
        }
    }
    private void ProcessSpawner(ref SystemState state, RefRW<EnemySpawner> spawner)
    {
        if (spawner.ValueRO.NextSpawnTime < SystemAPI.Time.ElapsedTime)
        {
            counter++;
            Entity newEntity = state.EntityManager.Instantiate(spawner.ValueRO.Prefab);
            state.EntityManager.SetComponentData(newEntity, LocalTransform.FromPosition(spawner.ValueRO.SpawnPosition));
            spawner.ValueRW.NextSpawnTime = (float)SystemAPI.Time.ElapsedTime + spawner.ValueRO.SpawnRate;

        }
    }
}

here is the enemySpawner system too

mellow vale
#

So you have a MonoBehaviour for the EnemySpawner, and that has a prefab that has the Enemy authoring component

#

You can just add the physics components to your Enemy prefab, you don't need to add them in your EnemyBaker as that would be exactly the same result

somber harbor
#

yes to the first part that is how I have it set up, I had the components added to the enemy (normal rigid body and collidor) in the editor component part of the prefab but they did not collide at all

mellow vale
#

how are you moving the enemies?

#

also you can turn on the physics debug rendering to make sure the colliders are working

somber harbor
#
using UnityEngine;
using Unity.Entities;
using Unity.Burst;
using Unity.Transforms;
using Unity.Mathematics;
using Unity.Physics;
[BurstCompile]
public partial struct EnemySystem : ISystem
{

    public void OnCreate(ref SystemState state)
    {

    }
    public void OnDestroy(ref SystemState state) { }
    [BurstCompile]
    public void OnUpdate(ref SystemState state)
    {
        var _player = GameObject.FindGameObjectWithTag("Player");
        float3 playerPosition = _player.transform.position;
        int enemyCount = 0;
        foreach (var (enemy, localTransform) in SystemAPI.Query<RefRW<Enemy>, LocalTransform>())
        {
            enemyCount++;
            MoveEnemy(ref state, enemy, playerPosition);
        }
    }
    private void MoveEnemy(ref SystemState state, RefRW<Enemy> enemy, float3 targetPosition)
    {
        Vector2 targetPosition2D = new Vector2(targetPosition.x, targetPosition.y);

        Entity enemyEntity = enemy.ValueRW.Entity;
        LocalTransform enemyTransform = state.EntityManager.GetComponentData<LocalTransform>(enemyEntity);


        Vector2 enemyPosition2D = new Vector2(enemyTransform.Position.x, enemyTransform.Position.y);

        Vector2 directionToPlayer = (targetPosition2D - enemyPosition2D).normalized;

 
        float speed = 0.01f;
        
        
        
        enemyTransform.Position.x += directionToPlayer.x * speed;
        enemyTransform.Position.y += directionToPlayer.y * speed;

        enemy.ValueRW.CurrentPosition = new float3(enemyTransform.Position.x, enemyTransform.Position.y, enemyTransform.Position.z);

        state.EntityManager.SetComponentData(enemyEntity, enemyTransform);
        state.EntityManager.SetComponentData(enemyEntity, enemy.ValueRW);
    }
}

oh sorry here is the enemySystem, that I use to move my enemies, it seems to work fine and how I want it too, I will have a look at that documentation too, how can I turn on the debug rendering?

mellow vale
#

you should have these components on a single game object in a subscene:

somber harbor
#

ok sweet, I think I figured out one part I was doing wrong also, I wasnt adding thephysics shape and physics body but adding a rigidbody2d and a boxcollider component to the prefab, I think this is now causing another problem with my code with adding the local transform component in my enemy authoring bake script

#

yeah so I think I have collision going now, but I think I have broken the localTransform part of my enemySystem, I had to delete the addComponent in the enemy authoring that added a localTransform

mellow vale
#

oh yeah you don't need the LocalTransform, that gets added automatically based on the flags you pass to GetEntity in the baker