using System; using DG.Tweening; using SLSUtilities.General; using UnityEngine; using UnityEngine.AI; namespace Cielonos.MainGame.Characters { public partial class LandMovementSubcontroller : MovementSubcontrollerBase { protected AnimationSubcontrollerBase animationSc => owner.animationSc; protected Animator animator => animationSc.animator; protected virtual void OnAnimatorMove() { movementModifier = Vector3.zero; if (owner.animationSc.isDuringRootMotion) { UpdateRootMotionMovement(); } else { UpdateRegularMovement(); } ApplyGravity(); UpdateFinalMovement(); } protected virtual void Update() { isOnGround = groundDetector.DetectGround(); } } public partial class LandMovementSubcontroller { /// /// 如果角色当前在空中,强制其落地。 /// public void ForceLanding() { if(isOnGround) return; if (groundDetector.GetGroundPosition(out Vector3 landingPosition)) { jumpVelocity = 0; gravitationalMovement = Vector3.zero; if (owner.collisionSc.useCharacterController) { owner.collisionSc.characterController.enabled = false; owner.transform.position = landingPosition + new Vector3(0, groundDetector.groundedOffset + 0.1f, 0); owner.collisionSc.characterController.enabled = true; } else { owner.collisionSc.mainRigidbody.position = landingPosition + new Vector3(0, groundDetector.groundedOffset + 0.1f, 0); } } } } public partial class LandMovementSubcontroller { void UpdateRootMotionMovement() { Quaternion originalDeltaRotation = animator.deltaRotation; characterTransform.rotation *= originalDeltaRotation; Vector3 originalDeltaPosition = animator.deltaPosition; Vector3 localDeltaPosition = characterTransform.InverseTransformDirection(originalDeltaPosition); Vector3 adjustedLocalDeltaPosition = new Vector3( localDeltaPosition.x * rootMotionMoveXMultiplier, localDeltaPosition.y, localDeltaPosition.z * rootMotionMoveZMultiplier); Vector3 adjustedDeltaPosition = characterTransform.TransformDirection(adjustedLocalDeltaPosition); if (isDashing || isDodging) { Vector3 deltaPosition = adjustedLocalDeltaPosition; deltaPosition.z *= isDashing ? dashMoveMultiplier : dodgeMoveMultiplier; horizontalMovement = characterTransform.TransformDirection(deltaPosition); } else { horizontalMovement = adjustedDeltaPosition; } verticalMovement = new Vector3(0, animator.deltaPosition.y * rootMotionMoveYMultiplier, 0); if ( /*!player.statusModule.CanMove ||*/ animationSc.isDisablingMoveXZ) { horizontalMovement = Vector3.zero; } if (animationSc.isDisablingMoveY) { verticalMovement = Vector3.zero; } } private void UpdateRegularMovement() { horizontalMovement = targetDirection.normalized * (moveSpeed * DeltaTime); verticalMovement = Vector3.zero; } protected virtual void ApplyGravity() { if (!isApplyingGravity) { currentGravity = Vector3.zero; gravitationalMovement = Vector3.zero; return; } if (groundDetector.isOnGround) { currentGravity = Vector3.zero; gravitationalMovement = Vector3.zero; movementModifier += Vector3.down * DeltaTime; return; } currentGravity = normalGravity * Vector3.down * DeltaTime; gravitationalMovement += currentGravity * DeltaTime; } protected virtual void UpdateFinalMovement() { horizontalMovement.y = 0; verticalMovement.x = 0; verticalMovement.z = 0; initiativeMovementVelocity = horizontalMovement + (verticalMovement * verticalMoveMultiplier); Vector3 jumpMove = new Vector3(0, jumpVelocity * DeltaTime, 0); additionalForceSm.Update(owner.attributeSm["ImpactResistance"]); Vector3 forceMove = additionalForceSm.additionalForceXZ.currentValue * DeltaTime + additionalForceSm.additionalForceY.currentValue * verticalMoveMultiplier * Vector3.up * DeltaTime; finalMovementVelocity = initiativeMovementVelocity + gravitationalMovement * verticalMoveMultiplier * gravityMultiplier + forceMove + jumpMove * verticalMoveMultiplier; /*bool isHorizontalMoving = horizontalMovement.magnitude > 0.1f * DeltaTime; animator.SetBool(Animator.StringToHash("IsHorizontalMoving"), isHorizontalMoving);*/ } protected virtual void InitiativeMove() { if (owner.collisionSc.useCharacterController) { owner.collisionSc.characterController.Move(finalMovementVelocity + movementModifier); } else { Vector3 startPosition = owner.collisionSc.mainRigidbody.position; owner.collisionSc.mainRigidbody.MovePosition(startPosition + finalMovementVelocity + movementModifier); } } } public partial class LandMovementSubcontroller { private void OnDrawGizmos() { float groundedOffset = groundDetector?.groundedOffset ?? 0.05f; float groundedRadius = groundDetector?.groundedLength ?? 0.1f; float predictDistance = -character.movementSc.finalMovementVelocity.y; float adjustedRadius = groundedRadius + Mathf.Max(0, predictDistance); Gizmos.color = Color.red; Gizmos.DrawWireSphere(transform.position - new Vector3(0, groundedOffset, 0), adjustedRadius); } } }