using System; using DG.Tweening; using SLSUtilities.General; using SLSUtilities.FunctionalAnimation; using UniRx; using UnityEngine; namespace Cielonos.MainGame.Characters { public partial class PlayerLandMovementSubcontroller : LandMovementSubcontroller { public Player player => owner as Player; private PlayerAnimationSubcontroller animationSc => base.animationSc as PlayerAnimationSubcontroller; protected override void OnAnimatorMove() { if (DeltaTime == 0) { return; } Rotate(); Move(); Jump(); base.OnAnimatorMove(); InitiativeMove(); } public void TurnToInputDirection(Vector3 direction, float duration = 0f) { Vector3 dashRotation = Vector3.zero; float angle = Vector3.SignedAngle(Vector3.forward, direction, Vector3.up); if (owner is Player player) { dashRotation.y = player.viewSc.playerCamera.transform.eulerAngles.y + angle; } else { dashRotation = new Vector3(0, angle, 0); } if (duration > 0) { characterTransform.DORotateQuaternion(Quaternion.Euler(dashRotation), duration).Play(); } else { characterTransform.rotation = Quaternion.Euler(dashRotation); } } } public partial class PlayerLandMovementSubcontroller { void Rotate() { if (animationSc.isDuringRootMotion) return; Vector3 inputDirection = new Vector3(player.inputSc.Move.x, 0.0f, player.inputSc.Move.y).normalized; if (player.inputSc.IsMoving) { targetRotation = Mathf.Atan2(inputDirection.x, inputDirection.z) * Mathf.Rad2Deg + player.viewSc.playerCamera.transform.eulerAngles.y; if (rotationType == CharacterRotationType.ByMovement && canRotate.Value) { float rotation = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetRotation, ref rotationVelocity, rotationSmoothTime); player.transform.rotation = Quaternion.Euler(0.0f, rotation, 0.0f); } } targetDirection = Quaternion.Euler(0.0f, targetRotation, 0.0f) * Vector3.forward; } void Move() { if (!canMove.Value) { moveSpeed = 0; return; } float targetSpeed = player.attributeSm.GetAttribute(CharacterAttribute.MovementSpeed, 10f) * (isSprinting ? sprintSpeedMultiplier : 1f); float movementAnimationSpeedMultiplier = !player.inputSc.IsWalking && targetSpeed > 10f ? targetSpeed / 10f : 1; float inputMagnitude = player.inputSc.Move.magnitude; moveAcceleration = player.attributeSm.GetAttribute("MoveAcceleration", 6); moveDeceleration = player.attributeSm.GetAttribute("MoveDeceleration", 8); if (player.inputSc.IsMoving) { bool success = animationSc.fullBodyFuncAnimSm.Stop(DisruptionType.Movement, 0.25f); if (!success && animationSc.isDuringRootMotion) { if (!isDashing) { moveSpeed = Mathf.Lerp(moveSpeed, 0, DeltaTime * moveDeceleration); } return; } } else { isSprinting = false; } animator.SetFloat("MoveSpeedMultiplier", movementAnimationSpeedMultiplier); if (!isRushStopping && !isJumpLanding && player.inputSc.IsMoving) { float finalTargetSpeed = !player.inputSc.IsWalking ? targetSpeed * inputMagnitude : 2f; finalTargetSpeed = Mathf.Max(finalTargetSpeed, 1); moveSpeed = Mathf.Lerp(moveSpeed, finalTargetSpeed, DeltaTime * moveAcceleration); } else if (!isDashing) { moveSpeed = Mathf.Lerp(moveSpeed, 0, DeltaTime * moveDeceleration); } /*if (MotionController.characterRotationType == PlayerMotionController.CharacterRotationType.ByAiming) { mx = Mathf.Lerp(mx, Player.inputController.InputMoveValue.x, DeltaTime * movementSpeedAccelerationRate); my = Mathf.Lerp(my, Player.inputController.InputMoveValue.y, DeltaTime * movementSpeedAccelerationRate); Player.animator.SetFloat("MovementSpeedX", mx * movementSpeed); Player.animator.SetFloat("MovementSpeedZ", my * movementSpeed); } else */ { animator.SetFloat("MoveSpeedZ", moveSpeed); } if (moveSpeed > 5f * DeltaTime && player.inputSc.IsMoving) { runningTime += DeltaTime; } else { runningTime = 0; } } private void Jump() { if (player.inputSc.JumpPressed && animationSc.fullBodyFuncAnimSm.Stop(DisruptionType.NormalAction)) { if (!isJumping) { FirstJump(); } else { ExtraJump(-1, true); } } if (isJumping) { jumpTime += DeltaTime; if (jumpVelocity > 0) { jumpVelocity -= jumpGravity * DeltaTime; } else { jumpVelocity = 0f; gravitationalMovement += new Vector3(0, -jumpGravity * gravityMultiplier * DeltaTime, 0) * DeltaTime; } if (jumpTime > 0.1f) { if (jumpTime > 1f && groundDetector.DetectGround(4f, 1f)) { jumpVelocity = 0f; animationSc.grounderFBBIK.weight = 1; isJumping = false; movementModifier = Vector3.zero; animator.SetBool("IsLandingOnGround", true); animator.SetTrigger("LandFromHighAltitude"); isJumpLanding = true; Observable.Timer(TimeSpan.FromSeconds(0.4f)).Subscribe(_ => { isJumpLanding = false; }); return; } if(groundDetector.isOnGround || groundDetector.DetectGround()) { jumpVelocity = 0f; animationSc.grounderFBBIK.weight = 1; animator.SetBool("IsLandingOnGround", true); isJumping = false; movementModifier = Vector3.zero; } } } } public void FirstJump() { if(isStartJumping || isJumping || !groundDetector.isOnGround) { return; } animator.SetTrigger("Jump"); (animationSc as PlayerAnimationSubcontroller).grounderFBBIK.weight = 0; isStartJumping = true; player.eventSm.onFirstJump.Invoke(); player.selfTimeSm.AddLocalTimer(0.16f, () => { jumpVelocity = jumpForce; isStartJumping = false; isJumping = true; jumpTime = 0; jumpHeldTime = 0; gravitationalMovement = Vector3.zero; animator.SetBool("IsLandingOnGround", false); }); } public void ExtraJump(float overrideForce = -1, bool hasAnimation = false, bool isAdditive = true) { if (!isAdditive) { jumpVelocity = overrideForce > 0 ? overrideForce : jumpForce; } else { jumpVelocity += overrideForce > 0 ? overrideForce : jumpForce; } isJumping = true; gravitationalMovement = Vector3.zero; } protected override void UpdateFinalMovement() { base.UpdateFinalMovement(); float horizontalSpeed = horizontalMovement.magnitude / DeltaTime; float remapFactor = Mathf.InverseLerp(10f, 15f, horizontalSpeed); PostProcessingManager.Instance.speedLinesSm.SetRemap(1 - remapFactor); } } }