Skip to content

Commit

Permalink
[ECSLearn] 状态机Demo注释: 1 WithDisposeOnCompletion 可以在job执行完后直接dispose N…
Browse files Browse the repository at this point in the history
…ativeContainer 2 从Entity上获取组件GetComponentDataFromEntity,在job中需要targetPositionFromEntity【目标Entity】获取对应组件
  • Loading branch information
hexinping committed Aug 13, 2021
1 parent 2229685 commit e263201
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ protected override void OnUpdate()

var waypointHandle = Entities
.WithName("CheckReachedWaypoint") // ForEach name is helpful for debugging
.WithNone<IsChasingTag>() // WithNone means "Exclude all entities with IsChasingTag from this ForEach"
.WithNone<IsChasingTag, IdleTimer>() // WithNone means "Exclude all entities with IsChasingTag from this ForEach"
// This avoids running the waypoint checking code on guards that are chasing the player
.ForEach((
Entity e, // Refers to the current guard entity. Used by the ECB when changing states
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public static void TransitionToIdle(EntityCommandBuffer.ParallelWriter ecb, Enti
{
ecb.AddComponent(index, e, new IdleTimer {Value = 0.0f});
#if !UNITY_DISABLE_MANAGED_COMPONENTS
ecb.AddComponent<IsInTransitionTag>(index, e);
ecb.AddComponent<IsInTransitionTag>(index, e); //Idle 时加上IsInTransitionTag
#endif
}

Expand All @@ -68,10 +68,10 @@ public static void TransitionToIdle(EntityCommandBuffer.ParallelWriter ecb, Enti
/// <param name="playerPosition">The position of the player we are setting as our new TargetPosition</param>
public static void TransitionToChasing(EntityCommandBuffer.ParallelWriter ecb, Entity e, int index, float3 playerPosition)
{
ecb.AddComponent<IsChasingTag>(index, e);
ecb.AddComponent<IsChasingTag>(index, e); //追逐的特有标记
ecb.AddComponent(index, e, new TargetPosition {Value = playerPosition});
#if !UNITY_DISABLE_MANAGED_COMPONENTS
ecb.AddComponent<IsInTransitionTag>(index, e);
ecb.AddComponent<IsInTransitionTag>(index, e); //Chasing 也加上?
#endif
}

Expand All @@ -86,7 +86,7 @@ public static void TransitionToPatrolling(EntityCommandBuffer.ParallelWriter ecb
{
ecb.AddComponent(index, e, new TargetPosition {Value = waypointPosition});
#if !UNITY_DISABLE_MANAGED_COMPONENTS
ecb.AddComponent<IsInTransitionTag>(index, e);
ecb.AddComponent<IsInTransitionTag>(index, e); //Patrolling 都加上
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

// An IBufferElementData becomes a DynamicBuffer<T>
// This will reserve 8 WaypointPositions of memory per-entity in the chunk
[InternalBufferCapacity(8)]
[InternalBufferCapacity(8)] //设置容器大小
public struct WaypointPosition : IBufferElementData
{
public float3 Value;
Expand Down Expand Up @@ -42,8 +42,8 @@ public struct IdleTimer : IComponentData
// Defines a 2D cone in front of the guard, used to detect players
public struct VisionCone : IComponentData
{
public float AngleRadians;
public float ViewDistanceSq;
public float AngleRadians; //视角
public float ViewDistanceSq; //视野距离
}

// A tag that helps us tell the difference between "Patrolling" and "Chasing"
Expand Down Expand Up @@ -81,15 +81,15 @@ public void Convert(Entity entity, EntityManager dstManager, GameObjectConversio
dstManager.AddComponents(entity, new ComponentTypes(
new ComponentType[]
{
typeof(CooldownTime),
typeof(NextWaypointIndex),
typeof(TargetPosition),
typeof(WaypointPosition),
typeof(VisionCone),
typeof(MovementSpeed),
typeof(IsInTransitionTag)
typeof(CooldownTime), // 空闲时间
typeof(NextWaypointIndex), //下一个路点
typeof(TargetPosition), //移动目标
typeof(WaypointPosition),//路点的位置 BufferElementData类型,因为可以有多个
typeof(VisionCone), //视野组件
typeof(MovementSpeed), //移动速度
typeof(IsInTransitionTag) //移动时的状态区分,追逐或巡逻??
}));

// Since we've already added the WaypointPosition IBufferElementData to the entity, we need to Get the buffer to fill it
var buffer = dstManager.GetBuffer<WaypointPosition>(entity);
foreach (var waypointTransform in Waypoints)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public partial class LookForPlayerSystem : SystemBase
protected override void OnCreate()
{
m_EndSimECBSystem = World.GetExistingSystem<EndSimulationEntityCommandBufferSystem>();

//创建搜索player的筛选器
m_PlayerQuery = GetEntityQuery(ComponentType.ReadOnly<PlayerTag>(), ComponentType.ReadOnly<Translation>());
}

Expand All @@ -36,6 +38,7 @@ protected override void OnUpdate()
// Update the target position (must pass isReadOnly=false)
var targetPositionFromEntity = GetComponentDataFromEntity<TargetPosition>(false);

//WithDisposeOnCompletion ==> job执行完毕后会自动释放对应 NativeContainer
var lookHandle = Entities
.WithName("LookForPlayer") // ForEach name is helpful for debugging
.WithReadOnly(playerPosition) // Marked read only (We don't mutate the player position)
Expand All @@ -49,7 +52,8 @@ protected override void OnUpdate()
in Translation guardPosition, // "in" keyword makes the parameter ReadOnly
in Rotation guardRotation,
in VisionCone guardVisionCone
) =>

) =>
{
// If there are no players, we can safely skip this work
if (playerPosition.Length <= 0)
Expand All @@ -63,7 +67,8 @@ in VisionCone guardVisionCone
var unitVecToPlayer = math.normalize(vectorToPlayer);

// Use the dot product to determine if the player is within our vision cone
var dot = math.dot(forwardVector, unitVecToPlayer);
// 计算当前朝向和目标朝向之间的夹角的余弦值
var dot = math.dot(forwardVector, unitVecToPlayer);
var canSeePlayer = dot > 0.0f && // player is in front of us
math.abs(math.acos(dot)) < guardVisionCone.AngleRadians && // player is within the cone angle bounds
math.lengthsq(vectorToPlayer) < guardVisionCone.ViewDistanceSq; // player is within vision distance (we use Squared Distance to avoid sqrt calculation)
Expand All @@ -82,13 +87,15 @@ in VisionCone guardVisionCone
}
else
{
//非追逐下转换成追逐状态
GuardAIUtility.TransitionToChasing(ecb, guardEntity, entityInQueryIndex, playerPosition[0].Value);
}

// If the guard has an idle timer, we want to leave the idle state
// Therefore, we remove the timer from the guard
if (HasComponent<IdleTimer>(guardEntity))
{
//删除Idle组件
GuardAIUtility.TransitionFromIdle(ecb, guardEntity, entityInQueryIndex);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
#if !UNITY_DISABLE_MANAGED_COMPONENTS
class StateTransitionMaterials : IComponentData
{
public Material m_IdleMaterial;
public Material m_PatrollingMaterial;
public Material m_ChasingMaterial;
public Material m_IdleMaterial; //Idle使用材质
public Material m_PatrollingMaterial; //Patrolling使用材质
public Material m_ChasingMaterial; //Chasing使用材质
}
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ protected override void OnUpdate()
{
// Determine if we are within the StopDistance of our target.
var vectorToTarget = targetPosition.Value - guardPosition.Value;
//如果超过了最短停止距离
if (math.lengthsq(vectorToTarget) > GuardAIUtility.kStopDistanceSq)
{
// Normalize the vector to our target - this will be our movement direction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public void Convert(Entity entity, EntityManager dstManager, GameObjectConversio
{
// Here we add all of the components needed by the player
dstManager.AddComponents(entity, new ComponentTypes(
typeof(PlayerTag),
typeof(UserInputData),
typeof(MovementSpeed)));
typeof(PlayerTag), //玩家标识
typeof(UserInputData), //输入数据
typeof(MovementSpeed))); //移动速度

// Set the movement speed value from the authoring component
dstManager.SetComponentData(entity, new MovementSpeed {MetersPerSecond = MovementSpeedMetersPerSecond});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ RenderSettings:
m_ReflectionIntensity: 1
m_CustomReflection: {fileID: 0}
m_Sun: {fileID: 0}
m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1}
m_IndirectSpecularColor: {r: 0.17276844, g: 0.21589246, b: 0.2978263, a: 1}
m_UseRadianceAmbientProbe: 0
--- !u!157 &3
LightmapSettings:
m_ObjectHideFlags: 0
serializedVersion: 11
serializedVersion: 12
m_GIWorkflowMode: 1
m_GISettings:
serializedVersion: 2
Expand Down Expand Up @@ -98,7 +98,7 @@ LightmapSettings:
m_TrainingDataDestination: TrainingData
m_LightProbeSampleCountMultiplier: 4
m_LightingDataAsset: {fileID: 0}
m_UseShadowmask: 1
m_LightingSettings: {fileID: 0}
--- !u!196 &4
NavMeshSettings:
serializedVersion: 2
Expand All @@ -118,6 +118,8 @@ NavMeshSettings:
manualTileSize: 0
tileSize: 256
accuratePlacement: 0
maxJobWorkers: 0
preserveTilesOutsideBounds: 0
debug:
m_Flags: 0
m_NavMeshData: {fileID: 0}
Expand Down Expand Up @@ -176,6 +178,7 @@ MeshRenderer:
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
Expand All @@ -200,6 +203,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!1 &768734793
GameObject:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -341,6 +345,7 @@ MonoBehaviour:
m_FallbackScreenDPI: 96
m_DefaultSpriteDPI: 96
m_DynamicPixelsPerUnit: 1
m_PresetInfoIsWorld: 0
--- !u!223 &1037378163
Canvas:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -417,6 +422,7 @@ MeshRenderer:
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
Expand All @@ -441,6 +447,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &1075870892
MeshFilter:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -522,6 +529,7 @@ MeshRenderer:
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
Expand All @@ -546,6 +554,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!33 &1287682789
MeshFilter:
m_ObjectHideFlags: 0
Expand Down Expand Up @@ -710,6 +719,7 @@ Light:
m_UseColorTemperature: 0
m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0}
m_UseBoundingSphereOverride: 0
m_UseViewFrustumForShadowCasterCull: 1
m_ShadowRadius: 0
m_ShadowAngle: 0
--- !u!4 &1417656754
Expand Down Expand Up @@ -778,6 +788,8 @@ MonoBehaviour:
m_Material: {fileID: 0}
m_Color: {r: 0, g: 0, b: 0, a: 1}
m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1
m_OnCullStateChanged:
m_PersistentCalls:
m_Calls: []
Expand Down Expand Up @@ -921,6 +933,7 @@ MeshRenderer:
m_LightProbeUsage: 1
m_ReflectionProbeUsage: 1
m_RayTracingMode: 2
m_RayTraceProcedural: 0
m_RenderingLayerMask: 1
m_RendererPriority: 0
m_Materials:
Expand All @@ -945,6 +958,7 @@ MeshRenderer:
m_SortingLayerID: 0
m_SortingLayer: 0
m_SortingOrder: 0
m_AdditionalVertexStreams: {fileID: 0}
--- !u!1001 &1439216022550699745
PrefabInstance:
m_ObjectHideFlags: 0
Expand All @@ -967,6 +981,11 @@ PrefabInstance:
propertyPath: Waypoints.Array.data[1]
value:
objectReference: {fileID: 327779469}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_RootOrder
value: 8
objectReference: {fileID: 0}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_LocalPosition.x
Expand All @@ -982,6 +1001,11 @@ PrefabInstance:
propertyPath: m_LocalPosition.z
value: 5.07
objectReference: {fileID: 0}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_LocalRotation.x
Expand All @@ -997,16 +1021,6 @@ PrefabInstance:
propertyPath: m_LocalRotation.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_RootOrder
value: 8
objectReference: {fileID: 0}
- target: {fileID: 5633846768554455932, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_LocalEulerAnglesHint.x
Expand All @@ -1032,6 +1046,11 @@ PrefabInstance:
propertyPath: m_Name
value: Guard
objectReference: {fileID: 0}
- target: {fileID: 8672214540600007728, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 8903556393890852412, guid: 3a95237b170224a3a92b0c33ec8b87f1,
type: 3}
propertyPath: m_Materials.Array.data[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#if !UNITY_DISABLE_MANAGED_COMPONENTS
[UpdateInGroup(typeof(PresentationSystemGroup))]
[UpdateBefore(typeof(RenderMeshSystemV2))]
[UpdateBefore(typeof(RenderMeshSystemV2))] //RenderMeshSystemV2 是HyBrid里的system
public partial class StateTransitionVisualizationSystem : SystemBase
{
private EntityQuery m_StateTransitionMaterialSingletonQuery;
Expand All @@ -33,15 +33,15 @@ protected override void OnUpdate()
var meshRenderer = EntityManager.GetSharedComponentData<RenderMesh>(e);

if (HasComponent<IdleTimer>(e))
meshRenderer.material = materials.m_IdleMaterial;
meshRenderer.material = materials.m_IdleMaterial; //Idle状态
else if (HasComponent<IsChasingTag>(e))
meshRenderer.material = materials.m_ChasingMaterial;
meshRenderer.material = materials.m_ChasingMaterial; //追逐状态
else
meshRenderer.material = materials.m_PatrollingMaterial;

EntityManager.SetSharedComponentData(e, meshRenderer);
EntityManager.RemoveComponent<IsInTransitionTag>(e);
}).Run();
}).Run(); //Run 是在主线程执行
}
}
#endif
Loading

0 comments on commit e263201

Please sign in to comment.