1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
#pragma warning disable 0282 // Allows the 'partial' keyword without warnings
#if MODULE_ENTITIES
using Unity.Entities;
using Unity.Collections;
using UnityEngine;
using Unity.Transforms;
using Unity.Collections.LowLevel.Unsafe;
namespace Pathfinding.ECS {
using Pathfinding;
public partial struct JobManagedOffMeshLinkTransition : IJobEntity {
public EntityCommandBuffer commandBuffer;
public float deltaTime;
public void Execute (Entity entity, ManagedState state, ref LocalTransform transform, ref AgentMovementPlane movementPlane, ref MovementControl movementControl, ref MovementSettings movementSettings, ref AgentOffMeshLinkTraversal linkInfo, ManagedAgentOffMeshLinkTraversal managedLinkInfo) {
if (!MoveNext(entity, state, ref transform, ref movementPlane, ref movementControl, ref movementSettings, ref linkInfo, managedLinkInfo, deltaTime)) {
commandBuffer.RemoveComponent<AgentOffMeshLinkTraversal>(entity);
commandBuffer.RemoveComponent<ManagedAgentOffMeshLinkTraversal>(entity);
}
}
public static bool MoveNext (Entity entity, ManagedState state, ref LocalTransform transform, ref AgentMovementPlane movementPlane, ref MovementControl movementControl, ref MovementSettings movementSettings, ref AgentOffMeshLinkTraversal linkInfo, ManagedAgentOffMeshLinkTraversal managedLinkInfo, float deltaTime) {
unsafe {
managedLinkInfo.context.SetInternalData(entity, ref transform, ref movementPlane, ref movementControl, ref movementSettings, ref linkInfo, state, deltaTime);
}
// Initialize the coroutine during the first step.
// This can also happen if the entity is duplicated, since the coroutine cannot be cloned.
if (managedLinkInfo.coroutine == null) {
// If we are calculating a path right now, cancel that path calculation.
// We don't want to calculate a path while we are traversing an off-mesh link.
state.CancelCurrentPathRequest();
if (managedLinkInfo.stateMachine == null) {
managedLinkInfo.stateMachine = managedLinkInfo.handler != null? managedLinkInfo.handler.GetOffMeshLinkStateMachine(managedLinkInfo.context) : null;
}
managedLinkInfo.coroutine = managedLinkInfo.stateMachine != null? managedLinkInfo.stateMachine.OnTraverseOffMeshLink(managedLinkInfo.context).GetEnumerator() : JobStartOffMeshLinkTransition.DefaultOnTraverseOffMeshLink(managedLinkInfo.context).GetEnumerator();
}
bool finished;
bool error = false;
bool popParts = true;
try {
finished = !managedLinkInfo.coroutine.MoveNext();
} catch (AgentOffMeshLinkTraversalContext.AbortOffMeshLinkTraversal) {
error = true;
finished = true;
popParts = false;
}
catch (System.Exception e) {
Debug.LogException(e, managedLinkInfo.context.gameObject);
// Teleport the agent to the end of the link as a fallback, if there's an exception
managedLinkInfo.context.Teleport(managedLinkInfo.context.link.relativeEnd);
finished = true;
error = true;
}
if (finished) {
try {
if (managedLinkInfo.stateMachine != null) {
if (error) managedLinkInfo.stateMachine.OnAbortTraversingOffMeshLink();
else managedLinkInfo.stateMachine.OnFinishTraversingOffMeshLink(managedLinkInfo.context);
}
} catch (System.Exception e) {
// If an exception happens when exiting the state machine, log it, and then continue with the cleanup
Debug.LogException(e, managedLinkInfo.context.gameObject);
}
managedLinkInfo.context.Restore();
if (popParts) {
// Pop the part leading up to the link, and the link itself
state.PopNextLinkFromPath();
}
}
return !finished;
}
}
public partial struct JobManagedOffMeshLinkTransitionCleanup : IJobEntity {
public void Execute (ManagedAgentOffMeshLinkTraversal managedLinkInfo) {
managedLinkInfo.stateMachine.OnAbortTraversingOffMeshLink();
}
}
}
#endif
|