Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support trigger type AnimatorControllerParameter #2374

Merged
merged 25 commits into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 83 additions & 32 deletions packages/core/src/animation/Animator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import { AnimationCurveOwner } from "./internal/animationCurveOwner/AnimationCur
* The controller of the animation system.
*/
export class Animator extends Component {
private static _tempTriggeredParametersName: string[] = [];
GuoLei1990 marked this conversation as resolved.
Show resolved Hide resolved

/** Culling mode of this Animator. */
cullingMode: AnimatorCullingMode = AnimatorCullingMode.None;
/** The playback speed of the Animator, 1.0 is normal playback speed. */
Expand Down Expand Up @@ -244,13 +246,37 @@ export class Animator extends Component {
* @param name - The name of the parameter
* @param value - The value of the parameter
*/
setParameterValue(name: string, value: AnimatorControllerParameterValue) {
setParameterValue(name: string, value: AnimatorControllerParameterValue): void {
const parameter = this._animatorController?._parametersMap[name];
if (parameter) {
this._parametersValueMap[name] = value;
}
}

/**
* Activate the trigger parameter by name.
* @param name - The name of the trigger parameter
*/
activateTriggerParameter(name: string): void {
const parameter = this._animatorController?._parametersMap[name];

if (parameter?._isTrigger) {
this._parametersValueMap[name] = true;
}
}

/**
* Reset the trigger parameter to deactivate it by name.
* @param name - The name of the trigger parameter
*/
deactivateTriggerParameter(name: string): void {
const parameter = this._animatorController?._parametersMap[name];

if (parameter?._isTrigger) {
this._parametersValueMap[name] = false;
}
}

/**
* @internal
*/
Expand Down Expand Up @@ -1271,43 +1297,61 @@ export class Animator extends Component {
return false;
}

switch (mode) {
case AnimatorConditionMode.Equals:
if (parameterValue === threshold) {
pass = true;
}
break;
case AnimatorConditionMode.Greater:
if (parameterValue > threshold) {
pass = true;
}
break;
case AnimatorConditionMode.Less:
if (parameterValue < threshold) {
pass = true;
}
break;
case AnimatorConditionMode.NotEquals:
if (parameterValue !== threshold) {
pass = true;
}
break;
case AnimatorConditionMode.If:
if (parameterValue === true) {
pass = true;
}
break;
case AnimatorConditionMode.IfNot:
if (parameterValue === false) {
pass = true;
}
break;
if (parameterValue === true) {
const parameter = this.getParameter(name);
if (parameter?._isTrigger) {
Animator._tempTriggeredParametersName.push(name);
pass = true;
}
}

if (!pass) {
switch (mode) {
case AnimatorConditionMode.Equals:
if (parameterValue === threshold) {
pass = true;
}
break;
case AnimatorConditionMode.Greater:
if (parameterValue > threshold) {
pass = true;
}
break;
case AnimatorConditionMode.Less:
if (parameterValue < threshold) {
pass = true;
}
break;
case AnimatorConditionMode.NotEquals:
if (parameterValue !== threshold) {
pass = true;
}
break;
case AnimatorConditionMode.If:
if (parameterValue === true) {
pass = true;
}
break;
case AnimatorConditionMode.IfNot:
if (parameterValue === false) {
pass = true;
}
break;
}
}

if (!pass) {
allPass = false;
break;
}
}

if (allPass) {
this._deactivateTriggeredParameters();
}

Animator._tempTriggeredParametersName.length = 0;

return allPass;
}

Expand Down Expand Up @@ -1515,6 +1559,13 @@ export class Animator extends Component {
this._callAnimatorScriptOnUpdate(state, layerIndex);
}
}

private _deactivateTriggeredParameters(): void {
const tempTriggeredParametersName = Animator._tempTriggeredParametersName;
for (let i = 0, n = tempTriggeredParametersName.length; i < n; i++) {
this._parametersValueMap[tempTriggeredParametersName[i]] = false;
}
}
GuoLei1990 marked this conversation as resolved.
Show resolved Hide resolved
}

interface IAnimatorStateInfo {
Expand Down
55 changes: 41 additions & 14 deletions packages/core/src/animation/AnimatorController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,15 @@ export class AnimatorController extends ReferResource {
* @param defaultValue - The default value of the parameter
*/
addParameter(name: string, defaultValue?: AnimatorControllerParameterValue): AnimatorControllerParameter {
if (this._parametersMap[name]) {
console.warn(`Parameter ${name} already exists.`);
return null;
}
const param = new AnimatorControllerParameter();
param.name = name;
param.defaultValue = defaultValue;
param._onNameChanged = (oldName, newName) => {
delete this._parametersMap[oldName];
this._parametersMap[newName] = param as AnimatorControllerParameter;
};
this._parametersMap[name] = param;
this._parameters.push(param);
return param;
return this._addParameter(name, defaultValue, false);
}

/**
* Add a trigger parameter to the controller.
* @param name - The name of the parameter
*/
addTriggerParameter(name: string): AnimatorControllerParameter {
return this._addParameter(name, false, true);
}

/**
Expand All @@ -84,6 +79,16 @@ export class AnimatorController extends ReferResource {
}
}

/**
* Clear parameters.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opt comments

clearParameters(): void {
this._parameters.length = 0;
for (let name in this._parametersMap) {
delete this._parametersMap[name];
}
}

/**
* Get the parameter by name.
* @param name - The name of the parameter
Expand Down Expand Up @@ -138,4 +143,26 @@ export class AnimatorController extends ReferResource {
_registerChangeFlag(): BoolUpdateFlag {
return this._updateFlagManager.createFlag(BoolUpdateFlag);
}

private _addParameter(
name: string,
defaultValue: AnimatorControllerParameterValue,
isTrigger: boolean = false
): AnimatorControllerParameter {
if (this._parametersMap[name]) {
console.warn(`Parameter ${name} already exists.`);
return null;
}
const param = new AnimatorControllerParameter();
param.name = name;
param.defaultValue = defaultValue;
param._isTrigger = isTrigger;
param._onNameChanged = (oldName, newName) => {
delete this._parametersMap[oldName];
this._parametersMap[newName] = param as AnimatorControllerParameter;
};
this._parametersMap[name] = param;
this._parameters.push(param);
return param;
}
}
3 changes: 3 additions & 0 deletions packages/core/src/animation/AnimatorControllerParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export class AnimatorControllerParameter {
/** @internal */
_onNameChanged: (oldName: string, newName: string) => void = null;

/** @internal */
_isTrigger: boolean = false;

private _name: string;

/**
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/animation/AnimatorStateTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ export class AnimatorStateTransition {

/**
* Add a condition to a transition.
* @param mode - The AnimatorCondition mode of the condition
* @param parameterName - The name of the parameter
* @param mode - The AnimatorCondition mode of the condition
* @param threshold - The threshold value of the condition
*/
addCondition(
mode: AnimatorConditionMode,
parameterName: string,
mode: AnimatorConditionMode,
GuoLei1990 marked this conversation as resolved.
Show resolved Hide resolved
threshold?: AnimatorControllerParameterValue
): AnimatorCondition;

Expand All @@ -86,17 +86,17 @@ export class AnimatorStateTransition {
addCondition(animatorCondition: AnimatorCondition): AnimatorCondition;

addCondition(
param: AnimatorConditionMode | AnimatorCondition,
parameterName?: string,
param: string | AnimatorCondition,
mode?: AnimatorConditionMode,
threshold?: AnimatorControllerParameterValue
): AnimatorCondition {
if (typeof param === "object") {
this._conditions.push(param);
return param;
} else {
const condition = new AnimatorCondition();
condition.mode = param;
condition.parameterName = parameterName;
condition.parameterName = param;
condition.mode = mode ?? AnimatorConditionMode.If;
condition.threshold = threshold;
this._conditions.push(condition);
return condition;
Expand Down
8 changes: 6 additions & 2 deletions packages/loader/src/AnimatorControllerLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,11 @@ class AnimatorControllerLoader extends Loader<AnimatorController> {
animatorController.addLayer(layer);
});
parameters.forEach((parameterData) => {
animatorController.addParameter(parameterData.name, parameterData.defaultValue);
if (parameterData.isTrigger) {
animatorController.addTriggerParameter(parameterData.name);
} else {
animatorController.addParameter(parameterData.name, parameterData.defaultValue);
}
});
Promise.all(promises).then((clipData) => {
clipData.forEach((data) => {
Expand All @@ -125,7 +129,7 @@ class AnimatorControllerLoader extends Loader<AnimatorController> {
transition._isExit = transitionData.isExit;
transition.destinationState = destinationState;
transitionData.conditions.forEach((conditionData) => {
transition.addCondition(conditionData.mode, conditionData.parameterName, conditionData.threshold);
transition.addCondition(conditionData.parameterName, conditionData.mode, conditionData.threshold);
});
return transition;
}
Expand Down
Loading
Loading