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.
What you need to do is to add:
VelocityDelta
& PhysicsVelocity
components to an entity
OR
VelocityDeltaComponent
& PhysicsBody
components to a GameObject
(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 );
}
}