From e3f80c2856d025ad4e1a105e30f56e7f7d3d915c Mon Sep 17 00:00:00 2001 From: Gabriel Ikezaki Date: Sun, 26 Jul 2026 11:54:38 +0100 Subject: [PATCH 1/4] fix: adjust wallrun camera bound --- Assets/Scripts/Player/PlayerCamera.cs | 41 ++++++++++++------- .../Player/StateMachine/PlayerWallRunState.cs | 32 ++++++++------- Assets/Scripts/StateMachine/BaseState.cs | 6 +-- 3 files changed, 47 insertions(+), 32 deletions(-) diff --git a/Assets/Scripts/Player/PlayerCamera.cs b/Assets/Scripts/Player/PlayerCamera.cs index 94f9440..161ccc2 100644 --- a/Assets/Scripts/Player/PlayerCamera.cs +++ b/Assets/Scripts/Player/PlayerCamera.cs @@ -8,8 +8,9 @@ public class PlayerCamera : MonoBehaviour [Header("Settings")] [SerializeField] float mouseSensitivity = 100f; [SerializeField] float verticalClamp = 90f; - float maxHorizontalClamp = 0f; - float minHorizontalClamp = 0f; + bool isHorizontallyBounded = false; + float clockWiseBound = 0f; + float counterClockWiseBound = 0f; private float xRotation = 0f; private float yRotation = 0f; @@ -27,25 +28,31 @@ void Update() xRotation -= mouseY; xRotation = Mathf.Clamp(xRotation, -verticalClamp, verticalClamp); - - yRotation += mouseX; - yRotation = (maxHorizontalClamp == minHorizontalClamp) - ? yRotation % 360f - : Mathf.Clamp(yRotation, minHorizontalClamp, maxHorizontalClamp) % 360f; - transform.localRotation = Quaternion.Euler(xRotation, 0f, 0f); + + if(isHorizontallyBounded) + { + if( + (mouseX > 0f && yRotation + mouseX >= clockWiseBound) + || (mouseX < 0f && yRotation + mouseX <= counterClockWiseBound) + ) return; + } + + yRotation += mouseX; // This thing can grow indefinitely. It'll become a god. orientation.localRotation = Quaternion.Euler(0f, yRotation, 0f); } - public void SetHorizontalClamp(float min, float max) + public void SetHorizontalBounds(float counterClockWise, float clockWise) { - minHorizontalClamp = min % 360f; - maxHorizontalClamp = max % 360f; + counterClockWiseBound = counterClockWise; + clockWiseBound = clockWise; + isHorizontallyBounded = true; } - public void RemoveHorizontalClamp() + public void RemoveHorizontalBounds() { - minHorizontalClamp = 0; - maxHorizontalClamp = 0; + counterClockWiseBound = 0; + clockWiseBound = 0; + isHorizontallyBounded = false; } public float GetYRotation() @@ -57,4 +64,10 @@ public void SetYRotation(float yRotation) { this.yRotation = yRotation; } + + public void MakeRotationPositive() + { + if (yRotation >= 0f) return; + yRotation = (yRotation + 360f) % 360f; + } } diff --git a/Assets/Scripts/Player/StateMachine/PlayerWallRunState.cs b/Assets/Scripts/Player/StateMachine/PlayerWallRunState.cs index be8f029..7dece70 100644 --- a/Assets/Scripts/Player/StateMachine/PlayerWallRunState.cs +++ b/Assets/Scripts/Player/StateMachine/PlayerWallRunState.cs @@ -15,7 +15,7 @@ public PlayerWallRunState(PlayerStateMachine context, PlayerStateFactory factory wallNormal = leftHit.collider ? leftHit.normal : rightHit.normal; adjacentNormal = Vector3.Cross(wallNormal, Vector3.up).normalized; - SetClamp(); + SetBounds(); } public override void EnterState(){} @@ -31,7 +31,7 @@ public override void FixedUpdateState() } public override void ExitState() { - _context.PlayerCamera.RemoveHorizontalClamp(); + _context.PlayerCamera.RemoveHorizontalBounds(); } public override void CheckSwitchStates() { @@ -47,6 +47,7 @@ public override void CheckSwitchStates() } } public override void InitializeSubState(){} + void WallRun() { float multiplier = _context.AirMultiplier; @@ -65,27 +66,28 @@ void WallJump(Vector3 direction) rb.AddForce(direction * FORWARD_FORCE, ForceMode.Impulse); SwitchState(_factory.AirMove()); } + void Jump() { if(_context.PressedJump) WallJump(_context.Aim.cameraForward()); } - void SetClamp() + void SetBounds() { const float CLAMP_ANGLE = 73f; - Quaternion adjacentLookDir = Quaternion.LookRotation(adjacentNormal, Vector3.up); - float adjacentLookAngle = adjacentLookDir.eulerAngles.y; - float oppositeLookAngle = (adjacentLookAngle + 180f) % 360f; + Quaternion adjacentLookDir = Quaternion.LookRotation(adjacentNormal, Vector3.up); // The direction that goes along the wall + + float yRotation = _context.PlayerCamera.GetYRotation(); // Current camera rotation in world space + float adjacentLookAngle = adjacentLookDir.eulerAngles.y; // The world angle of the direction that goes along the wall in one direction + + float angleDiff = yRotation - adjacentLookAngle; + float halfRotations = Mathf.Round(angleDiff / 180f); // Used to "rotate" the adjacentLookAngle so that the current camera rotation is within bound range + + float baseLookAngle = adjacentLookAngle + (halfRotations * 180f); // The "rotated" adjacentLookAngle + float clockWiseBound = baseLookAngle + CLAMP_ANGLE; + float counterClockWiseBound = baseLookAngle - CLAMP_ANGLE; - float yRotation = Mathf.Abs(_context.PlayerCamera.GetYRotation()); - if(yRotation >= oppositeLookAngle - CLAMP_ANGLE && yRotation <= oppositeLookAngle + CLAMP_ANGLE) - { - adjacentLookAngle = oppositeLookAngle; - } - // Debug.Log("LookAngle: " + adjacentLookAngle + " | Clamp Range: " + (adjacentLookAngle - CLAMP_ANGLE) + ", " + (adjacentLookAngle + CLAMP_ANGLE)); - int yRotationSign = _context.PlayerCamera.GetYRotation() < 0 ? -1 : 1; - float clampBase = adjacentLookAngle * yRotationSign; - _context.PlayerCamera.SetHorizontalClamp(clampBase - CLAMP_ANGLE, clampBase + CLAMP_ANGLE); + _context.PlayerCamera.SetHorizontalBounds(counterClockWiseBound, clockWiseBound); } } diff --git a/Assets/Scripts/StateMachine/BaseState.cs b/Assets/Scripts/StateMachine/BaseState.cs index 635c6f8..c063a97 100644 --- a/Assets/Scripts/StateMachine/BaseState.cs +++ b/Assets/Scripts/StateMachine/BaseState.cs @@ -66,20 +66,20 @@ protected void SwitchState(BaseState newState) * substate to change from this one to the new one. Pretty * much transfering states. */ - Debug.Log("Sub State switched to: " + newState.name); + // Debug.Log("Sub State switched to: " + newState.name); currentSuperState.SetSubState(newState); } } protected void SetSuperState(BaseState newSuperState) { - Debug.Log(this + " setting new Super State: " + newSuperState.name); + // Debug.Log(this + " setting new Super State: " + newSuperState.name); currentSuperState = newSuperState; } protected void SetSubState(BaseState newSubState) { - Debug.Log(this + " setting new Sub State: " + newSubState.name); + // Debug.Log(this + " setting new Sub State: " + newSubState.name); currentSubState = newSubState; newSubState.SetSuperState(this); } From be42de4ab316a1d2ea2af0df107a0560fd94d021 Mon Sep 17 00:00:00 2001 From: Gabriel Ikezaki Date: Sun, 26 Jul 2026 18:14:12 +0100 Subject: [PATCH 2/4] feat: add roll animation --- .../Player/Orientation/GroundStandUp.anim | 425 ------------------ .../Orientation/GroundStandUp.anim.meta | 8 - .../Orientation/PlayerOrientation.controller | 154 +++++-- .../{AirStandUp.anim => Roll.anim} | 182 +++++--- .../{AirStandUp.anim.meta => Roll.anim.meta} | 2 +- 5 files changed, 240 insertions(+), 531 deletions(-) delete mode 100644 Assets/Animations/Player/Orientation/GroundStandUp.anim delete mode 100644 Assets/Animations/Player/Orientation/GroundStandUp.anim.meta rename Assets/Animations/Player/Orientation/{AirStandUp.anim => Roll.anim} (82%) rename Assets/Animations/Player/Orientation/{AirStandUp.anim.meta => Roll.anim.meta} (79%) diff --git a/Assets/Animations/Player/Orientation/GroundStandUp.anim b/Assets/Animations/Player/Orientation/GroundStandUp.anim deleted file mode 100644 index d9b62e3..0000000 --- a/Assets/Animations/Player/Orientation/GroundStandUp.anim +++ /dev/null @@ -1,425 +0,0 @@ -%YAML 1.1 -%TAG !u! tag:unity3d.com,2011: ---- !u!74 &7400000 -AnimationClip: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: GroundStandUp - serializedVersion: 7 - m_Legacy: 0 - m_Compressed: 0 - m_UseHighQualityCurve: 1 - m_RotationCurves: [] - m_CompressedRotationCurves: [] - m_EulerCurves: [] - m_PositionCurves: - - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: {x: 0, y: 0.029, z: 0} - inSlope: {x: 0, y: 0, z: 0} - outSlope: {x: 0, y: 0, z: 0} - tangentMode: 0 - weightedMode: 0 - inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - - serializedVersion: 3 - time: 0.11666667 - value: {x: 0, y: 0.6359999, z: 0} - inSlope: {x: 0, y: 0, z: 0} - outSlope: {x: 0, y: 0, z: 0} - tangentMode: 0 - weightedMode: 0 - inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - path: CameraHolder - - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: {x: 0, y: -0.3506, z: 0} - inSlope: {x: 0, y: 0, z: 0} - outSlope: {x: 0, y: 0, z: 0} - tangentMode: 0 - weightedMode: 0 - inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - - serializedVersion: 3 - time: 0.11666667 - value: {x: 0, y: 0, z: 0} - inSlope: {x: 0, y: 0, z: 0} - outSlope: {x: 0, y: 0, z: 0} - tangentMode: 0 - weightedMode: 0 - inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - path: Capsule - m_ScaleCurves: - - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: {x: 1, y: 0.6493903, z: 1} - inSlope: {x: 0, y: 0, z: 0} - outSlope: {x: 0, y: 0, z: 0} - tangentMode: 0 - weightedMode: 0 - inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - - serializedVersion: 3 - time: 0.11666667 - value: {x: 1, y: 1, z: 1} - inSlope: {x: 0, y: 0, z: 0} - outSlope: {x: 0, y: 0, z: 0} - tangentMode: 0 - weightedMode: 0 - inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - path: Capsule - m_FloatCurves: [] - m_PPtrCurves: [] - m_SampleRate: 60 - m_WrapMode: 0 - m_Bounds: - m_Center: {x: 0, y: 0, z: 0} - m_Extent: {x: 0, y: 0, z: 0} - m_ClipBindingConstant: - genericBindings: - - serializedVersion: 2 - path: 1022213160 - attribute: 1 - script: {fileID: 0} - typeID: 4 - customType: 0 - isPPtrCurve: 0 - isIntCurve: 0 - isSerializeReferenceCurve: 0 - - serializedVersion: 2 - path: 232101919 - attribute: 1 - script: {fileID: 0} - typeID: 4 - customType: 0 - isPPtrCurve: 0 - isIntCurve: 0 - isSerializeReferenceCurve: 0 - - serializedVersion: 2 - path: 232101919 - attribute: 3 - script: {fileID: 0} - typeID: 4 - customType: 0 - isPPtrCurve: 0 - isIntCurve: 0 - isSerializeReferenceCurve: 0 - pptrCurveMapping: [] - m_AnimationClipSettings: - serializedVersion: 2 - m_AdditiveReferencePoseClip: {fileID: 0} - m_AdditiveReferencePoseTime: 0 - m_StartTime: 0 - m_StopTime: 0.11666667 - m_OrientationOffsetY: 0 - m_Level: 0 - m_CycleOffset: 0 - m_HasAdditiveReferencePose: 0 - m_LoopTime: 0 - m_LoopBlend: 0 - m_LoopBlendOrientation: 0 - m_LoopBlendPositionY: 0 - m_LoopBlendPositionXZ: 0 - m_KeepOriginalOrientation: 0 - m_KeepOriginalPositionY: 1 - m_KeepOriginalPositionXZ: 0 - m_HeightFromFeet: 0 - m_Mirror: 0 - m_EditorCurves: - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalPosition.x - path: CameraHolder - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0.029 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 0.6359999 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalPosition.y - path: CameraHolder - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalPosition.z - path: CameraHolder - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalPosition.x - path: Capsule - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: -0.3506 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalPosition.y - path: Capsule - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 0 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalPosition.z - path: Capsule - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalScale.x - path: Capsule - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 0.6493903 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalScale.y - path: Capsule - classID: 4 - script: {fileID: 0} - flags: 0 - - serializedVersion: 2 - curve: - serializedVersion: 2 - m_Curve: - - serializedVersion: 3 - time: 0 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - - serializedVersion: 3 - time: 0.11666667 - value: 1 - inSlope: 0 - outSlope: 0 - tangentMode: 136 - weightedMode: 0 - inWeight: 0.33333334 - outWeight: 0.33333334 - m_PreInfinity: 2 - m_PostInfinity: 2 - m_RotationOrder: 4 - attribute: m_LocalScale.z - path: Capsule - classID: 4 - script: {fileID: 0} - flags: 0 - m_EulerEditorCurves: [] - m_HasGenericRootTransform: 0 - m_HasMotionFloatCurves: 0 - m_Events: [] diff --git a/Assets/Animations/Player/Orientation/GroundStandUp.anim.meta b/Assets/Animations/Player/Orientation/GroundStandUp.anim.meta deleted file mode 100644 index fa6a4be..0000000 --- a/Assets/Animations/Player/Orientation/GroundStandUp.anim.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: ce3130571860da541911017ea755470b -NativeFormatImporter: - externalObjects: {} - mainObjectFileID: 7400000 - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Animations/Player/Orientation/PlayerOrientation.controller b/Assets/Animations/Player/Orientation/PlayerOrientation.controller index 1616761..3306616 100644 --- a/Assets/Animations/Player/Orientation/PlayerOrientation.controller +++ b/Assets/Animations/Player/Orientation/PlayerOrientation.controller @@ -127,6 +127,9 @@ AnimatorStateTransition: - m_ConditionMode: 1 m_ConditionEvent: Grounded m_EventTreshold: 0 + - m_ConditionMode: 2 + m_ConditionEvent: Rolling + m_EventTreshold: 0 m_DstStateMachine: {fileID: 0} m_DstState: {fileID: -2465076779379803191} m_Solo: 0 @@ -156,18 +159,15 @@ AnimatorStateMachine: - serializedVersion: 1 m_State: {fileID: 8266268976970671112} m_Position: {x: 50, y: 590, z: 0} - - serializedVersion: 1 - m_State: {fileID: 912697715850440543} - m_Position: {x: 150, y: 30, z: 0} - serializedVersion: 1 m_State: {fileID: 3997618425405177691} - m_Position: {x: 430, y: 280, z: 0} - - serializedVersion: 1 - m_State: {fileID: -3668854303707722321} - m_Position: {x: 330, y: -20, z: 0} + m_Position: {x: 680, y: 490, z: 0} - serializedVersion: 1 m_State: {fileID: -2465076779379803191} m_Position: {x: 370, y: 590, z: 0} + - serializedVersion: 1 + m_State: {fileID: -839922899556779156} + m_Position: {x: 720, y: 240, z: 0} m_ChildStateMachines: [] m_AnyStateTransitions: [] m_EntryTransitions: [] @@ -178,17 +178,19 @@ AnimatorStateMachine: m_ExitPosition: {x: 800, y: 120, z: 0} m_ParentStateMachinePosition: {x: 800, y: 20, z: 0} m_DefaultState: {fileID: -6959265476885965635} ---- !u!1102 &-3668854303707722321 +--- !u!1102 &-2465076779379803191 AnimatorState: serializedVersion: 6 m_ObjectHideFlags: 1 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: AirStandUp + m_Name: GroundSlide m_Speed: 1 m_CycleOffset: 0 - m_Transitions: [] + m_Transitions: + - {fileID: 8869372357425199926} + - {fileID: 960849644707303155} m_StateMachineBehaviours: [] m_Position: {x: 50, y: 50, z: 0} m_IKOnFeet: 0 @@ -198,25 +200,25 @@ AnimatorState: m_MirrorParameterActive: 0 m_CycleOffsetParameterActive: 0 m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: f071f11c5d2957a49b02edcb646f9f89, type: 2} + m_Motion: {fileID: 7400000, guid: 3be7011ef2688db43a836a2ae26af94d, type: 2} m_Tag: m_SpeedParameter: m_MirrorParameter: m_CycleOffsetParameter: m_TimeParameter: ---- !u!1102 &-2465076779379803191 +--- !u!1102 &-839922899556779156 AnimatorState: serializedVersion: 6 m_ObjectHideFlags: 1 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: GroundSlide + m_Name: Roll m_Speed: 1 m_CycleOffset: 0 m_Transitions: - - {fileID: 8869372357425199926} - - {fileID: 960849644707303155} + - {fileID: 2101414185491879145} + - {fileID: 5441160079636676230} m_StateMachineBehaviours: [] m_Position: {x: 50, y: 50, z: 0} m_IKOnFeet: 0 @@ -226,7 +228,7 @@ AnimatorState: m_MirrorParameterActive: 0 m_CycleOffsetParameterActive: 0 m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: 3be7011ef2688db43a836a2ae26af94d, type: 2} + m_Motion: {fileID: 7400000, guid: ab09cca703b69c146acfbb69647b846f, type: 2} m_Tag: m_SpeedParameter: m_MirrorParameter: @@ -259,6 +261,12 @@ AnimatorController: m_DefaultInt: 0 m_DefaultBool: 0 m_Controller: {fileID: 9100000} + - m_Name: Rolling + m_Type: 4 + m_DefaultFloat: 0 + m_DefaultInt: 0 + m_DefaultBool: 0 + m_Controller: {fileID: 9100000} m_AnimatorLayers: - serializedVersion: 5 m_Name: Base Layer @@ -272,32 +280,6 @@ AnimatorController: m_IKPass: 0 m_SyncedLayerAffectsTiming: 0 m_Controller: {fileID: 9100000} ---- !u!1102 &912697715850440543 -AnimatorState: - serializedVersion: 6 - m_ObjectHideFlags: 1 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_Name: GroundStandUp - m_Speed: 1 - m_CycleOffset: 0 - m_Transitions: [] - m_StateMachineBehaviours: [] - m_Position: {x: 50, y: 50, z: 0} - m_IKOnFeet: 0 - m_WriteDefaultValues: 1 - m_Mirror: 0 - m_SpeedParameterActive: 0 - m_MirrorParameterActive: 0 - m_CycleOffsetParameterActive: 0 - m_TimeParameterActive: 0 - m_Motion: {fileID: 7400000, guid: ce3130571860da541911017ea755470b, type: 2} - m_Tag: - m_SpeedParameter: - m_MirrorParameter: - m_CycleOffsetParameter: - m_TimeParameter: --- !u!1101 &960849644707303155 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -326,6 +308,37 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 +--- !u!1101 &2101414185491879145 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 2 + m_ConditionEvent: CrouchPressed + m_EventTreshold: 0 + - m_ConditionMode: 1 + m_ConditionEvent: Grounded + m_EventTreshold: 0 + - m_ConditionMode: 2 + m_ConditionEvent: Rolling + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -6959265476885965635} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0 + m_TransitionOffset: 0 + m_ExitTime: 0 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1102 &3997618425405177691 AnimatorState: serializedVersion: 6 @@ -339,6 +352,7 @@ AnimatorState: m_Transitions: - {fileID: -4648518239752711752} - {fileID: -4408986984054651228} + - {fileID: 7699341573661604819} m_StateMachineBehaviours: [] m_Position: {x: 50, y: 50, z: 0} m_IKOnFeet: 0 @@ -354,6 +368,31 @@ AnimatorState: m_MirrorParameter: m_CycleOffsetParameter: m_TimeParameter: +--- !u!1101 &5441160079636676230 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 2 + m_ConditionEvent: Grounded + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -6959265476885965635} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.1 + m_TransitionOffset: 0 + m_ExitTime: 0 + m_HasExitTime: 0 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1101 &5665668721513457468 AnimatorStateTransition: m_ObjectHideFlags: 1 @@ -382,6 +421,37 @@ AnimatorStateTransition: m_InterruptionSource: 0 m_OrderedInterruption: 1 m_CanTransitionToSelf: 1 +--- !u!1101 &7699341573661604819 +AnimatorStateTransition: + m_ObjectHideFlags: 1 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: + m_Conditions: + - m_ConditionMode: 1 + m_ConditionEvent: Grounded + m_EventTreshold: 0 + - m_ConditionMode: 1 + m_ConditionEvent: CrouchPressed + m_EventTreshold: 0 + - m_ConditionMode: 1 + m_ConditionEvent: Rolling + m_EventTreshold: 0 + m_DstStateMachine: {fileID: 0} + m_DstState: {fileID: -839922899556779156} + m_Solo: 0 + m_Mute: 0 + m_IsExit: 0 + serializedVersion: 3 + m_TransitionDuration: 0.1 + m_TransitionOffset: 0 + m_ExitTime: 0 + m_HasExitTime: 1 + m_HasFixedDuration: 1 + m_InterruptionSource: 0 + m_OrderedInterruption: 1 + m_CanTransitionToSelf: 1 --- !u!1102 &8266268976970671112 AnimatorState: serializedVersion: 6 diff --git a/Assets/Animations/Player/Orientation/AirStandUp.anim b/Assets/Animations/Player/Orientation/Roll.anim similarity index 82% rename from Assets/Animations/Player/Orientation/AirStandUp.anim rename to Assets/Animations/Player/Orientation/Roll.anim index 4ffbd2f..06d392f 100644 --- a/Assets/Animations/Player/Orientation/AirStandUp.anim +++ b/Assets/Animations/Player/Orientation/Roll.anim @@ -6,21 +6,20 @@ AnimationClip: m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_Name: AirStandUp + m_Name: Roll serializedVersion: 7 m_Legacy: 0 m_Compressed: 0 m_UseHighQualityCurve: 1 m_RotationCurves: [] m_CompressedRotationCurves: [] - m_EulerCurves: [] - m_PositionCurves: + m_EulerCurves: - curve: serializedVersion: 2 m_Curve: - serializedVersion: 3 time: 0 - value: {x: 0, y: 0.3506, z: 0} + value: {x: 0, y: 0, z: 0} inSlope: {x: 0, y: 0, z: 0} outSlope: {x: 0, y: 0, z: 0} tangentMode: 0 @@ -28,8 +27,17 @@ AnimationClip: inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - serializedVersion: 3 - time: 0.11666667 - value: {x: 0, y: 0, z: 0} + time: 0.4 + value: {x: 360, y: 0, z: 0} + inSlope: {x: 0, y: 0, z: 0} + outSlope: {x: 0, y: 0, z: 0} + tangentMode: 0 + weightedMode: 0 + inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} + outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} + - serializedVersion: 3 + time: 0.41666666 + value: {x: 360, y: 0, z: 0} inSlope: {x: 0, y: 0, z: 0} outSlope: {x: 0, y: 0, z: 0} tangentMode: 0 @@ -39,13 +47,14 @@ AnimationClip: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - path: Capsule + path: CameraHolder + m_PositionCurves: - curve: serializedVersion: 2 m_Curve: - serializedVersion: 3 time: 0 - value: {x: 0, y: 0.6359999, z: 0} + value: {x: 0, y: 0.3506, z: 0} inSlope: {x: 0, y: 0, z: 0} outSlope: {x: 0, y: 0, z: 0} tangentMode: 0 @@ -53,8 +62,8 @@ AnimationClip: inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - serializedVersion: 3 - time: 0.11666667 - value: {x: 0, y: 0.6359999, z: 0} + time: 0.41666666 + value: {x: 0, y: 0.3506, z: 0} inSlope: {x: 0, y: 0, z: 0} outSlope: {x: 0, y: 0, z: 0} tangentMode: 0 @@ -64,7 +73,7 @@ AnimationClip: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - path: CameraHolder + path: Capsule - curve: serializedVersion: 2 m_Curve: @@ -78,8 +87,8 @@ AnimationClip: inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - serializedVersion: 3 - time: 0.11666667 - value: {x: 0, y: -0.908, z: 0} + time: 0.41666666 + value: {x: 0, y: -0.254, z: 0} inSlope: {x: 0, y: 0, z: 0} outSlope: {x: 0, y: 0, z: 0} tangentMode: 0 @@ -104,8 +113,8 @@ AnimationClip: inWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} outWeight: {x: 0.33333334, y: 0.33333334, z: 0.33333334} - serializedVersion: 3 - time: 0.11666667 - value: {x: 1, y: 1, z: 1} + time: 0.41666666 + value: {x: 1, y: 0.6493903, z: 1} inSlope: {x: 0, y: 0, z: 0} outSlope: {x: 0, y: 0, z: 0} tangentMode: 0 @@ -126,16 +135,16 @@ AnimationClip: m_ClipBindingConstant: genericBindings: - serializedVersion: 2 - path: 232101919 - attribute: 1 + path: 1022213160 + attribute: 4 script: {fileID: 0} typeID: 4 - customType: 0 + customType: 4 isPPtrCurve: 0 isIntCurve: 0 isSerializeReferenceCurve: 0 - serializedVersion: 2 - path: 1923299162 + path: 232101919 attribute: 1 script: {fileID: 0} typeID: 4 @@ -144,8 +153,8 @@ AnimationClip: isIntCurve: 0 isSerializeReferenceCurve: 0 - serializedVersion: 2 - path: 232101919 - attribute: 3 + path: 1923299162 + attribute: 1 script: {fileID: 0} typeID: 4 customType: 0 @@ -153,8 +162,8 @@ AnimationClip: isIntCurve: 0 isSerializeReferenceCurve: 0 - serializedVersion: 2 - path: 1022213160 - attribute: 1 + path: 232101919 + attribute: 3 script: {fileID: 0} typeID: 4 customType: 0 @@ -167,7 +176,7 @@ AnimationClip: m_AdditiveReferencePoseClip: {fileID: 0} m_AdditiveReferencePoseTime: 0 m_StartTime: 0 - m_StopTime: 0.11666667 + m_StopTime: 0.41666666 m_OrientationOffsetY: 0 m_Level: 0 m_CycleOffset: 0 @@ -197,7 +206,7 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.41666666 value: 0 inSlope: 0 outSlope: 0 @@ -227,8 +236,8 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 - value: 0 + time: 0.41666666 + value: 0.3506 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -257,7 +266,7 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.41666666 value: 0 inSlope: 0 outSlope: 0 @@ -287,7 +296,7 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.41666666 value: 1 inSlope: 0 outSlope: 0 @@ -317,8 +326,8 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 - value: 1 + time: 0.41666666 + value: 0.6493903 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -347,7 +356,7 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.41666666 value: 1 inSlope: 0 outSlope: 0 @@ -377,7 +386,7 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.41666666 value: 0 inSlope: 0 outSlope: 0 @@ -389,7 +398,7 @@ AnimationClip: m_PostInfinity: 2 m_RotationOrder: 4 attribute: m_LocalPosition.x - path: CameraHolder + path: GroundCheck classID: 4 script: {fileID: 0} flags: 0 @@ -399,7 +408,7 @@ AnimationClip: m_Curve: - serializedVersion: 3 time: 0 - value: 0.6359999 + value: -0.254 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -407,8 +416,8 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 - value: 0.6359999 + time: 0.41666666 + value: -0.254 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -419,7 +428,7 @@ AnimationClip: m_PostInfinity: 2 m_RotationOrder: 4 attribute: m_LocalPosition.y - path: CameraHolder + path: GroundCheck classID: 4 script: {fileID: 0} flags: 0 @@ -437,7 +446,7 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.41666666 value: 0 inSlope: 0 outSlope: 0 @@ -449,7 +458,7 @@ AnimationClip: m_PostInfinity: 2 m_RotationOrder: 4 attribute: m_LocalPosition.z - path: CameraHolder + path: GroundCheck classID: 4 script: {fileID: 0} flags: 0 @@ -467,8 +476,17 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 - value: 0 + time: 0.4 + value: 360 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 0.41666666 + value: 360 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -478,18 +496,27 @@ AnimationClip: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - attribute: m_LocalPosition.x - path: GroundCheck + attribute: localEulerAnglesRaw.x + path: CameraHolder classID: 4 script: {fileID: 0} - flags: 0 + flags: 16 - serializedVersion: 2 curve: serializedVersion: 2 m_Curve: - serializedVersion: 3 time: 0 - value: -0.254 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 0.4 + value: 0 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -497,8 +524,8 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 - value: -0.908 + time: 0.41666666 + value: 0 inSlope: 0 outSlope: 0 tangentMode: 136 @@ -508,11 +535,11 @@ AnimationClip: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - attribute: m_LocalPosition.y - path: GroundCheck + attribute: localEulerAnglesRaw.y + path: CameraHolder classID: 4 script: {fileID: 0} - flags: 0 + flags: 16 - serializedVersion: 2 curve: serializedVersion: 2 @@ -527,7 +554,16 @@ AnimationClip: inWeight: 0.33333334 outWeight: 0.33333334 - serializedVersion: 3 - time: 0.11666667 + time: 0.4 + value: 0 + inSlope: 0 + outSlope: 0 + tangentMode: 136 + weightedMode: 0 + inWeight: 0.33333334 + outWeight: 0.33333334 + - serializedVersion: 3 + time: 0.41666666 value: 0 inSlope: 0 outSlope: 0 @@ -538,12 +574,48 @@ AnimationClip: m_PreInfinity: 2 m_PostInfinity: 2 m_RotationOrder: 4 - attribute: m_LocalPosition.z - path: GroundCheck + attribute: localEulerAnglesRaw.z + path: CameraHolder + classID: 4 + script: {fileID: 0} + flags: 16 + m_EulerEditorCurves: + - serializedVersion: 2 + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_LocalEulerAngles.x + path: CameraHolder + classID: 4 + script: {fileID: 0} + flags: 0 + - serializedVersion: 2 + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_LocalEulerAngles.y + path: CameraHolder + classID: 4 + script: {fileID: 0} + flags: 0 + - serializedVersion: 2 + curve: + serializedVersion: 2 + m_Curve: [] + m_PreInfinity: 2 + m_PostInfinity: 2 + m_RotationOrder: 4 + attribute: m_LocalEulerAngles.z + path: CameraHolder classID: 4 script: {fileID: 0} flags: 0 - m_EulerEditorCurves: [] m_HasGenericRootTransform: 0 m_HasMotionFloatCurves: 0 m_Events: [] diff --git a/Assets/Animations/Player/Orientation/AirStandUp.anim.meta b/Assets/Animations/Player/Orientation/Roll.anim.meta similarity index 79% rename from Assets/Animations/Player/Orientation/AirStandUp.anim.meta rename to Assets/Animations/Player/Orientation/Roll.anim.meta index fc31b0f..28d71eb 100644 --- a/Assets/Animations/Player/Orientation/AirStandUp.anim.meta +++ b/Assets/Animations/Player/Orientation/Roll.anim.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f071f11c5d2957a49b02edcb646f9f89 +guid: ab09cca703b69c146acfbb69647b846f NativeFormatImporter: externalObjects: {} mainObjectFileID: 7400000 From 327289a3b52f3dad4630414931abb42744f5c6d0 Mon Sep 17 00:00:00 2001 From: Gabriel Ikezaki Date: Sun, 26 Jul 2026 18:14:37 +0100 Subject: [PATCH 3/4] feat: add roll state and functionality --- .../StateMachine/PlayerAirborneState.cs | 46 +++++++++++++++--- .../StateMachine/PlayerGroundedState.cs | 11 ++++- .../Player/StateMachine/PlayerRollState.cs | 47 +++++++++++++++++++ .../StateMachine/PlayerRollState.cs.meta | 2 + .../Player/StateMachine/PlayerStateFactory.cs | 5 +- .../Player/StateMachine/PlayerStateMachine.cs | 4 ++ 6 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 Assets/Scripts/Player/StateMachine/PlayerRollState.cs create mode 100644 Assets/Scripts/Player/StateMachine/PlayerRollState.cs.meta diff --git a/Assets/Scripts/Player/StateMachine/PlayerAirborneState.cs b/Assets/Scripts/Player/StateMachine/PlayerAirborneState.cs index 5f276d8..e0d88ec 100644 --- a/Assets/Scripts/Player/StateMachine/PlayerAirborneState.cs +++ b/Assets/Scripts/Player/StateMachine/PlayerAirborneState.cs @@ -2,8 +2,13 @@ public class PlayerAirborneState : PlayerBaseState { - float _fallDamageThreshold = -9f; - float _fallDamageMultiplier = 1.0f; + const float MIN_VELOCITY_TO_ROLL = -6f; + const float FALL_DAMAGE_THRESHOLD = -9f; + const float FALL_DAMAGE_MULTIPLIER = 1.0f; + const float ROLL_WINDOW = 0.4f; + const float ROLL_ATTEMPT_RESET_TIME = 0.7f; + + float timeSinceCrouchPressed; GameObject _lastWallRunSurface; // god i fucking hate the name of this variable. public GameObject LastWallRunSurface { get { return _lastWallRunSurface; } set { _lastWallRunSurface = value; } } @@ -13,6 +18,7 @@ public PlayerAirborneState(PlayerStateMachine context, PlayerStateFactory factor isRootState = true; name = "Airborne"; _lastWallRunSurface = null; + timeSinceCrouchPressed = -1; InitializeSubState(); } @@ -23,6 +29,7 @@ public override void EnterState() } public override void UpdateState() { + CheckRollCooldown(); CheckSwitchStates(); } public override void FixedUpdateState() @@ -38,7 +45,7 @@ public override void CheckSwitchStates() { if (_context.Grounded) { - FallDamage(); + OnLanding(); SwitchState(_factory.Grounded()); } } @@ -58,13 +65,38 @@ void LimitSpeed() rb.linearVelocity = new Vector3(xzVelocity.x, rb.linearVelocity.y, xzVelocity.z); } } - void FallDamage() + void CheckRollCooldown() + { + if(_context.PressedCrouch && timeSinceCrouchPressed < 0) + timeSinceCrouchPressed = 0; + + if(timeSinceCrouchPressed >= 0) + timeSinceCrouchPressed += Time.deltaTime; + + if(timeSinceCrouchPressed >= ROLL_ATTEMPT_RESET_TIME) + timeSinceCrouchPressed = -1; + } + void OnLanding() { - if (_context.PlayerRigidBody.linearVelocity.y < _fallDamageThreshold) + float linearVelocityY = _context.PlayerRigidBody.linearVelocity.y; + bool succeededRoll = + _context.IsCrouchPressed + && linearVelocityY < MIN_VELOCITY_TO_ROLL + && timeSinceCrouchPressed > 0 + && timeSinceCrouchPressed <= ROLL_WINDOW; + + if(succeededRoll) { - int damage = Mathf.RoundToInt(Mathf.Abs(_context.PlayerRigidBody.linearVelocity.y) * _fallDamageMultiplier); - _context.TakeDamage(damage); + _context.RollOnGrounded = true; + return; } + if (linearVelocityY < FALL_DAMAGE_THRESHOLD) + FallDamage(); + } + void FallDamage() + { + int damage = Mathf.RoundToInt(Mathf.Abs(_context.PlayerRigidBody.linearVelocity.y) * FALL_DAMAGE_MULTIPLIER); + _context.TakeDamage(damage); } } diff --git a/Assets/Scripts/Player/StateMachine/PlayerGroundedState.cs b/Assets/Scripts/Player/StateMachine/PlayerGroundedState.cs index 74c7900..b3ff69d 100644 --- a/Assets/Scripts/Player/StateMachine/PlayerGroundedState.cs +++ b/Assets/Scripts/Player/StateMachine/PlayerGroundedState.cs @@ -26,7 +26,6 @@ public override void FixedUpdateState() } public override void ExitState() { - _context.OrientationAnimator.SetBool("Sliding", false); currentSubState?.ExitState(); } public override void CheckSwitchStates() @@ -38,7 +37,15 @@ public override void CheckSwitchStates() } public override void InitializeSubState() { - SetSubState(_factory.Move()); + if(_context.RollOnGrounded) + { + SetSubState(_factory.Roll()); + _context.RollOnGrounded = false; + } + else + { + SetSubState(_factory.Move()); + } currentSubState.EnterState(); } diff --git a/Assets/Scripts/Player/StateMachine/PlayerRollState.cs b/Assets/Scripts/Player/StateMachine/PlayerRollState.cs new file mode 100644 index 0000000..ad435be --- /dev/null +++ b/Assets/Scripts/Player/StateMachine/PlayerRollState.cs @@ -0,0 +1,47 @@ +using UnityEngine; + +public class PlayerRollState : PlayerBaseState +{ + float ROLL_SPEED; + float _rollDuration = 0.3f; + public PlayerRollState(PlayerStateMachine context, PlayerStateFactory factory) + : base(context, factory) + { + name = "Roll"; + _context.OrientationAnimator.SetBool("Rolling", true); + _context.CurrentDrag = _context.CrouchDrag; + ROLL_SPEED = _context.GroundSpeed; + } + + public override void EnterState(){} + public override void UpdateState() + { + _rollDuration -= Time.deltaTime; + CheckSwitchStates(); + } + public override void FixedUpdateState() + { + Move(); + } + public override void ExitState() + { + _context.OrientationAnimator.SetBool("Rolling", false); + } + public override void CheckSwitchStates() + { + if (_rollDuration <= 0) + { + SwitchState(_factory.Move()); + } + } + public override void InitializeSubState(){} + + void Move() + { + Transform orientation = _context.PlayerOrientation; + Vector3 directionVector = orientation.forward; + Rigidbody rb = _context.PlayerRigidBody; + + rb.AddForce(directionVector * ROLL_SPEED); + } +} diff --git a/Assets/Scripts/Player/StateMachine/PlayerRollState.cs.meta b/Assets/Scripts/Player/StateMachine/PlayerRollState.cs.meta new file mode 100644 index 0000000..b9aba43 --- /dev/null +++ b/Assets/Scripts/Player/StateMachine/PlayerRollState.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 2b69a6297092711459639f2305436afb \ No newline at end of file diff --git a/Assets/Scripts/Player/StateMachine/PlayerStateFactory.cs b/Assets/Scripts/Player/StateMachine/PlayerStateFactory.cs index 06334d7..efb6d57 100644 --- a/Assets/Scripts/Player/StateMachine/PlayerStateFactory.cs +++ b/Assets/Scripts/Player/StateMachine/PlayerStateFactory.cs @@ -26,7 +26,10 @@ public BaseState Crouch() { return new PlayerCrouchState(_context, this); } - + public BaseState Roll() + { + return new PlayerRollState(_context, this); + } public BaseState Airborne() { return new PlayerAirborneState(_context, this); diff --git a/Assets/Scripts/Player/StateMachine/PlayerStateMachine.cs b/Assets/Scripts/Player/StateMachine/PlayerStateMachine.cs index e0abebc..01d705e 100644 --- a/Assets/Scripts/Player/StateMachine/PlayerStateMachine.cs +++ b/Assets/Scripts/Player/StateMachine/PlayerStateMachine.cs @@ -37,6 +37,8 @@ public class PlayerStateMachine : BaseStateMachine float _initCollisionPosY; float _initCollisionHeight; + bool _rollOnGrounded; + Vector3 _initCameraPos; Rigidbody rb; @@ -59,6 +61,7 @@ public class PlayerStateMachine : BaseStateMachine public bool IsCrouchPressed { get{ return Input.GetKey(KeyCode.LeftControl); } } public bool PressedCrouch { get { return Input.GetKeyDown(KeyCode.LeftControl); } } public bool ReleasedCrouch { get { return Input.GetKeyUp(KeyCode.LeftControl); } } + public bool RollOnGrounded { get { return _rollOnGrounded; } set { _rollOnGrounded = value; } } public float JumpForce { get{ return _jumpForce; } } public float AirMultiplier { get{ return _airMultiplier; } } @@ -111,6 +114,7 @@ void Awake() _initCollisionPosY = collision.center.y; _initCollisionHeight = collision.height; _initCameraPos = cameraTransform.localPosition; + _rollOnGrounded = false; _states = new PlayerStateFactory(this); CurrentState = _states.Grounded(); From 2b0e1b625cd3b698ba7c7390c7445e5c3d0f3541 Mon Sep 17 00:00:00 2001 From: Gabriel Ikezaki Date: Sun, 26 Jul 2026 19:00:50 +0100 Subject: [PATCH 4/4] chore: make roll duration longer, add transition time from roll to standup animation --- .../Animations/Player/Orientation/PlayerOrientation.controller | 2 +- Assets/Scripts/Player/StateMachine/PlayerRollState.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Animations/Player/Orientation/PlayerOrientation.controller b/Assets/Animations/Player/Orientation/PlayerOrientation.controller index 3306616..d212e10 100644 --- a/Assets/Animations/Player/Orientation/PlayerOrientation.controller +++ b/Assets/Animations/Player/Orientation/PlayerOrientation.controller @@ -331,7 +331,7 @@ AnimatorStateTransition: m_Mute: 0 m_IsExit: 0 serializedVersion: 3 - m_TransitionDuration: 0 + m_TransitionDuration: 0.1 m_TransitionOffset: 0 m_ExitTime: 0 m_HasExitTime: 0 diff --git a/Assets/Scripts/Player/StateMachine/PlayerRollState.cs b/Assets/Scripts/Player/StateMachine/PlayerRollState.cs index ad435be..31416d8 100644 --- a/Assets/Scripts/Player/StateMachine/PlayerRollState.cs +++ b/Assets/Scripts/Player/StateMachine/PlayerRollState.cs @@ -3,7 +3,7 @@ public class PlayerRollState : PlayerBaseState { float ROLL_SPEED; - float _rollDuration = 0.3f; + float _rollDuration = .45f; public PlayerRollState(PlayerStateMachine context, PlayerStateFactory factory) : base(context, factory) {