feat(anim): 3-������ ������ + ������������ �������� #31
@ -53,6 +53,7 @@ const BASE_STATES = ["idle", "walk", "run", "jump", "fall"];
|
|||||||
const EXTRA_STATES = [
|
const EXTRA_STATES = [
|
||||||
"jump_anticipate", "jump_air", "jump_land",
|
"jump_anticipate", "jump_air", "jump_land",
|
||||||
"jump_fwd_anticipate", "jump_fwd_air", "jump_fwd_land",
|
"jump_fwd_anticipate", "jump_fwd_air", "jump_fwd_land",
|
||||||
|
"jump_run_anticipate", "jump_run_air", "jump_run_land",
|
||||||
"walk_backward", "run_backward", "run_to_stop", "run_slide",
|
"walk_backward", "run_backward", "run_to_stop", "run_slide",
|
||||||
"jump_forward", "jump_backward", "jump_down",
|
"jump_forward", "jump_backward", "jump_down",
|
||||||
"crouch_enter", "crouch_idle", "crouch_walk", "crouch_to_stand",
|
"crouch_enter", "crouch_idle", "crouch_walk", "crouch_to_stand",
|
||||||
@ -278,6 +279,7 @@ export class MixamoAnimator {
|
|||||||
const PHASES = new Set([
|
const PHASES = new Set([
|
||||||
'jump_anticipate', 'jump_land',
|
'jump_anticipate', 'jump_land',
|
||||||
'jump_fwd_anticipate', 'jump_fwd_land',
|
'jump_fwd_anticipate', 'jump_fwd_land',
|
||||||
|
'jump_run_anticipate', 'jump_run_land',
|
||||||
]);
|
]);
|
||||||
if (!PHASES.has(state)) {
|
if (!PHASES.has(state)) {
|
||||||
continue;
|
continue;
|
||||||
@ -334,6 +336,7 @@ export class MixamoAnimator {
|
|||||||
"jump", "jump_forward", "jump_backward", "jump_down",
|
"jump", "jump_forward", "jump_backward", "jump_down",
|
||||||
"jump_anticipate", "jump_land",
|
"jump_anticipate", "jump_land",
|
||||||
"jump_fwd_anticipate", "jump_fwd_air", "jump_fwd_land",
|
"jump_fwd_anticipate", "jump_fwd_air", "jump_fwd_land",
|
||||||
|
"jump_run_anticipate", "jump_run_air", "jump_run_land",
|
||||||
"crouch_enter", "crouch_to_stand",
|
"crouch_enter", "crouch_to_stand",
|
||||||
"hit_react", "die_forward", "die_back",
|
"hit_react", "die_forward", "die_back",
|
||||||
"throw_action", "pickup", "push_button", "open_door",
|
"throw_action", "pickup", "push_button", "open_door",
|
||||||
@ -382,6 +385,7 @@ export class MixamoAnimator {
|
|||||||
const JUMP_STATES = new Set([
|
const JUMP_STATES = new Set([
|
||||||
'jump_air', 'jump_land', 'jump_in_place', 'jump_anticipate',
|
'jump_air', 'jump_land', 'jump_in_place', 'jump_anticipate',
|
||||||
'jump_fwd_anticipate', 'jump_fwd_air', 'jump_fwd_land',
|
'jump_fwd_anticipate', 'jump_fwd_air', 'jump_fwd_land',
|
||||||
|
'jump_run_anticipate', 'jump_run_air', 'jump_run_land',
|
||||||
]);
|
]);
|
||||||
if (JUMP_STATES.has(this._currentState) && !JUMP_STATES.has(state)
|
if (JUMP_STATES.has(this._currentState) && !JUMP_STATES.has(state)
|
||||||
&& this._restPositions) {
|
&& this._restPositions) {
|
||||||
@ -402,6 +406,7 @@ export class MixamoAnimator {
|
|||||||
const JUMP_VITAL = new Set([
|
const JUMP_VITAL = new Set([
|
||||||
'jump', 'fall', 'jump_air', 'jump_land', 'jump_anticipate',
|
'jump', 'fall', 'jump_air', 'jump_land', 'jump_anticipate',
|
||||||
'jump_fwd_anticipate', 'jump_fwd_air', 'jump_fwd_land',
|
'jump_fwd_anticipate', 'jump_fwd_air', 'jump_fwd_land',
|
||||||
|
'jump_run_anticipate', 'jump_run_air', 'jump_run_land',
|
||||||
]);
|
]);
|
||||||
const isVitalSwitch = JUMP_VITAL.has(state)
|
const isVitalSwitch = JUMP_VITAL.has(state)
|
||||||
|| JUMP_VITAL.has(this._currentState)
|
|| JUMP_VITAL.has(this._currentState)
|
||||||
@ -448,8 +453,11 @@ export class MixamoAnimator {
|
|||||||
// Per-state speedRatio: подгоняем длительность под физику.
|
// Per-state speedRatio: подгоняем длительность под физику.
|
||||||
// jump_fwd_air: Mixamo Jump полёт = 0.43с, физика = 0.73с
|
// jump_fwd_air: Mixamo Jump полёт = 0.43с, физика = 0.73с
|
||||||
// → speedRatio = 0.59 (замедлить чтобы клип не зациклился).
|
// → speedRatio = 0.59 (замедлить чтобы клип не зациклился).
|
||||||
|
// jump_fwd_air: Mixamo Jump полёт 0.43с, физика 0.73с → 0.59
|
||||||
|
// jump_run_air: Mixamo Running Jump полёт 0.52с, физика 0.73с → 0.71
|
||||||
const SPEED_RATIO = {
|
const SPEED_RATIO = {
|
||||||
jump_fwd_air: 0.59,
|
jump_fwd_air: 0.59,
|
||||||
|
jump_run_air: 0.71,
|
||||||
};
|
};
|
||||||
const speedRatio = SPEED_RATIO[state] || 1.0;
|
const speedRatio = SPEED_RATIO[state] || 1.0;
|
||||||
// Запустить новую анимацию. Babylon 7 ВНИМАНИЕ: параметр loop
|
// Запустить новую анимацию. Babylon 7 ВНИМАНИЕ: параметр loop
|
||||||
|
|||||||
@ -3101,9 +3101,16 @@ export class PlayerController {
|
|||||||
|| cc.has('KeyA') || cc.has('KeyD')
|
|| cc.has('KeyA') || cc.has('KeyD')
|
||||||
|| cc.has('ArrowUp') || cc.has('ArrowDown')
|
|| cc.has('ArrowUp') || cc.has('ArrowDown')
|
||||||
|| cc.has('ArrowLeft') || cc.has('ArrowRight'));
|
|| cc.has('ArrowLeft') || cc.has('ArrowRight'));
|
||||||
this._jumpKind = wasdHeld ? 'forward' : 'in_place';
|
// in_place — нет WASD
|
||||||
|
// forward — WASD без Shift (Mixamo Jump)
|
||||||
|
// run — WASD + Shift (Mixamo Running Jump)
|
||||||
|
const sprinting = this._shift && !this._crouching;
|
||||||
|
if (!wasdHeld) this._jumpKind = 'in_place';
|
||||||
|
else if (sprinting) this._jumpKind = 'run';
|
||||||
|
else this._jumpKind = 'forward';
|
||||||
// anticipate-фаза разной длительности.
|
// anticipate-фаза разной длительности.
|
||||||
const antDuration = this._jumpKind === 'forward' ? 170 : 375;
|
const antDuration = this._jumpKind === 'in_place' ? 375
|
||||||
|
: this._jumpKind === 'run' ? 125 : 170;
|
||||||
this._jumpHeld = true;
|
this._jumpHeld = true;
|
||||||
this._coyoteLeft = 0;
|
this._coyoteLeft = 0;
|
||||||
this._jumpAnticipateUntil = Date.now() + antDuration;
|
this._jumpAnticipateUntil = Date.now() + antDuration;
|
||||||
@ -3351,13 +3358,28 @@ export class PlayerController {
|
|||||||
const inCrouchTransition = this._crouchTransitionUntil
|
const inCrouchTransition = this._crouchTransitionUntil
|
||||||
&& now < this._crouchTransitionUntil;
|
&& now < this._crouchTransitionUntil;
|
||||||
// 3-фазная анимация прыжка. Выбираем семейство фаз по _jumpKind:
|
// 3-фазная анимация прыжка. Выбираем семейство фаз по _jumpKind:
|
||||||
// in_place: jump_anticipate/jump_air/jump_land (Mixamo Jumping)
|
// in_place: jump_* (Mixamo Jumping)
|
||||||
// forward: jump_fwd_anticipate/jump_fwd_air/jump_fwd_land (Mixamo Jump)
|
// forward: jump_fwd_* (Mixamo Jump, прыжок с шага)
|
||||||
const isForward = this._jumpKind === 'forward';
|
// run: jump_run_* (Mixamo Running Jump, прыжок с бега)
|
||||||
const stAnticipate = isForward ? 'jump_fwd_anticipate' : 'jump_anticipate';
|
const jk = this._jumpKind;
|
||||||
const stAir = isForward ? 'jump_fwd_air' : 'jump_air';
|
const isAirborneJump = jk === 'forward' || jk === 'run';
|
||||||
const stLand = isForward ? 'jump_fwd_land' : 'jump_land';
|
let stAnticipate, stAir, stLand, landDuration;
|
||||||
const landDuration = isForward ? 142 : 570;
|
if (jk === 'run') {
|
||||||
|
stAnticipate = 'jump_run_anticipate';
|
||||||
|
stAir = 'jump_run_air';
|
||||||
|
stLand = 'jump_run_land';
|
||||||
|
landDuration = 175;
|
||||||
|
} else if (jk === 'forward') {
|
||||||
|
stAnticipate = 'jump_fwd_anticipate';
|
||||||
|
stAir = 'jump_fwd_air';
|
||||||
|
stLand = 'jump_fwd_land';
|
||||||
|
landDuration = 142;
|
||||||
|
} else {
|
||||||
|
stAnticipate = 'jump_anticipate';
|
||||||
|
stAir = 'jump_air';
|
||||||
|
stLand = 'jump_land';
|
||||||
|
landDuration = 570;
|
||||||
|
}
|
||||||
const inAnticipate = this._jumpAnticipateUntil
|
const inAnticipate = this._jumpAnticipateUntil
|
||||||
&& now < this._jumpAnticipateUntil
|
&& now < this._jumpAnticipateUntil
|
||||||
&& this._jumpPendingImpulse;
|
&& this._jumpPendingImpulse;
|
||||||
@ -3378,7 +3400,7 @@ export class PlayerController {
|
|||||||
} else if (inJumpLand) {
|
} else if (inJumpLand) {
|
||||||
// Для forward — доигрываем land даже при движении
|
// Для forward — доигрываем land даже при движении
|
||||||
// (там короткая фаза 142мс)
|
// (там короткая фаза 142мс)
|
||||||
if (isForward || !isMoving) mState = stLand;
|
if (isAirborneJump || !isMoving) mState = stLand;
|
||||||
} else if (this._crouchEnterPending && inCrouchTransition && !isMoving) {
|
} else if (this._crouchEnterPending && inCrouchTransition && !isMoving) {
|
||||||
mState = 'crouch_enter';
|
mState = 'crouch_enter';
|
||||||
} else if (this._crouchExitPending && inCrouchTransition && !isMoving) {
|
} else if (this._crouchExitPending && inCrouchTransition && !isMoving) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user