Skip to content

Commit

Permalink
refactor: opt code
Browse files Browse the repository at this point in the history
  • Loading branch information
luzhuang committed Sep 13, 2024
1 parent 2f6708c commit 7183a07
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 66 deletions.
68 changes: 25 additions & 43 deletions packages/core/src/animation/Animator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,17 +109,20 @@ export class Animator extends Component {
* @param normalizedTimeOffset - The normalized time offset (between 0 and 1, default 0) to start the state's animation from
*/
play(stateName: string, layerIndex: number = -1, normalizedTimeOffset: number = 0): void {
this._play(stateName, layerIndex, normalizedTimeOffset, false);
}
if (this._controllerUpdateFlag?.flag) {
this._reset();
}

/**
* Play a state by name with a fixed time offset.
* @param stateName - The state name
* @param layerIndex - The layer index(default -1). If layer is -1, play the first state with the given state name
* @param fixedTimeOffset - The time offset in seconds from the start of the animation
*/
playInFixedTime(stateName: string, layerIndex: number = -1, fixedTimeOffset: number = 0): void {
this._play(stateName, layerIndex, fixedTimeOffset, true);
const stateInfo = this._getAnimatorStateInfo(stateName, layerIndex);
const { state } = stateInfo;

if (!state) {
return;
}

if (this._preparePlay(state, stateInfo.layerIndex, normalizedTimeOffset)) {
this._playFrameCount = this.engine.time.frameCount;
}
}

/**
Expand All @@ -143,15 +146,15 @@ export class Animator extends Component {
* @param stateName - The state name
* @param fixedDuration - The duration of the transition in seconds
* @param layerIndex - The layer index(default -1). If layer is -1, play the first state with the given state name
* @param fixedTimeOffset - The time offset in seconds from the start of the animation
* @param normalizedTimeOffset - The normalized time offset (between 0 and 1, default 0) to start the destination state's animation from
*/
crossFadeInFixedTime(
crossFadeInFixedDuration(
stateName: string,
fixedDuration: number,
layerIndex: number = -1,
fixedTimeOffset: number = 0
normalizedTimeOffset: number = 0
): void {
this._crossFade(stateName, fixedDuration, layerIndex, fixedTimeOffset, true);
this._crossFade(stateName, fixedDuration, layerIndex, normalizedTimeOffset, true);
}

/**
Expand Down Expand Up @@ -322,33 +325,12 @@ export class Animator extends Component {
}
}

private _play(stateName: string, layerIndex: number, timeOffset: number, isFixedTime: boolean): void {
if (this._controllerUpdateFlag?.flag) {
this._reset();
}

const stateInfo = this._getAnimatorStateInfo(stateName, layerIndex);
const { state } = stateInfo;

if (!state) {
return;
}

if (!isFixedTime) {
timeOffset = timeOffset * state._getDuration();
}

if (this._preparePlay(state, stateInfo.layerIndex, timeOffset)) {
this._playFrameCount = this.engine.time.frameCount;
}
}

private _crossFade(
stateName: string,
duration: number,
layerIndex: number,
timeOffset: number,
isFixedTime: boolean
normalizedTimeOffset: number,
isFixedDuration: boolean
): void {
if (this._controllerUpdateFlag?.flag) {
this._reset();
Expand All @@ -358,9 +340,8 @@ export class Animator extends Component {
const { manuallyTransition } = this._getAnimatorLayerData(playLayerIndex);
manuallyTransition.duration = duration;

const stateDuration = state._getDuration();
manuallyTransition.offset = isFixedTime ? (stateDuration === 0 ? 0 : timeOffset / stateDuration) : timeOffset;
manuallyTransition.isFixedDuration = isFixedTime;
manuallyTransition.offset = normalizedTimeOffset;
manuallyTransition.isFixedDuration = isFixedDuration;
manuallyTransition.destinationState = state;

if (this._prepareCrossFadeByTransition(manuallyTransition, playLayerIndex)) {
Expand Down Expand Up @@ -1295,7 +1276,7 @@ export class Animator extends Component {
}
}

private _preparePlay(state: AnimatorState, layerIndex: number, timeOffset: number = 0): boolean {
private _preparePlay(state: AnimatorState, layerIndex: number, normalizedTimeOffset: number = 0): boolean {
const name = state.name;
if (!state.clip) {
Logger.warn(`The state named ${name} has no AnimationClip data.`);
Expand All @@ -1308,7 +1289,7 @@ export class Animator extends Component {
this._preparePlayOwner(animatorLayerData, state);

animatorLayerData.layerState = LayerState.Playing;
animatorLayerData.srcPlayData.reset(state, animatorStateData, timeOffset);
animatorLayerData.srcPlayData.reset(state, animatorStateData, state._getDuration() * normalizedTimeOffset);

return true;
}
Expand Down Expand Up @@ -1413,7 +1394,8 @@ export class Animator extends Component {

const animatorLayerData = this._getAnimatorLayerData(layerIndex);
const animatorStateData = this._getAnimatorStateData(crossState.name, crossState, animatorLayerData, layerIndex);
animatorLayerData.destPlayData.reset(crossState, animatorStateData, transition._getFixedTimeOffset());

animatorLayerData.destPlayData.reset(crossState, animatorStateData, transition.offset * crossState._getDuration());

switch (animatorLayerData.layerState) {
case LayerState.Standby:
Expand Down
9 changes: 1 addition & 8 deletions packages/core/src/animation/AnimatorStateTransition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { AnimatorConditionMode } from "./enums/AnimatorConditionMode";
* Transitions define when and how the state machine switch from on state to another. AnimatorTransition always originate from a StateMachine or a StateMachine entry.
*/
export class AnimatorStateTransition {
/** The duration of the transition. This is represented in normalized time. */
/** The duration of the transition. The duration is in normalized time by default. To set it to be in seconds, set isFixedDuration to true. */
duration = 0;
/** The time at which the destination state will start. This is represented in normalized time. */
offset = 0;
Expand Down Expand Up @@ -120,11 +120,4 @@ export class AnimatorStateTransition {
_getFixedDuration(): number {
return this.isFixedDuration ? this.duration : this.duration * this.destinationState._getDuration();
}

/**
* @internal
*/
_getFixedTimeOffset(): number {
return this.offset * this.destinationState._getDuration();
}
}
18 changes: 3 additions & 15 deletions tests/src/core/Animator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,23 +211,10 @@ describe("Animator test", function () {
expect(layerState).to.eq(2);
});

it("play in fixed time", () => {
animator.playInFixedTime("Walk", 0, 0.3);
// @ts-ignore
animator.engine.time._frameCount++;
// @ts-ignore
animator.update(0.3);

// @ts-ignore
const layerData = animator._getAnimatorLayerData(0);
const srcPlayData = layerData.srcPlayData;
expect(srcPlayData.frameTime).to.eq(0.6);
});

it("cross fade in fixed time", () => {
const runState = animator.findAnimatorState("Run");
animator.play("Walk");
animator.crossFadeInFixedTime("Run", 0.3, 0, 0.1);
animator.crossFadeInFixedDuration("Run", 0.3, 0, 0.1);
// @ts-ignore
animator.engine.time._frameCount++;
// @ts-ignore
Expand All @@ -237,7 +224,8 @@ describe("Animator test", function () {
const layerData = animator._getAnimatorLayerData(0);
const srcPlayData = layerData.srcPlayData;
expect(srcPlayData.state.name).to.eq("Run");
expect(srcPlayData.frameTime).to.eq(0.4);
// @ts-ignore
expect(srcPlayData.frameTime).to.eq(0.3 + 0.1 * runState._getDuration());
});

it("animation cross fade by transition", () => {
Expand Down

0 comments on commit 7183a07

Please sign in to comment.