new dash implementation

This commit is contained in:
2026-01-30 17:06:33 +01:00
parent 3102e1b2bf
commit caa53d5ade
15 changed files with 9302 additions and 173 deletions

View File

@@ -60734,6 +60734,10 @@ MonoBehaviour:
healthRecoveryCap: 1
useAnimationBasedRotation: 0
dashBlendTreeState: Dash_Directional
dashHorizontalParam: DashHorizontal
dashVerticalParam: DashVertical
dashAngleCorrection: 0
debugDash: 1
--- !u!114 &9202663235077955828
MonoBehaviour:
m_ObjectHideFlags: 0

View File

@@ -6652,6 +6652,18 @@ AnimatorController:
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
- m_Name: DashHorizontal
m_Type: 1
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
- m_Name: DashVertical
m_Type: 1
m_DefaultFloat: 0
m_DefaultInt: 0
m_DefaultBool: 0
m_Controller: {fileID: 9100000}
m_AnimatorLayers:
- serializedVersion: 5
m_Name: Base Layer
@@ -46844,16 +46856,7 @@ BlendTree:
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 10c005d4a1cfe8648af9ff7bfc4f7275,
type: 3}
m_Threshold: 0
m_Position: {x: 0, y: 0}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 10c005d4a1cfe8648af9ff7bfc4f7275,
type: 3}
m_Threshold: 0.25
m_Threshold: 0.125
m_Position: {x: 0, y: -1}
m_TimeScale: 1
m_CycleOffset: 0
@@ -46862,34 +46865,70 @@ BlendTree:
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 0e637c252c2643d4d9770ad55b6e71c1,
type: 3}
m_Threshold: 0.5
m_Threshold: 0.2
m_Position: {x: 0, y: 1}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 91b0987685baf44bb853583ed38ef4ed,
m_Motion: {fileID: 1827226128182048838, guid: ea59d735895318549a2927c0f055a480,
type: 3}
m_Threshold: 0.75
m_Threshold: 0.275
m_Position: {x: -1, y: 0}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 1c9f48ddca32d45479d6aeb95df77d7f,
m_Motion: {fileID: 1827226128182048838, guid: 92a0213fe328958449f8212bd701597b,
type: 3}
m_Threshold: 1
m_Threshold: 0.35
m_Position: {x: 1, y: 0}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
m_BlendParameter: InputHorizontal
m_BlendParameterY: InputVertical
m_MinThreshold: 0
m_MaxThreshold: 1
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 5390eaabe8094204983513a21277bd9b,
type: 3}
m_Threshold: 0.425
m_Position: {x: -0.7, y: -0.7}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: a60b5ff8c46006d4d9a39ac7327237eb,
type: 3}
m_Threshold: 0.5
m_Position: {x: 0.7, y: -0.7}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: 548517d69a9f2954bac08ec35b81e4c1,
type: 3}
m_Threshold: 0.575
m_Position: {x: -0.7, y: 0.7}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
- serializedVersion: 2
m_Motion: {fileID: 1827226128182048838, guid: aa01bc85e87e25e488a6c3f258007c7f,
type: 3}
m_Threshold: 0.65
m_Position: {x: 0.7, y: 0.7}
m_TimeScale: 1
m_CycleOffset: 0
m_DirectBlendParameter: InputHorizontal
m_Mirror: 0
m_BlendParameter: DashHorizontal
m_BlendParameterY: DashVertical
m_MinThreshold: 0.125
m_MaxThreshold: 0.65
m_UseAutomaticThresholds: 1
m_NormalizedBlendValues: 0
m_BlendType: 3

View File

@@ -14584,6 +14584,11 @@ PrefabInstance:
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4704300330561169846, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: locomotionType
value: 1
objectReference: {fileID: 0}
- target: {fileID: 4704300330561169846, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: strafeRollDuration
@@ -15107,12 +15112,12 @@ PrefabInstance:
- target: {fileID: 5234664790783380194, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: m_AnchoredPosition.x
value: 2781164
value: 4271459
objectReference: {fileID: 0}
- target: {fileID: 5234664790783380194, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: m_AnchoredPosition.y
value: -444986.44
value: -683435.1
objectReference: {fileID: 0}
- target: {fileID: 5265345828117443429, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
@@ -15162,7 +15167,17 @@ PrefabInstance:
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.size
value: 9
value: 11
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: itemsFilter.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: 'itemsFilter.Array.data[0]'
value: 23
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
@@ -15182,12 +15197,12 @@ PrefabInstance:
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].id
value: 1
value: 96
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].id
value: 1
value: 97
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
@@ -15297,12 +15312,12 @@ PrefabInstance:
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].amount
value: 1
value: 3
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].amount
value: 1
value: 3
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
@@ -15417,22 +15432,22 @@ PrefabInstance:
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].autoEquip
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].indexArea
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].autoEquip
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].indexArea
value: 0
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
@@ -15739,16 +15754,46 @@ PrefabInstance:
propertyPath: startItems.Array.data[8].attributes.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].attributes.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].attributes.Array.size
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[8].attributes.Array.data[0].name
value: 12
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].attributes.Array.data[0].name
value: 12
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].attributes.Array.data[0].name
value: 12
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[8].attributes.Array.data[0].value
value: 15
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[9].attributes.Array.data[0].value
value: 15
objectReference: {fileID: 0}
- target: {fileID: 5582921900280934274, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: startItems.Array.data[10].attributes.Array.data[0].value
value: 15
objectReference: {fileID: 0}
- target: {fileID: 5613825752652024524, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: m_Layer
@@ -15879,6 +15924,11 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.y
value: -116.866
objectReference: {fileID: 0}
- target: {fileID: 6463794160194089925, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6692395660911280292, guid: 851e8e61247888340bdec90fc8aa37f5,
type: 3}
propertyPath: m_Layer

View File

@@ -21,18 +21,19 @@ namespace Beyond
[Header("Beyond's Dash Settings")]
public string dashBlendTreeState = "Dash_Directional";
public string dashHorizontalParam = "DashHorizontal";
public string dashVerticalParam = "DashVertical";
// Internal flag to lock animator parameters during dash
private bool _lockAnimParamsForDash = false;
[Tooltip("If your animation is slightly rotated (Red arrow offset), add an angle here to compensate (e.g. -45 or 45).")]
public float dashAngleCorrection = 0f;
[Tooltip("Print debug info to Console when dashing")]
public bool debugDash = true;
public bool GodMode
{
get => m_GodMode;
set
{
m_GodMode = value;
isImmortal = m_GodMode;
}
set { m_GodMode = value; isImmortal = m_GodMode; }
}
protected override bool canRecoverHealth
@@ -44,21 +45,13 @@ namespace Beyond
}
}
public bool IsDashingOrRolling()
{
return m_isDashing || isRolling;
}
public bool IsDashingOrRolling() => m_isDashing || isRolling;
protected override void Start()
{
base.Start();
}
protected override void RollBehavior()
{
base.RollBehavior();
}
public override void Roll()
{
Dash();
@@ -71,71 +64,59 @@ namespace Beyond
ReduceStamina(rollStamina, false);
currentStaminaRecoveryDelay = 2f;
// 1. Handle Stationary (Backwards Dash)
if (input.sqrMagnitude < 0.05f)
// Setup Camera Vectors
Transform camT = Camera.main != null ? Camera.main.transform : transform;
// Flatten camera vectors so looking up/down doesn't affect dash length
Vector3 camFwd = Vector3.Scale(camT.forward, new Vector3(1, 0, 1)).normalized;
Vector3 camRight = Vector3.Scale(camT.right, new Vector3(1, 0, 1)).normalized;
Vector3 targetWorldDir = Vector3.zero;
// 1. Determine Target World Direction
if (input.sqrMagnitude < 0.1f)
{
ApplyDashParams(0f, -1f);
// NO INPUT -> Move strictly "Into the Screen" (Towards Camera)
// This is the negative of the Camera Forward vector.
targetWorldDir = -camFwd;
if (debugDash) Debug.Log($"[Dash] No Input. Target: BACKWARD ({targetWorldDir})");
}
else
{
// 2. Handle Directional Input (Camera Relative -> Character Relative)
// DIRECTIONAL INPUT
// FIX: Use input.z for Forward/Backward, NOT input.y
targetWorldDir = (camFwd * input.z + camRight * input.x).normalized;
// A. Get the Input Direction relative to the Camera
Vector3 inputDir = Vector3.zero;
if (Camera.main != null)
{
// Convert joystick input (X,Y) into World Space based on Camera facing
Vector3 camFwd = Vector3.Scale(Camera.main.transform.forward, new Vector3(1, 0, 1)).normalized;
Vector3 camRight = Vector3.Scale(Camera.main.transform.right, new Vector3(1, 0, 1)).normalized;
inputDir = (camFwd * input.y + camRight * input.x).normalized;
}
else
{
// Fallback if no camera found
inputDir = new Vector3(input.x, 0, input.y).normalized;
}
// B. Convert that World Direction into the Character's Local Space
// This tells us: "Is the input to the Left, Right, or Forward of ME?"
Vector3 localDir = transform.InverseTransformDirection(inputDir);
// C. Send to Animator
ApplyDashParams(localDir.x, localDir.z);
if (debugDash) Debug.Log($"[Dash] Input: {input}. Target World Dir: {targetWorldDir}");
}
// 3. Play Animation
// 2. Convert World Direction to Character Local Space
// "Where is the Target World Dir relative to ME?"
Vector3 localDir = transform.InverseTransformDirection(targetWorldDir);
// 3. Apply Angle Correction (If animation is skewed 45 degrees)
if (dashAngleCorrection != 0f)
{
localDir = Quaternion.Euler(0, dashAngleCorrection, 0) * localDir;
}
// 4. Normalize (Ensure full blend magnitude)
localDir.y = 0;
localDir.Normalize();
// 5. Send to Animator (Dedicated Parameters)
animator.SetFloat(dashHorizontalParam, localDir.x);
animator.SetFloat(dashVerticalParam, localDir.z);
if (debugDash)
{
Debug.Log($"[Dash Final] Local X: {localDir.x} | Local Z: {localDir.z}");
}
// 6. Play Animation
animator.CrossFadeInFixedTime(dashBlendTreeState, rollTransition, baseLayer);
// 4. Lock parameters briefly so Invector doesn't overwrite them immediately
StartCoroutine(LockDashParamsRoutine());
}
// Helper to set params and lock the update loop
private void ApplyDashParams(float x, float y)
{
_lockAnimParamsForDash = true;
animator.SetFloat(vAnimatorParameters.InputHorizontal, x);
animator.SetFloat(vAnimatorParameters.InputVertical, y);
}
// Release the lock after a short delay (once the blend has firmly started)
private IEnumerator LockDashParamsRoutine()
{
yield return new WaitForSeconds(0.2f); // Adjust this if the blend pops back too soon
_lockAnimParamsForDash = false;
}
// --- CRITICAL FIX: Override Invector's Parameter Update ---
public override void UpdateAnimatorParameters()
{
// If we are locking parameters for the dash, DO NOT let the base class overwrite them.
if (_lockAnimParamsForDash) return;
// Otherwise, run standard Invector logic
base.UpdateAnimatorParameters();
}
// Standard overrides below...
// --- Standard Boilerplate Below ---
public void OnEvadeStart() { if (!m_GodMode) isImmortal = true; }
public void OnEvadeEnd() { if (!m_GodMode) isImmortal = false; }
public override void ActionsControl() { base.ActionsControl(); m_isDashing = IsAnimatorTag("IsDashing"); }
@@ -148,30 +129,18 @@ namespace Beyond
{
int deadLayer = 0;
var info = animatorStateInfos.GetStateInfoUsingTag("Dead");
if (info != null)
{
if (!animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.99f && groundDistance <= 0.15f) RemoveComponents();
}
if (info != null && !animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.99f && groundDistance <= 0.15f) RemoveComponents();
}
else if (deathBy == DeathBy.AnimationWithRagdoll)
{
int deadLayer = 0;
var info = animatorStateInfos.GetStateInfoUsingTag("Dead");
if (info != null)
{
if (!animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.8f) onActiveRagdoll.Invoke(null);
}
}
else if (deathBy == DeathBy.Ragdoll)
{
onActiveRagdoll.Invoke(null);
if (info != null && !animator.IsInTransition(deadLayer) && info.normalizedTime >= 0.8f) onActiveRagdoll.Invoke(null);
}
else if (deathBy == DeathBy.Ragdoll) onActiveRagdoll.Invoke(null);
}
public void RemoveAnimatorTags()
{
animatorStateInfos.stateInfos.vToList().ForEach(infos => infos.tags.Clear());
}
public void RemoveAnimatorTags() => animatorStateInfos.stateInfos.vToList().ForEach(infos => infos.tags.Clear());
public override void ControlAnimatorRootMotion()
{
@@ -191,24 +160,17 @@ namespace Beyond
if (useRootMotion) MoveCharacter(moveDirection);
}
protected override void OnTriggerEnter(Collider other)
{
if (!m_ignoreTriggers) onActionEnter.Invoke(other);
}
protected override void OnTriggerEnter(Collider other) { if (!m_ignoreTriggers) onActionEnter.Invoke(other); }
protected override void OnTriggerStay(Collider other)
{
try { CheckForAutoCrouch(other); }
catch (UnityException e) { Debug.LogWarning(e.Message); }
try { CheckForAutoCrouch(other); } catch (UnityException e) { Debug.LogWarning(e.Message); }
if (!m_ignoreTriggers) base.OnTriggerStay(other);
}
protected override void OnTriggerExit(Collider other)
{
AutoCrouchExit(other);
if (!m_ignoreTriggers) base.OnTriggerExit(other);
}
void DrawWeaponLowLeft() { }
public override void ControlRotationType()
@@ -217,10 +179,7 @@ namespace Beyond
bool validInput = input != Vector3.zero || (isStrafing ? strafeSpeed.rotateWithCamera : freeSpeed.rotateWithCamera);
if (validInput)
{
if (lockAnimMovement)
{
inputSmooth = Vector3.Lerp(inputSmooth, input, (isStrafing ? strafeSpeed.movementSmooth : freeSpeed.movementSmooth) * Time.deltaTime);
}
if (lockAnimMovement) inputSmooth = Vector3.Lerp(inputSmooth, input, (isStrafing ? strafeSpeed.movementSmooth : freeSpeed.movementSmooth) * Time.deltaTime);
Vector3 dir = (isStrafing && isGrounded && (!isSprinting || sprintOnlyFree == false) || (freeSpeed.rotateWithCamera && input == Vector3.zero)) && rotateTarget ? rotateTarget.forward : moveDirection;
if (isStrafing || !useAnimationBasedRotation) RotateToDirection(dir);
}

View File

@@ -122,6 +122,7 @@ Material:
- _DetailNormalMapScale: 1
- _DissolveNoiseScale: 25
- _DstBlend: 10
- _DstBlendAlpha: 10
- _EffectStrenght: 1
- _EffectThreshold: 0
- _EnvironmentReflections: 1
@@ -140,6 +141,7 @@ Material:
- _SmoothnessTextureChannel: 0
- _SpecularHighlights: 1
- _SrcBlend: 1
- _SrcBlendAlpha: 1
- _Surface: 1
- _Threshold: 0
- _USEDISSOLVE: 1

View File

@@ -19,10 +19,15 @@ ModelImporter:
animationImportErrors:
animationImportWarnings: "\nClip 'Take 001' has import animation warnings that
might lower retargeting quality:\nNote: Activate translation DOF on avatar
to improve retargeting quality.\n\t'BascileusRCalf' has scale animation that
will be discarded.\n\t'BascileusRFoot' has scale animation that will be discarded.\n\t'BascileusRibcage'
is inbetween humanoid transforms and has rotation animation that will be discarded.\n\t'BascileusLForearm2'
is inbetween humanoid transforms and has rotation animation that will be discarded.\n\t'BascileusRForearm2'
to improve retargeting quality.\n\t'BascileusLCalf' has scale animation that
will be discarded.\n\t'BascileusLFoot' has scale animation that will be discarded.\n\t'BascileusRibcage'
is inbetween humanoid transforms and has rotation animation that will be discarded.\n\t'BascileusLForearm1'
has scale animation that will be discarded.\n\t'BascileusLForearm2' is inbetween
humanoid transforms and has rotation animation that will be discarded.\n\t'BascileusLPalm'
has scale animation that will be discarded.\n\t'BascileusLDigit11' has scale
animation that will be discarded.\n\t'BascileusLDigit22' has scale animation
that will be discarded.\n\t'BascileusLDigit32' has scale animation that will
be discarded.\n\t'BascileusLDigit42' has scale animation that will be discarded.\n\t'BascileusRForearm2'
is inbetween humanoid transforms and has rotation animation that will be discarded.\n"
animationRetargetingWarnings:
animationDoRetargetingWarnings: 0
@@ -50,12 +55,12 @@ ModelImporter:
hasAdditiveReferencePose: 0
loopTime: 0
loopBlend: 0
loopBlendOrientation: 0
loopBlendOrientation: 1
loopBlendPositionY: 0
loopBlendPositionXZ: 0
keepOriginalOrientation: 0
keepOriginalOrientation: 1
keepOriginalPositionY: 1
keepOriginalPositionXZ: 1
keepOriginalPositionXZ: 0
heightFromFeet: 0
mirror: 0
bodyMask: 01000000010000000100000001000000010000000100000001000000010000000100000001000000010000000100000001000000