Last active
March 29, 2020 16:33
-
-
Save tsubaki/9f5841aae552965b9e90c72475001dc0 to your computer and use it in GitHub Desktop.
UnityPhysics 0.3.1と Entities 0.8.0 の組み合わせ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Unity.Collections; | |
using Unity.Entities; | |
using Unity.Jobs; | |
using Unity.Physics; | |
using Unity.Physics.Systems; | |
using static Unity.Entities.ComponentType; | |
namespace BallSystems | |
{ | |
// ボール | |
[GenerateAuthoringComponent] | |
public struct Ball : IComponentData | |
{ | |
public float Lifetime; // 接触時にLifeTimeに渡す値 | |
} | |
// ボールの生存時間 | |
// 本system郡でのみ使用する | |
struct Lifetime : IComponentData | |
{ | |
public float Value; // 生存時間、0になったら死ぬ | |
} | |
// ボールが接触したら1秒後に破棄するシステム | |
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() | |
{ | |
// 当たり判定からLifetimeを追加するジョブを実行 | |
// 普通にITriggerEventsJobのジョブを実行。依存関係はthis.Dependencyで取得 | |
Dependency = new HitEventJob | |
{ | |
balls = GetComponentDataFromEntity<Ball>(true), | |
lifetimes = GetComponentDataFromEntity<Lifetime>(true), | |
commands = _commandSystem.CreateCommandBuffer() | |
}.Schedule(_stepPhysicsWorldSystem.Simulation, ref _buildPhysicsWorldSystem.PhysicsWorld, Dependency); | |
_commandSystem.AddJobHandleForProducer(Dependency); | |
} | |
// 接触判定 | |
[Unity.Burst.BurstCompile] | |
struct HitEventJob : ITriggerEventsJob | |
{ | |
[ReadOnly] public ComponentDataFromEntity<Ball> balls; | |
[ReadOnly] public ComponentDataFromEntity<Lifetime> lifetimes; | |
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); | |
} | |
// Ballを持ちlieftimeを持っていない場合にTrueを返す | |
private bool HasBallTagWithoutInterval(Entity entity) | |
{ | |
return balls.Exists(entity) && !lifetimes.Exists(entity); | |
} | |
// 接触時の処理を実行 | |
public void DoProcess(Entity entity) | |
{ | |
commands.AddComponent(entity, new Lifetime { Value = balls[entity].Lifetime }); | |
} | |
} | |
} | |
public class BallLifetimeSystem : SystemBase | |
{ | |
EntityCommandBufferSystem _commandSystem; | |
protected override void OnCreate() | |
{ | |
_commandSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>(); | |
} | |
protected override void OnUpdate() | |
{ | |
// Entities.ForEach的に、システムで使用するデータは全てローカル変数として書き出しておく | |
var commands = _commandSystem.CreateCommandBuffer(); | |
var dt = Time.DeltaTime; | |
// LifetimeをチェックしてEntityを破棄するジョブを実行 | |
Entities | |
.ForEach((Entity entity, ref Lifetime interval) => | |
{ | |
interval.Value -= dt; | |
if (interval.Value < 0) | |
{ | |
commands.DestroyEntity(entity); | |
} | |
}).Schedule(); | |
_commandSystem.AddJobHandleForProducer(Dependency); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment