Skip to content

Instantly share code, notes, and snippets.

@tsubaki
Created March 29, 2020 13:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsubaki/0a2c2041192ef231fcc46390a41ae980 to your computer and use it in GitHub Desktop.
Save tsubaki/0a2c2041192ef231fcc46390a41ae980 to your computer and use it in GitHub Desktop.
UnityPhysics 0.3.1と Entities 0.8.0 の組み合わせ
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Physics;
using Unity.Physics.Systems;
[GenerateAuthoringComponent]
public struct BallTag : IComponentData{}
[AlwaysUpdateSystem]
public class BallHitSystem : SystemBase
{
EntityCommandBufferSystem _commandSystem;
BuildPhysicsWorld _buildPhysicsWorldSystem;
StepPhysicsWorld _stepPhysicsWorldSystem;
protected override void OnCreate()
{
_commandSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
_buildPhysicsWorldSystem = World.GetOrCreateSystem<BuildPhysicsWorld>();
_stepPhysicsWorldSystem = World.GetOrCreateSystem<StepPhysicsWorld>();
}
protected override void OnUpdate()
{
// Entities.ForEach的に、システムで使用するデータは全てローカル変数として書き出しておく
var commands = _commandSystem.CreateCommandBuffer();
var dt = Time.DeltaTime;
// 普通にITriggerEventsJobのジョブを実行。依存関係はthis.Dependencyで取得
Dependency = new HitEvent
{
ballTags = GetComponentDataFromEntity<BallTag>(true),
intervals = GetComponentDataFromEntity<Interval>(true),
commands = commands
}.Schedule(_stepPhysicsWorldSystem.Simulation, ref _buildPhysicsWorldSystem.PhysicsWorld, Dependency );
// 追加処理はEntiites.ForEachで行っても大丈夫。こちらはDependencyを省略可
Dependency = Entities
.WithAll<BallTag>()
.ForEach((Entity entity, ref Interval interval)=>{
interval.Value -= dt;
if( interval.Value < 0)
{
commands.DestroyEntity(entity);
}
}).Schedule(Dependency);
_commandSystem.AddJobHandleForProducer(Dependency);
}
[Unity.Burst.BurstCompile]
struct HitEvent : ITriggerEventsJob
{
[ReadOnly] public ComponentDataFromEntity<BallTag> ballTags;
[ReadOnly] public ComponentDataFromEntity<Interval> intervals;
public EntityCommandBuffer commands;
public void Execute(TriggerEvent triggerEvent)
{
if (HasBallTagWithoutInterval(triggerEvent.Entities.EntityA))
DoProcess(triggerEvent.Entities.EntityA);
if (HasBallTagWithoutInterval(triggerEvent.Entities.EntityB))
DoProcess(triggerEvent.Entities.EntityB);
}
private bool HasBallTagWithoutInterval(Entity entity)
{
return ballTags.Exists(entity) && !intervals.Exists(entity);
}
public void DoProcess(Entity entity)
{
commands.AddComponent(entity, new Interval { Value = 1f });
}
}
struct Interval : IComponentData
{
public float Value;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment