Skip to content

Commit cfd9334

Browse files
authored
AnimComponent transition updates (playcanvas#3329)
* update how transition trigger conditions are consumed and enable transitioning to the active state * support single frame triggers
1 parent 4c13f4b commit cfd9334

File tree

3 files changed

+28
-15
lines changed

3 files changed

+28
-15
lines changed

src/anim/controller/anim-controller.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,16 @@ import {
2020
* @param {object[]} transitions - The list of transitions used to form the controller state graph.
2121
* @param {object[]} parameters - The anim components parameters.
2222
* @param {boolean} activate - Determines whether the anim controller should automatically play once all {@link AnimNodes} are assigned animations.
23+
* @param {EventHandler} eventHandler - The event handler which should be notified with anim events
24+
* @param {Set} consumedTriggers - Used to set triggers back to their default state after they have been consumed by a transition
2325
*/
2426
class AnimController {
25-
constructor(animEvaluator, states, transitions, parameters, activate, eventHandler) {
27+
constructor(animEvaluator, states, transitions, parameters, activate, eventHandler, consumedTriggers) {
2628
this._animEvaluator = animEvaluator;
2729
this._states = {};
2830
this._stateNames = [];
2931
this._eventHandler = eventHandler;
32+
this._consumedTriggers = consumedTriggers;
3033
for (let i = 0; i < states.length; i++) {
3134
this._states[states[i].name] = new AnimState(
3235
this,
@@ -279,10 +282,6 @@ class AnimController {
279282

280283
// filter out transitions that don't have their conditions met
281284
transitions = transitions.filter(function (transition) {
282-
// if the transition is moving to the already active state, ignore it
283-
if (transition.to === this.activeStateName) {
284-
return false;
285-
}
286285
// when an exit time is present, we should only exit if it falls within the current frame delta time
287286
if (transition.hasExitTime) {
288287
let progressBefore = this._getActiveStateProgressForTime(this._timeInStateBefore);
@@ -325,7 +324,7 @@ class AnimController {
325324
const condition = transition.conditions[i];
326325
const parameter = this.findParameter(condition.parameterName);
327326
if (parameter.type === ANIM_PARAMETER_TRIGGER) {
328-
parameter.value = false;
327+
this._consumedTriggers.add(condition.parameterName);
329328
}
330329
}
331330

src/framework/components/anim/component.js

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class AnimComponent extends Component {
4040
this._layers = [];
4141
this._layerIndices = {};
4242
this._parameters = {};
43+
this._consumedTriggers = new Set();
4344
}
4445

4546
get stateGraphAsset() {
@@ -228,7 +229,8 @@ class AnimComponent extends Component {
228229
transitions,
229230
this._parameters,
230231
this._activate,
231-
this
232+
this,
233+
this._consumedTriggers
232234
);
233235
this._layers.push(new AnimComponentLayer(name, controller, this));
234236
this._layerIndices[name] = order;
@@ -636,9 +638,13 @@ class AnimComponent extends Component {
636638
* @name AnimComponent#setTrigger
637639
* @description Sets the value of a trigger parameter that was defined in the animation components state graph to true.
638640
* @param {string} name - The name of the parameter to set.
641+
* @param {boolean} [singleFrame] - If true, this trigger will be set back to false at the end of the animation update. Defaults to false.
639642
*/
640-
setTrigger(name) {
643+
setTrigger(name, singleFrame = false) {
641644
this.setParameterValue(name, ANIM_PARAMETER_TRIGGER, true);
645+
if (singleFrame) {
646+
this._consumedTriggers.add(name);
647+
}
642648
}
643649

644650
/**
@@ -656,6 +662,16 @@ class AnimComponent extends Component {
656662
this.system.app.assets.get(this._stateGraphAsset).off('change', this._onStateGraphAssetChangeEvent);
657663
}
658664
}
665+
666+
update(dt) {
667+
for (let i = 0; i < this.layers.length; i++) {
668+
this.layers[i].update(dt * this.speed);
669+
}
670+
this._consumedTriggers.forEach((trigger) => {
671+
this.parameters[trigger].value = false;
672+
});
673+
this._consumedTriggers.clear();
674+
}
659675
}
660676

661677
export { AnimComponent };

src/framework/components/anim/system.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,15 @@ class AnimComponentSystem extends ComponentSystem {
5858
}
5959

6060
onAnimationUpdate(dt) {
61-
var components = this.store;
61+
const components = this.store;
6262

63-
for (var id in components) {
63+
for (const id in components) {
6464
if (components.hasOwnProperty(id)) {
65-
var component = components[id].entity.anim;
66-
var componentData = component.data;
65+
const component = components[id].entity.anim;
66+
const componentData = component.data;
6767

6868
if (componentData.enabled && component.entity.enabled && component.playing) {
69-
for (var i = 0; i < component.layers.length; i++) {
70-
component.layers[i].update(dt * component.speed);
71-
}
69+
component.update(dt);
7270
}
7371
}
7472
}

0 commit comments

Comments
 (0)