update di chuyển debug jump

This commit is contained in:
2026-05-30 11:20:59 +07:00
parent ee8e633043
commit dfcf8c1c25
26 changed files with 2716 additions and 219 deletions

View File

@@ -127,7 +127,19 @@ namespace OnlyScove.Scripts
public void OnJump(InputAction.CallbackContext context)
{
if (context.performed) OnJumpEvent?.Invoke();
if (context.performed)
{
wasJumpPressed = true;
OnJumpEvent?.Invoke();
}
}
private bool wasJumpPressed;
public bool ConsumeJumpInput()
{
bool val = wasJumpPressed;
wasJumpPressed = false;
return val;
}
public void OnDodgeOrThrust(InputAction.CallbackContext context)

View File

@@ -9,46 +9,153 @@ namespace OnlyScove.Scripts
[SerializeField] private string speedParamName = "Speed";
[SerializeField] private string velocityXParamName = "Velocity X";
[SerializeField] private string velocityZParamName = "Velocity Z";
[SerializeField] private string groundedParamName = "Grounded";
[SerializeField] private float animationDamping = 0.2f;
[Header("Visual Correction")]
[SerializeField] private float visualOffsetY = 0f;
[SerializeField] private Transform modelTransform;
private CharacterController controller;
private Animator anim;
private int speedHash;
private int velocityXHash;
private int velocityZHash;
private bool hasSpeedParam;
private bool hasVelocityXParam;
private bool hasVelocityZParam;
private int groundedHash;
private readonly System.Collections.Generic.HashSet<int> parameterHashes = new System.Collections.Generic.HashSet<int>();
public void Initialize(Animator animator)
{
this.anim = animator;
this.controller = GetComponentInParent<CharacterController>();
// Auto-assign modelTransform if null
if (modelTransform == null && anim != null) modelTransform = anim.transform;
if (anim != null)
{
Debug.Log($"<color=green>[AnimationHandler]</color> Animator found on: {anim.gameObject.name}");
parameterHashes.Clear();
foreach (AnimatorControllerParameter param in anim.parameters)
{
if (param.name == speedParamName) hasSpeedParam = true;
if (param.name == velocityXParamName) hasVelocityXParam = true;
if (param.name == velocityZParamName) hasVelocityZParam = true;
parameterHashes.Add(param.nameHash);
}
int speedHashCheck = Animator.StringToHash(speedParamName);
if (!parameterHashes.Contains(speedHashCheck) && parameterHashes.Contains(Animator.StringToHash("Blend")))
{
speedParamName = "Blend";
speedHash = Animator.StringToHash(speedParamName);
Debug.Log($"<color=yellow>[AnimationHandler]</color> 'Speed' not found, using 'Blend' instead.");
}
}
else
{
Debug.LogError("<color=red>[AnimationHandler]</color> FAILED to find Animator! Please check your Prefab.");
}
speedHash = Animator.StringToHash(speedParamName);
velocityXHash = Animator.StringToHash(velocityXParamName);
velocityZHash = Animator.StringToHash(velocityZParamName);
groundedHash = Animator.StringToHash(groundedParamName);
}
public void UpdateAnimator(float speed, Vector2 moveInput, float deltaTime)
private bool wasGroundedInAnimator;
public void UpdateAnimator(float speed, Vector2 moveInput, bool isGrounded, float deltaTime)
{
if (anim == null) return;
if (hasSpeedParam) anim.SetFloat(speedHash, speed, animationDamping, deltaTime);
if (hasVelocityXParam) anim.SetFloat(velocityXHash, moveInput.x * speed, animationDamping, deltaTime);
if (hasVelocityZParam) anim.SetFloat(velocityZHash, moveInput.y * speed, animationDamping, deltaTime);
// Snap to zero if speed is very low to force Idle
float targetSpeed = speed < 0.05f ? 0f : speed;
float damping = (targetSpeed == 0f || targetSpeed > 0.9f) ? 0f : animationDamping;
if (parameterHashes.Contains(speedHash)) anim.SetFloat(speedHash, targetSpeed, damping, deltaTime);
if (parameterHashes.Contains(velocityXHash)) anim.SetFloat(velocityXHash, moveInput.x * targetSpeed, damping, deltaTime);
if (parameterHashes.Contains(velocityZHash)) anim.SetFloat(velocityZHash, moveInput.y * targetSpeed, damping, deltaTime);
// Quan trọng: Cập nhật biến Grounded cho Animator
if (parameterHashes.Contains(groundedHash)) anim.SetBool(groundedHash, isGrounded);
// Nếu đang ở trên mặt đất, đảm bảo reset các trạng thái nhảy/rơi
if (isGrounded)
{
SafeSetBool("IsJumping", false);
SafeSetBool("IsFalling", false);
var stateInfo = anim.GetCurrentAnimatorStateInfo(0);
if (stateInfo.IsName("Jump") || stateInfo.IsName("Fall") || stateInfo.IsName("Airborne"))
{
anim.CrossFadeInFixedTime("Locomotion Ground", 0.1f);
}
}
wasGroundedInAnimator = isGrounded;
}
public void SafeSetTrigger(string name)
{
if (anim == null) return;
int hash = Animator.StringToHash(name);
if (parameterHashes.Contains(hash)) anim.SetTrigger(hash);
}
public void SafeSetTrigger(int hash)
{
if (anim == null) return;
if (parameterHashes.Contains(hash)) anim.SetTrigger(hash);
}
public void SafeResetTrigger(string name)
{
if (anim == null) return;
int hash = Animator.StringToHash(name);
if (parameterHashes.Contains(hash)) anim.ResetTrigger(hash);
}
public void SafeResetTrigger(int hash)
{
if (anim == null) return;
if (parameterHashes.Contains(hash)) anim.ResetTrigger(hash);
}
public void SafeSetBool(string name, bool value)
{
if (anim == null) return;
int hash = Animator.StringToHash(name);
if (parameterHashes.Contains(hash)) anim.SetBool(hash, value);
}
public void SafeSetFloat(int hash, float value, float dampTime, float deltaTime)
{
if (anim == null) return;
if (parameterHashes.Contains(hash)) anim.SetFloat(hash, value, dampTime, deltaTime);
}
public void SetSpeed(float speed)
{
if (anim != null && hasSpeedParam) anim.SetFloat(speedHash, speed);
if (anim != null && parameterHashes.Contains(speedHash))
anim.SetFloat(speedHash, speed);
}
public void ForceLocomotion()
{
if (anim != null) anim.CrossFadeInFixedTime("Locomotion Ground", 0.1f);
}
private void LateUpdate()
{
if (modelTransform != null && controller != null)
{
// Automatically snap mesh to the bottom of the CharacterController capsule
// This fixes hovering/tiptoeing issues regardless of animation offsets
Vector3 targetPos = modelTransform.localPosition;
float bottomY = controller.center.y - (controller.height / 2f);
targetPos.y = bottomY + visualOffsetY;
modelTransform.localPosition = targetPos;
}
}
}
}

View File

@@ -15,8 +15,8 @@ namespace OnlyScove.Scripts
{
dashTimer = dashDuration;
// Fire the Dash animation trigger
stateMachine.Anim.SetTrigger(dashHash);
// Safely fire the Dash animation trigger
stateMachine.AnimationHandler.SafeSetTrigger(dashHash);
stateMachine.Input.OnJumpEvent += OnJump;

View File

@@ -14,7 +14,7 @@ namespace OnlyScove.Scripts
public override void Enter()
{
dodgeTimer = dodgeDuration;
stateMachine.Anim.SetTrigger(dodgeHash);
stateMachine.AnimationHandler.SafeSetTrigger(dodgeHash);
Vector2 input = stateMachine.MoveInput;
if (input != Vector2.zero)

View File

@@ -25,7 +25,7 @@ namespace OnlyScove.Scripts
public override void Enter()
{
stateMachine.Anim.SetTrigger(fallHash);
stateMachine.AnimationHandler.SafeSetTrigger(fallHash);
stateMachine.Input.OnDodgeEvent += OnThrustPressed;
stateMachine.Input.OnSprintEvent += OnAirDash;
}
@@ -50,6 +50,12 @@ namespace OnlyScove.Scripts
if (stateMachine.IsGrounded)
{
// Landing Reset Animator
stateMachine.AnimationHandler.SafeSetBool("IsJumping", false);
stateMachine.AnimationHandler.SafeSetBool("IsFalling", false);
stateMachine.AnimationHandler.SafeResetTrigger("Jump");
stateMachine.AnimationHandler.SafeResetTrigger("Fall");
// Landing Shake
if (!stateMachine.WasGrounded && stateMachine.VelocityY < -1f)
{

View File

@@ -4,27 +4,21 @@ namespace OnlyScove.Scripts
{
public class PlayerIdleState : PlayerBaseState
{
private readonly int speedHash = Animator.StringToHash("Speed");
public PlayerIdleState(PlayerStateMachine stateMachine) : base(stateMachine) {}
public override void Enter()
{
// Tạm thời bỏ ResetTrigger nếu chúng không tồn tại trong Animator của bạn
// stateMachine.Anim.ResetTrigger("Jump");
// stateMachine.Anim.ResetTrigger("Fall");
stateMachine.AnimationHandler.SafeResetTrigger("Jump");
stateMachine.AnimationHandler.SafeResetTrigger("Fall");
stateMachine.AnimationHandler.ForceLocomotion();
stateMachine.Input.OnJumpEvent += OnJump;
stateMachine.Input.OnDodgeEvent += OnDodge;
stateMachine.Input.OnCrouchEvent += OnCrouch;
stateMachine.Input.OnInteractEvent += OnInteract;
}
private readonly int speedXHash = Animator.StringToHash("Velocity X");
private readonly int speedZHash = Animator.StringToHash("Velocity Z");
public override void Tick(float deltaTime)
{
// Cập nhật trọng lực
if (stateMachine.IsGrounded && stateMachine.VelocityY < 0)
{
stateMachine.VelocityY = -2f;
@@ -34,14 +28,11 @@ namespace OnlyScove.Scripts
stateMachine.VelocityY += stateMachine.Gravity * deltaTime;
}
// Sử dụng hàm Move tập trung để đồng bộ Animator và Vị trí
stateMachine.Move(new Vector3(0, stateMachine.VelocityY, 0), 0f, deltaTime);
// QUAN TRỌNG: Đọc dữ liệu đã đồng bộ từ mạng (stateMachine.MoveInput)
if (stateMachine.MoveInput != Vector2.zero)
{
stateMachine.SwitchState(new PlayerMoveState(stateMachine));
return;
}
}
@@ -49,28 +40,11 @@ namespace OnlyScove.Scripts
public override void Exit()
{
stateMachine.Input.OnJumpEvent -= OnJump;
stateMachine.Input.OnDodgeEvent -= OnDodge;
stateMachine.Input.OnCrouchEvent -= OnCrouch;
stateMachine.Input.OnInteractEvent -= OnInteract;
}
private void OnJump()
{
if (stateMachine.IsGrounded)
{
if (stateMachine.Scanner != null)
{
var hitData = stateMachine.Scanner.ObstacleCheck();
if (hitData.forwardHitFound)
{
stateMachine.SwitchState(new PlayerParkourState(stateMachine));
return;
}
}
stateMachine.SwitchState(new PlayerJumpState(stateMachine, stateMachine.WalkSpeed));
}
}
private void OnDodge() => stateMachine.SwitchState(new PlayerDodgeState(stateMachine));
private void OnCrouch() => stateMachine.SwitchState(new PlayerCrouchState(stateMachine));
private void OnInteract() => stateMachine.SwitchState(new PlayerInteractState(stateMachine));

View File

@@ -25,14 +25,14 @@ namespace OnlyScove.Scripts
public override void Enter()
{
// Sử dụng dữ liệu đồng bộ
Vector2 input = stateMachine.MoveInput;
Debug.Log("<color=yellow>[PlayerJumpState]</color> Entered Jump State");
stateMachine.Anim.ResetTrigger(jumpHash);
stateMachine.Anim.SetTrigger(jumpHash);
stateMachine.AnimationHandler.SafeResetTrigger(jumpHash);
stateMachine.AnimationHandler.SafeSetTrigger(jumpHash);
stateMachine.AnimationHandler.SafeSetBool("IsJumping", true);
// Physic formula: v = sqrt(h * -2 * g)
stateMachine.VelocityY = Mathf.Sqrt(stateMachine.JumpHeight * -2f * stateMachine.Gravity);
// Sử dụng hàm Jump tập trung để đồng bộ vật lý và cooldown
stateMachine.Movement.Jump();
stateMachine.Input.OnSprintEvent += OnAirDash;
}

View File

@@ -4,23 +4,21 @@ namespace OnlyScove.Scripts
{
public class PlayerMoveState : PlayerBaseState
{
private readonly int speedHash = Animator.StringToHash("Speed");
public PlayerMoveState(PlayerStateMachine stateMachine) : base(stateMachine) {}
public override void Enter()
{
stateMachine.Input.OnJumpEvent += OnJump;
stateMachine.AnimationHandler.SafeResetTrigger("Jump");
stateMachine.AnimationHandler.SafeResetTrigger("Fall");
stateMachine.AnimationHandler.ForceLocomotion();
stateMachine.Input.OnDodgeEvent += OnDodge;
stateMachine.Input.OnCrouchEvent += OnCrouch;
stateMachine.Input.OnInteractEvent += OnInteract;
}
private readonly int speedXHash = Animator.StringToHash("Velocity X");
private readonly int speedZHash = Animator.StringToHash("Velocity Z");
public override void Tick(float deltaTime)
{
// QUAN TRỌNG: Đọc trực tiếp từ stateMachine (Dữ liệu đã đồng bộ mạng)
Vector2 input = stateMachine.MoveInput;
float moveAmount = Mathf.Clamp01(Mathf.Abs(input.x) + Mathf.Abs(input.y));
@@ -53,7 +51,6 @@ namespace OnlyScove.Scripts
}
velocity.y = stateMachine.VelocityY;
// Sử dụng hàm Move tập trung (0.7f là giá trị Speed cho Animator khi đi bộ)
stateMachine.Move(velocity, 0.7f, deltaTime);
stateMachine.Rotate(moveDirection, deltaTime);
}
@@ -62,29 +59,11 @@ namespace OnlyScove.Scripts
public override void Exit()
{
stateMachine.Input.OnJumpEvent -= OnJump;
stateMachine.Input.OnDodgeEvent -= OnDodge;
stateMachine.Input.OnCrouchEvent -= OnCrouch;
stateMachine.Input.OnInteractEvent -= OnInteract;
}
private void OnJump()
{
if (stateMachine.IsGrounded)
{
if (stateMachine.Scanner != null)
{
var hitData = stateMachine.Scanner.ObstacleCheck();
if (hitData.forwardHitFound)
{
stateMachine.SwitchState(new PlayerParkourState(stateMachine));
return;
}
}
stateMachine.SwitchState(new PlayerJumpState(stateMachine, stateMachine.WalkSpeed));
}
}
private void OnDodge() => stateMachine.SwitchState(new PlayerDodgeState(stateMachine));
private void OnCrouch() => stateMachine.SwitchState(new PlayerCrouchState(stateMachine));
private void OnInteract() => stateMachine.SwitchState(new PlayerInteractState(stateMachine));

View File

@@ -22,25 +22,86 @@ namespace OnlyScove.Scripts
[field: SerializeField] public float GroundCheckRadius { get; private set; } = 0.2f;
[field: SerializeField] public Vector3 GroundCheckOffset { get; private set; }
[field: SerializeField] public LayerMask GroundMask { get; private set; }
// Networked shadow properties
[Networked] private NetworkBool _isGroundedNet { get; set; }
[Networked] private NetworkBool _wasGroundedNet { get; set; }
[Networked] private float _velocityYNet { get; set; }
[Networked] public Vector3 NetworkedPosition { get; set; }
[Networked] public bool IsGrounded { get; set; }
[Networked] public bool WasGrounded { get; set; }
[Networked] public float VelocityY { get; set; }
[Networked] public Vector3 NetworkedPosition { get; set; }
// Local backing fields for Offline mode
private bool _isGroundedLocal;
private bool _wasGroundedLocal;
private float _velocityYLocal;
private CharacterController controller;
// Public wrappers that handle both Online and Offline
public bool IsGrounded
{
get => (Object != null && Object.IsValid) ? (bool)_isGroundedNet : _isGroundedLocal;
set { if (Object != null && Object.IsValid) _isGroundedNet = value; _isGroundedLocal = value; }
}
public void Initialize(CharacterController controller)
public bool WasGrounded
{
get => (Object != null && Object.IsValid) ? (bool)_wasGroundedNet : _wasGroundedLocal;
set { if (Object != null && Object.IsValid) _wasGroundedNet = value; _wasGroundedLocal = value; }
}
public float VelocityY
{
get => (Object != null && Object.IsValid) ? _velocityYNet : _velocityYLocal;
set { if (Object != null && Object.IsValid) _velocityYNet = value; _velocityYLocal = value; }
}
private CharacterController controller;
private float jumpCooldown = 0f;
public void Initialize(CharacterController controller)
{
this.controller = controller;
_isGroundedLocal = true; // Safe local initialization
}
public override void Spawned()
{
// Initialize networked state once spawned (only on State Authority)
if (Object.HasStateAuthority)
{
_isGroundedNet = true;
_wasGroundedNet = true;
_velocityYNet = 0f;
}
}
public void CheckGround(Transform playerTransform, float deltaTime)
{
this.controller = controller;
}
public void CheckGround(Transform playerTransform)
{
if (Object == null || (!Object.HasStateAuthority && !Object.HasInputAuthority)) return;
if (jumpCooldown > 0)
{
jumpCooldown -= deltaTime;
WasGrounded = IsGrounded;
IsGrounded = false;
return;
}
WasGrounded = IsGrounded;
IsGrounded = Physics.CheckSphere(playerTransform.TransformPoint(GroundCheckOffset), GroundCheckRadius, GroundMask);
bool sphereCheck = Physics.CheckSphere(playerTransform.TransformPoint(GroundCheckOffset), GroundCheckRadius, GroundMask);
bool ccCheck = (controller != null) && controller.isGrounded;
IsGrounded = sphereCheck || ccCheck;
if (Object != null && Object.IsValid && Object.HasStateAuthority)
{
// State authority updates the networked position for reconciliation
NetworkedPosition = playerTransform.position;
}
}
public void Jump()
{
// Physic formula: v = sqrt(h * -2 * g)
VelocityY = Mathf.Sqrt(JumpHeight * -2f * Gravity);
IsGrounded = false;
jumpCooldown = 0.15f; // Ngăn không cho dính đất trong 0.15s đầu
}
public void Move(CharacterController controller, Vector3 velocity, float deltaTime)
@@ -48,10 +109,6 @@ namespace OnlyScove.Scripts
if (controller != null && controller.enabled)
{
controller.Move(velocity * deltaTime);
if (Object != null && Object.HasStateAuthority)
{
NetworkedPosition = transform.position;
}
}
}

View File

@@ -12,6 +12,7 @@ namespace OnlyScove.Scripts
public override void Enter()
{
Debug.Log("<color=orange>[PlayerParkourState]</color> Entered Parkour State");
if (stateMachine.Anim != null && stateMachine.Anim.layerCount > 0)
{
// Play the Parkour animation (Step Up)

View File

@@ -4,22 +4,20 @@ namespace OnlyScove.Scripts
{
public class PlayerRunState : PlayerBaseState
{
private readonly int speedHash = Animator.StringToHash("Speed");
private readonly int speedXHash = Animator.StringToHash("Velocity X");
private readonly int speedZHash = Animator.StringToHash("Velocity Z");
public PlayerRunState(PlayerStateMachine stateMachine) : base(stateMachine) {}
public override void Enter()
{
stateMachine.Input.OnJumpEvent += OnJump;
stateMachine.AnimationHandler.SafeResetTrigger("Jump");
stateMachine.AnimationHandler.SafeResetTrigger("Fall");
stateMachine.AnimationHandler.ForceLocomotion();
stateMachine.Input.OnDodgeEvent += OnDodge;
stateMachine.Input.OnCrouchEvent += OnCrouch;
}
public override void Tick(float deltaTime)
{
// ĐÚNG: Sử dụng dữ liệu đã đồng bộ qua mạng
Vector2 input = stateMachine.MoveInput;
float moveAmount = Mathf.Clamp01(Mathf.Abs(input.x) + Mathf.Abs(input.y));
@@ -52,7 +50,6 @@ namespace OnlyScove.Scripts
}
velocity.y = stateMachine.VelocityY;
// Sử dụng hàm Move tập trung (1.0f là giá trị Speed cho Animator khi chạy)
stateMachine.Move(velocity, 1.0f, deltaTime);
stateMachine.Rotate(moveDirection, deltaTime);
}
@@ -61,28 +58,10 @@ namespace OnlyScove.Scripts
public override void Exit()
{
stateMachine.Input.OnJumpEvent -= OnJump;
stateMachine.Input.OnDodgeEvent -= OnDodge;
stateMachine.Input.OnCrouchEvent -= OnCrouch;
}
private void OnJump()
{
if (stateMachine.IsGrounded)
{
if (stateMachine.Scanner != null)
{
var hitData = stateMachine.Scanner.ObstacleCheck();
if (hitData.forwardHitFound)
{
stateMachine.SwitchState(new PlayerParkourState(stateMachine));
return;
}
}
stateMachine.SwitchState(new PlayerJumpState(stateMachine, stateMachine.SprintSpeed));
}
}
private void OnDodge() => stateMachine.SwitchState(new PlayerDodgeState(stateMachine));
private void OnCrouch() => stateMachine.SwitchState(new PlayerCrouchState(stateMachine));
}

View File

@@ -32,12 +32,12 @@ namespace OnlyScove.Scripts
public float VelocityY
{
get => (Object != null && Object.IsValid && Movement != null) ? Movement.VelocityY : 0f;
set { if (Object != null && Object.IsValid && Movement != null) Movement.VelocityY = value; }
get => (Movement != null) ? Movement.VelocityY : 0f;
set { if (Movement != null) Movement.VelocityY = value; }
}
public bool IsGrounded => (Object != null && Object.IsValid && Movement != null) ? Movement.IsGrounded : true;
public bool WasGrounded => (Object != null && Object.IsValid && Movement != null) ? Movement.WasGrounded : true;
public bool IsGrounded => (Movement != null) ? Movement.IsGrounded : true;
public bool WasGrounded => (Movement != null) ? Movement.WasGrounded : true;
public float WalkSpeed => Movement.WalkSpeed;
public float RunSpeed => Movement.RunSpeed;
@@ -106,6 +106,7 @@ namespace OnlyScove.Scripts
if (isOffline || (Object != null && Object.HasInputAuthority))
{
Local = this;
CameraController cameraController = GameObject.FindAnyObjectByType<CameraController>();
if (cameraController != null)
{
@@ -161,7 +162,9 @@ namespace OnlyScove.Scripts
bool isNetworked = Runner != null && Runner.IsRunning && Object != null && Object.IsValid;
float speedValue = (!isNetworked || Object.HasInputAuthority) ? localAnimatorSpeed : NetworkedSpeed;
Vector2 inputVector = (!isNetworked || Object.HasInputAuthority) ? MoveInput : NetworkedMoveInput;
AnimationHandler.UpdateAnimator(speedValue, inputVector, deltaTime);
// Pass IsGrounded to handle air/ground transitions
AnimationHandler.UpdateAnimator(speedValue, inputVector, IsGrounded, deltaTime);
}
public override void FixedUpdateNetwork()
@@ -169,38 +172,64 @@ namespace OnlyScove.Scripts
bool isRunning = Runner != null && Runner.IsRunning;
if (isRunning && (Object == null || !Object.IsValid)) return;
float deltaTime = isRunning ? Runner.DeltaTime : Time.fixedDeltaTime;
if (GetInput(out PlayerInputData data))
{
MoveInput = data.Direction;
IsSprintHeld = (bool)data.sprint;
if (isRunning) NetworkedCameraRotation = data.rot;
if (data.jump) TriggerJump();
}
else if (!isRunning)
{
MoveInput = new Vector2(UnityEngine.Input.GetAxisRaw("Horizontal"), UnityEngine.Input.GetAxisRaw("Vertical"));
IsSprintHeld = UnityEngine.Input.GetKey(KeyCode.LeftShift);
if (Input.ConsumeJumpInput()) TriggerJump();
}
if (!isRunning || (Object != null && Object.IsValid && (Object.HasInputAuthority || Runner.IsServer)))
{
if (hasControl)
{
Movement.CheckGround(transform);
Movement.CheckGround(transform, deltaTime);
Interaction.UpdateInteractables();
currentState?.Tick(isRunning ? Runner.DeltaTime : Time.fixedDeltaTime);
currentState?.Tick(deltaTime);
}
}
}
public void TriggerJump()
{
if (!IsGrounded) return;
if (Scanner != null)
{
var hitData = Scanner.ObstacleCheck();
if (hitData.forwardHitFound && hitData.heightHitFound)
{
SwitchState(new PlayerParkourState(this));
return;
}
}
float jumpMoveSpeed = (IsSprintHeld) ? Movement.SprintSpeed : Movement.WalkSpeed;
SwitchState(new PlayerJumpState(this, jumpMoveSpeed));
}
public override void Render()
{
bool isRunning = Runner != null && Runner.IsRunning;
if (isRunning && Object != null && Object.IsValid && !Object.HasInputAuthority)
if (isRunning && Object != null && Object.IsValid)
{
// Smooth interpolation for proxies
if (Movement.NetworkedPosition != Vector3.zero)
if (!Object.HasInputAuthority)
{
transform.position = Vector3.Lerp(transform.position, Movement.NetworkedPosition, Runner.DeltaTime * 15f);
// Proxies
if (Movement.NetworkedPosition != Vector3.zero)
{
transform.position = Vector3.Lerp(transform.position, Movement.NetworkedPosition, Runner.DeltaTime * 20f);
}
}
UpdateAnimator(Runner.DeltaTime);
}

View File

@@ -10,7 +10,7 @@ namespace OnlyScove.Scripts
public override void Enter()
{
stateMachine.Anim.SetTrigger(thrustHash);
stateMachine.AnimationHandler.SafeSetTrigger(thrustHash);
// Immediately set a massive downward velocity
stateMachine.VelocityY = stateMachine.ThrustDownwardForce;