- Home /
"OnStart" for each PhysicsVelocity entity ?
I have a bunch of entities that I need to give an initial velocity
physicsVelocity.Linear = velocity
How would I do that for all entities, as OnStartRunning
in system is only called once and as soon as there is one entity in scene it stops ? So basically I would need something like Start()
in MonoBehaviour
, but for each entity.
You can use "foreach" functionality provided by entity manager to loop through all entities with "physicsVelocity" component. Assign your initial velocity there, OR you can give an initial velocity when you are assigning a "physicsVelocity" component to an entity. Take a look at this ECS documentation from unity.
Answer by andrew-lukasik · Apr 30 at 10:40 AM
What you need to do is to add:
VelocityDelta
&PhysicsVelocity
components to an entity
OR
VelocityDeltaComponent
&PhysicsBody
components to aGameObject
(that you convert into an entity)
VelocityDeltaSystem
looks for entities with VelocityDelta
components then:
applies an one-time change in it's
PhysicsVelocity.Linear
removes the
VelocityDelta
component (so the vel change won't reapeat)note:
VelocityDeltaSystem
executes only when the matching entities exist and is idle otherwise.
VelocityDeltaComponent.cs
using UnityEngine;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Transforms;
using Unity.Physics;
[DisallowMultipleComponent]
public class VelocityDeltaComponent : MonoBehaviour, IConvertGameObjectToEntity
{
[SerializeField] public Vector3 _delta = new Vector3{ z=10 };
public void Convert ( Entity e , EntityManager cmd , GameObjectConversionSystem cs )
=> cmd.AddComponentData( e , new VelocityDelta{ Value = _delta } );
#if UNITY_EDITOR
void OnDrawGizmosSelected ()
{
Gizmos.color = Color.yellow;
Gizmos.DrawLine( transform.position , transform.position + transform.TransformDirection(_delta) );
}
#endif
}
public struct VelocityDelta : IComponentData
{
public float3 Value;
}
public partial class VelocityDeltaSystem : SystemBase
{
EndFixedStepSimulationEntityCommandBufferSystem _commandBufferSystem;
protected override void OnCreate ()
{
_commandBufferSystem = World.GetOrCreateSystem<EndFixedStepSimulationEntityCommandBufferSystem>();
}
protected override void OnUpdate ()
{
var cmd = _commandBufferSystem.CreateCommandBuffer().AsParallelWriter();
Entities
.ForEach( ( ref PhysicsVelocity velocity , in VelocityDelta delta , in LocalToWorld transform , in Entity e , in int nativeThreadIndex ) =>
{
velocity.Linear += math.mul( delta.Value , math.inverse( (float3x3) transform.Value ) );
cmd.RemoveComponent<VelocityDelta>( nativeThreadIndex , e );
} )
.WithBurst()
.ScheduleParallel();
_commandBufferSystem.AddJobHandleForProducer( this.Dependency );
}
}
Indeed, it works. I found a different approach as well, but this one might be more useful. Thank you.