Skip to content

Commit 6d4e13b

Browse files
authored
Merge pull request #378 from crashkonijn/feature/configurable-delta-time
Feature: Added configurable deltaTime
2 parents ab68ad5 + 8fb1dd6 commit 6d4e13b

File tree

10 files changed

+83
-53
lines changed

10 files changed

+83
-53
lines changed

Package/Documentation/Classes/AgentBehaviourAndActionProvider.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,23 @@ Actions often have associated targets, indicating a position the agent should re
5959

6060
Some actions might need the agent to perform tasks while moving. The `MoveMode` in the `ActionConfig` allows for such configurations.
6161

62+
### Run In Unity Update
63+
When set to true will call `Run` from the `Update` method. When set to false you must call `Run()` or `Run(float deltaTime)` yourself.
64+
65+
Calling the `Run` method manually gives you full control over the agent's update cycle.
66+
67+
```csharp
68+
agentBehaviour.RunInUnityUpdate = false;
69+
agentBehaviour.Run(1f);
70+
71+
// In actions
72+
public override IActionRunState Perform(IMonoAgent agent, Data data, IActionContext context)
73+
{
74+
// Make sure to use the deltaTime provided in the context!
75+
var deltaTime = context.DeltaTime;
76+
}
77+
```
78+
6279
### Distance Multiplier
6380

6481
The primary objective of actions is to achieve goals swiftly. If the action's cost equates to its completion time, then the heuristic's distance value should be divided by the agent's movement speed. Using `SetDistanceMultiplierSpeed(float speed)` sets the agent's (max/average) speed, enabling the planner to more precisely ascertain the optimal action.

Package/Documentation/upgrade/upgrade-guide-3.0-3.1.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,19 @@ public interface IGoapInjector
3333
### AgenTypeFactory and CapabilityFactory can now be injected
3434
You can now inject into `AgentTypeFactoryBase` and `CapabilityFactoryBase` classes, similar to other actions, goals and sensors.
3535

36+
### You can now manually call AgentBehaviour.Run() with custom deltaTimes
37+
This allows you to determine the rate at which agents are updated, for example agents further away from the player.
38+
39+
Make sure to set `AgentBehaviour.RunInUnityUpdate` to false before calling `Run` yourself!
40+
41+
```csharp
42+
agentBehaviour.RunInUnityUpdate = false;
43+
agentBehaviour.Run(1f);
44+
45+
// In actions
46+
public override IActionRunState Perform(IMonoAgent agent, Data data, IActionContext context)
47+
{
48+
// Make sure to use the deltaTime provided in the context!
49+
var deltaTime = context.DeltaTime;
50+
}
51+
```

Package/Documentation/upgrading.meta

Lines changed: 0 additions & 8 deletions
This file was deleted.

Package/Documentation/upgrading/README.md

Lines changed: 0 additions & 2 deletions
This file was deleted.

Package/Documentation/upgrading/README.md.meta

Lines changed: 0 additions & 7 deletions
This file was deleted.

Package/Editor/CrashKonijn.Goap.Editor/TypeDrawers/AgentEditor.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ public override VisualElement CreateInspectorGUI()
1616
root.styleSheets.Add(AssetDatabase.LoadAssetAtPath<StyleSheet>($"{GoapEditorSettings.BasePath}/Styles/Generic.uss"));
1717

1818
root.Add(new PropertyField(this.serializedObject.FindProperty("<ActionProviderBase>k__BackingField")));
19+
root.Add(new PropertyField(this.serializedObject.FindProperty("<RunInUnityUpdate>k__BackingField")));
1920
root.Add(new PropertyField(this.serializedObject.FindProperty("isPaused")));
2021
root.Add(new PropertyField(this.serializedObject.FindProperty("<DistanceMultiplier>k__BackingField")));
2122
root.Add(new PropertyField(this.serializedObject.FindProperty("<LoggerConfig>k__BackingField")));

Package/Runtime/CrashKonijn.Agent.Core/Interfaces/IAgent.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace CrashKonijn.Agent.Core
44
{
55
public interface IAgent : IActionReceiver
66
{
7-
public bool IsPaused { get; set; }
7+
bool RunInUnityUpdate { get; set; }
88
AgentState State { get; }
99
AgentMoveState MoveState { get; }
1010

@@ -22,6 +22,7 @@ public interface IAgent : IActionReceiver
2222

2323
void Initialize();
2424
void Run();
25+
void Run(float deltaTime);
2526

2627
void CompleteAction(bool resolveAction = true);
2728
void ResolveAction();

Package/Runtime/CrashKonijn.Agent.Runtime/ActionRunner.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ public ActionRunner(IMonoAgent agent, IAgentProxy proxy)
1616
this.proxy = proxy;
1717
}
1818

19-
public void Run()
19+
public void Run(float deltaTime)
2020
{
2121
if (!this.RunIsValid())
2222
return;
2323

2424
switch (this.agent.ActionState.Action.GetMoveMode(this.agent))
2525
{
2626
case ActionMoveMode.MoveBeforePerforming:
27-
this.RunMoveBeforePerforming();
27+
this.RunMoveBeforePerforming(deltaTime);
2828
break;
2929
case ActionMoveMode.PerformWhileMoving:
30-
this.RunPerformWhileMoving();
30+
this.RunPerformWhileMoving(deltaTime);
3131
break;
3232
}
3333
}
@@ -52,29 +52,29 @@ private bool RunIsValid()
5252
return true;
5353
}
5454

55-
private void RunPerformWhileMoving()
55+
private void RunPerformWhileMoving(float deltaTime)
5656
{
5757
if (this.proxy.IsInRange())
5858
{
5959
this.proxy.SetState(AgentState.PerformingAction);
6060
this.proxy.SetMoveState(AgentMoveState.InRange);
61-
this.PerformAction();
61+
this.PerformAction(deltaTime);
6262
return;
6363
}
6464

6565
this.proxy.SetState(AgentState.MovingWhilePerformingAction);
6666
this.proxy.SetMoveState(AgentMoveState.NotInRange);
6767
this.Move();
68-
this.PerformAction();
68+
this.PerformAction(deltaTime);
6969
}
7070

71-
private void RunMoveBeforePerforming()
71+
private void RunMoveBeforePerforming(float deltaTime)
7272
{
7373
if (this.proxy.IsInRange() || this.agent.State == AgentState.PerformingAction)
7474
{
7575
this.proxy.SetState(AgentState.PerformingAction);
7676
this.proxy.SetMoveState(AgentMoveState.InRange);
77-
this.PerformAction();
77+
this.PerformAction(deltaTime);
7878
return;
7979
}
8080

@@ -91,12 +91,12 @@ private void Move()
9191
this.agent.Events.Move(this.agent.CurrentTarget);
9292
}
9393

94-
private void PerformAction()
94+
private void PerformAction(float deltaTime)
9595
{
9696
if (!this.ShouldContinue())
9797
return;
9898

99-
this.context.DeltaTime = Time.deltaTime;
99+
this.context.DeltaTime = deltaTime;
100100
this.context.IsInRange = this.proxy.IsInRange();
101101

102102
if (!this.agent.ActionState.HasPerformed)

Package/Runtime/CrashKonijn.Agent.Runtime/AgentBehaviour.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ public class AgentBehaviour : MonoBehaviour, IMonoAgent
99
[field: SerializeField]
1010
public ActionProviderBase ActionProviderBase { get; set; }
1111

12+
[field: SerializeField]
13+
public bool RunInUnityUpdate { get; set; } = true;
14+
1215
[SerializeField]
1316
private bool isPaused = false;
1417

@@ -121,13 +124,22 @@ public void Initialize()
121124

122125
private void Update()
123126
{
124-
this.Run();
127+
if (this.RunInUnityUpdate)
128+
this.Run();
125129
}
126-
130+
127131
/// <summary>
128-
/// Runs the current action. This is called in the Update method.
132+
/// Runs the current action.
129133
/// </summary>
130134
public void Run()
135+
{
136+
this.Run(Time.deltaTime);
137+
}
138+
139+
/// <summary>
140+
/// Runs the current action with the given deltaTime
141+
/// </summary>
142+
public void Run(float deltaTime)
131143
{
132144
if (this.IsPaused)
133145
return;
@@ -137,7 +149,7 @@ public void Run()
137149

138150
this.UpdateTarget();
139151

140-
this.actionRunner.Run();
152+
this.actionRunner.Run(deltaTime);
141153
}
142154

143155
private void UpdateTarget()

Package/Tests/CrashKonijn.Goap.Tests/UnitTests/ActionRunnerTests.cs

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ public void Run_WhenRunIsNotValid_ShouldStopAction()
4747
this.action.IsValid(this.agent, this.agent.ActionState.Data).Returns(false);
4848

4949
// Act
50-
this.actionRunner.Run();
50+
this.actionRunner.Run(0f);
5151

5252
// Assert
5353
this.agent.Received().StopAction();
@@ -61,7 +61,7 @@ public void MoveBeforePerforming_WhenInRange_ShouldSetStateToPerformingAction()
6161
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
6262

6363
// Act
64-
this.actionRunner.Run();
64+
this.actionRunner.Run(0f);
6565

6666
// Assert
6767
this.proxy.Received().SetState(AgentState.PerformingAction);
@@ -75,7 +75,7 @@ public void MoveBeforePerforming_WhenInRange_ShouldSetMoveStateToInRange()
7575
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
7676

7777
// Act
78-
this.actionRunner.Run();
78+
this.actionRunner.Run(0f);
7979

8080
// Assert
8181
this.proxy.Received().SetMoveState(AgentMoveState.InRange);
@@ -89,7 +89,7 @@ public void MoveBeforePerforming_WhenInRange_ShouldPerformAction()
8989
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
9090

9191
// Act
92-
this.actionRunner.Run();
92+
this.actionRunner.Run(0f);
9393

9494
// Assert
9595
this.action.Received().Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>());
@@ -103,7 +103,7 @@ public void MoveBeforePerforming_WhenNotInRange_ShouldSetStateToMovingToTarget()
103103
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
104104

105105
// Act
106-
this.actionRunner.Run();
106+
this.actionRunner.Run(0f);
107107

108108
// Assert
109109
this.proxy.Received().SetState(AgentState.MovingToTarget);
@@ -117,7 +117,7 @@ public void MoveBeforePerforming_WhenNotInRange_ShouldSetMoveStateToOutOfRange()
117117
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
118118

119119
// Act
120-
this.actionRunner.Run();
120+
this.actionRunner.Run(0f);
121121

122122
// Assert
123123
this.proxy.Received().SetMoveState(AgentMoveState.NotInRange);
@@ -131,7 +131,7 @@ public void MoveBeforePerforming_WhenNotInRange_ShouldMove()
131131
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
132132

133133
// Act
134-
this.actionRunner.Run();
134+
this.actionRunner.Run(0f);
135135

136136
// Assert
137137
this.agent.Events.Received().Move(this.agent.CurrentTarget);
@@ -146,7 +146,7 @@ public void MoveBeforePerforming_WhenNotInRangeAndStateIsPerformingAction_Should
146146
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.MoveBeforePerforming);
147147

148148
// Act
149-
this.actionRunner.Run();
149+
this.actionRunner.Run(0f);
150150

151151
// Assert
152152
this.proxy.DidNotReceive().SetState(AgentState.MovingToTarget);
@@ -160,7 +160,7 @@ public void PerformWhileMoving_WhenInRange_ShouldSetStateToPerformingAction()
160160
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
161161

162162
// Act
163-
this.actionRunner.Run();
163+
this.actionRunner.Run(0f);
164164

165165
// Assert
166166
this.proxy.Received().SetState(AgentState.PerformingAction);
@@ -174,7 +174,7 @@ public void PerformWhileMoving_WhenInRange_ShouldSetMoveStateToInRange()
174174
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
175175

176176
// Act
177-
this.actionRunner.Run();
177+
this.actionRunner.Run(0f);
178178

179179
// Assert
180180
this.proxy.Received().SetMoveState(AgentMoveState.InRange);
@@ -188,7 +188,7 @@ public void PerformWhileMoving_WhenInRange_ShouldPerformAction()
188188
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
189189

190190
// Act
191-
this.actionRunner.Run();
191+
this.actionRunner.Run(0f);
192192

193193
// Assert
194194
this.action.Received().Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>());
@@ -202,7 +202,7 @@ public void PerformWhileMoving_WhenNotInRange_ShouldSetStateToMovingWhilePerform
202202
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
203203

204204
// Act
205-
this.actionRunner.Run();
205+
this.actionRunner.Run(0f);
206206

207207
// Assert
208208
this.proxy.Received().SetState(AgentState.MovingWhilePerformingAction);
@@ -216,7 +216,7 @@ public void PerformWhileMoving_WhenNotInRange_ShouldSetMoveStateToOutOfRange()
216216
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
217217

218218
// Act
219-
this.actionRunner.Run();
219+
this.actionRunner.Run(0f);
220220

221221
// Assert
222222
this.proxy.Received().SetMoveState(AgentMoveState.NotInRange);
@@ -230,7 +230,7 @@ public void PerformWhileMoving_WhenNotInRange_ShouldMove()
230230
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
231231

232232
// Act
233-
this.actionRunner.Run();
233+
this.actionRunner.Run(0f);
234234

235235
// Assert
236236
this.agent.Events.Received().Move(this.agent.CurrentTarget);
@@ -244,7 +244,7 @@ public void PerformAction_NoRunState_ShouldPerformAction()
244244
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
245245

246246
// Act
247-
this.actionRunner.Run();
247+
this.actionRunner.Run(0f);
248248

249249
// Assert
250250
this.action.Received().Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>());
@@ -259,7 +259,7 @@ public void PerformAction_IsCompletedRunState_ShouldNotPerformAction()
259259
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
260260

261261
// Act
262-
this.actionRunner.Run();
262+
this.actionRunner.Run(0f);
263263

264264
// Assert
265265
this.action.DidNotReceive().Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>());
@@ -275,7 +275,7 @@ public void PerformAction_ShouldStopRunState_ShouldNotPerformAction()
275275
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
276276

277277
// Act
278-
this.actionRunner.Run();
278+
this.actionRunner.Run(0f);
279279

280280
// Assert
281281
this.action.DidNotReceive().Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>());
@@ -291,7 +291,7 @@ public void PerformAction_ContinueRunState_ShouldPerformAction()
291291
this.action.GetMoveMode(this.agent).Returns(ActionMoveMode.PerformWhileMoving);
292292

293293
// Act
294-
this.actionRunner.Run();
294+
this.actionRunner.Run(0f);
295295

296296
// Assert
297297
this.action.Received().Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>());
@@ -307,7 +307,7 @@ public void PerformAction_ReturnedCompleteState_ShouldCompleteAction()
307307
this.action.Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>()).Returns(ActionRunState.Completed);
308308

309309
// Act
310-
this.actionRunner.Run();
310+
this.actionRunner.Run(0f);
311311

312312
// Assert
313313
this.agent.Received().CompleteAction();
@@ -323,7 +323,7 @@ public void PerformAction_ReturnedStopState_ShouldStopAction()
323323
this.action.Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>()).Returns(ActionRunState.Stop);
324324

325325
// Act
326-
this.actionRunner.Run();
326+
this.actionRunner.Run(0f);
327327

328328
// Assert
329329
this.agent.Received().StopAction();
@@ -342,7 +342,7 @@ public void PerformAction_ReturnedContinueState_ShouldContinueAction()
342342
this.action.Perform(this.agent, this.agent.ActionState.Data, Arg.Any<IActionContext>()).Returns(ActionRunState.Continue);
343343

344344
// Act
345-
this.actionRunner.Run();
345+
this.actionRunner.Run(0f);
346346

347347
// Assert
348348
this.agent.DidNotReceive().CompleteAction();

0 commit comments

Comments
 (0)