This was an interesting problem. A user wanted to be able to switch between states on the graph and use the arrow keys to scrub through that animation in the state which meant that speed would be 0 so that it wouldn’t animate.
Project: PlayCanvas | HTML5 Game Engine
Use the keys: 1, 2, 3 to switch states between idle, jump and run and the arrow keys left/right to scrub through the animation.
(be aware of this bug though Anim transition of state to itself via ANY state does not activate · Issue #3313 · playcanvas/engine · GitHub )
The issue was that if speed was 0 during the anim component update, it wouldn’t perform any transitions as there is no timeframe in the animation to check if any transitions are valid.
So even if the trigger was set to transition to another state, it wouldn’t activate.
This is as designed.
The workaround would to be set the trigger and the speed to be > 0 in the update frame of the script.
The anim component update would happen in the same frame but after the script update and as speed > 0, it would perform the transition.
In the script postUpdate which is called after the anim component update, we set the speed back to 0. The animation controller has now at this point follow transitioned to the next state (as long as transition duration is 0) and we can scrub through the animation.
1 Like
Also worth noting that the next engine release will have a new API that allows you to transition between states via code without needing to have valid transitions which will help a lot in certain scenerios.
playcanvas:master
← playcanvas:anim-component-api-update
opened 03:59PM - 15 Jun 21 UTC
This PR updates the anim component API to make it more user friendly for engine … only users. It replicates the functionality of the animation component which we can now be deprecated.
### Updated functions
```javascript
/**
* @function
* @name AnimComponent#assignAnimation
* @description Associates an animation with a state in the loaded state graph. If all states are linked and the {@link AnimComponent#activate} value was set to true then the component will begin playing.
* If no state graph is loaded, a default state graph will be created with a single state based on the provided nodeName parameter.
* @param {string} nodeName - The name of the state node that this animation should be associated with.
* @param {object} animTrack - The animation track that will be assigned to this state and played whenever this state is active.
* @param {string} [layerName] - The name of the anim component layer to update. If omitted the default layer is used. If no state graph has been previously loaded this parameter is ignored.
* @param {number} [speed] - Update the speed of the state you are assigning an animation to.
* @param {boolean} [loop] - Update the loop property of the state you are assigning an animation to.
*/
pc.AnimComponent#assignAnimation(nodeName, animTrack, layerName, speed, loop);
/**
* @function
* @name AnimComponentLayer#assignAnimation
* @description Assigns an animation track to a state in the current graph. If a state for the given nodeName doesn't exist, it will be created. If all states nodes are linked and the {@link AnimComponent#activate} value was set to true then the component will begin playing.
* @param {string} nodeName - The name of the node that this animation should be associated with.
* @param {object} animTrack - The animation track that will be assigned to this state and played whenever this state is active.
* @param {number} [speed] - Update the speed of the state you are assigning an animation to.
* @param {boolean} [loop] - Update the loop property of the state you are assigning an animation to.
*/
pc.AnimComponentLayer#assignAnimation(nodeName, animTrack, speed, loop);
```
### New functions
```javascript
/**
* @name AnimComponent#addLayer
* @returns {AnimComponentLayer} - The created anim component layer
* @description Adds a new anim component layer to the anim component.
* @param {string} layerName - The name of the layer to create.
*/
addLayer(layerName);
/**
* @function
* @name AnimComponentLayer#transition
* @description Transition to any state in the current layers graph. Transitions can be instant or take an optional blend time.
* @param {string} to - The state that this transition will transition to.
* @param {number} [time=0] - The duration of the transition in seconds.
* @param {number} [transitionOffset=null] - If provided, the destination state will begin playing its animation at this time. Given in normalised time, based on the states duration & must be between 0 and 1.
*/
pc.AnimComponentLayer#transition(to, time = 0, transitionOffset = null);
```
### Usage
```javascript
this.entity.addComponent('anim', { activate: true });
this.entity.anim.assignAnimation('Idle', idleTrack);
this.entity.anim.assignAnimation('Wave', waveTrack);
setTimeout(() => {
this.entity.anim.baseLayer.transition('Wave');
}, 2000);
setTimeout(() => {
this.entity.anim.baseLayer.transition('Idle');
}, 5000);
```
### Other updates
- Fixes an issue when destroying an entity with an anim component causes the app to crash https://github.com/playcanvas/engine/issues/3232
- Fixes issues with cloning entities with anim components
- Refactors the anim component to the new style of component that doesn't rely on the data class
- Includes an engine example for animation events which makes use of the new assignAnimation API:
https://user-images.githubusercontent.com/1721533/122932333-8e732300-d365-11eb-8263-54eb3c8c8760.mov
I confirm I have read the [contributing guidelines](https://github.com/playcanvas/engine/blob/master/.github/CONTRIBUTING.md) and signed the [Contributor License Agreement](https://docs.google.com/a/playcanvas.com/forms/d/1Ih69zQfJG-QDLIEpHr6CsaAs6fPORNOVnMv5nuo0cjk/viewform).
1 Like