using DG.Tweening; using Sirenix.OdinInspector; using SLSUtilities.General; using UnityEngine; using UnityEngine.Serialization; namespace Cielonos.MainGame.Characters { public partial class MovementSubcontrollerBase : SubcontrollerBase { protected CharacterBase character => owner; protected float DeltaTime => owner.selfTimeSm.DeltaTime; [Tooltip("角色旋转方式,ByMovement为ARPG式默认移动旋转,ByAiming为八向移动")] public CharacterRotationType rotationType; public AdditionalForceSubmodule additionalForceSm; [HideInEditorMode] public Transform characterTransform; public override void Initialize() { base.Initialize(); additionalForceSm ??= new AdditionalForceSubmodule(this); canMove = new CompoundBool(true); canRotate = new CompoundBool(true); canDash = true; canDodge = true; canJump = true; maxJumpCount = 1; isApplyingGravity = true; characterTransform = character.transform; if (owner is Player) { var groundMasks = LayerMask.GetMask("Default", "Enemy", "Wall", "Ground", "FadableEnvironment", "UnfadableEnvironment"); groundDetector ??= new GroundDetector(owner, 0.1f, 0.1f, 0.05f, groundMasks); } else { groundDetector ??= new GroundDetector(owner, 0.1f, 0.1f, 0.05f, LayerMask.GetMask("Default", "Wall", "Ground", "FadableEnvironment", "UnfadableEnvironment")); } } public void TurnToTarget(CharacterBase target, float duration = 0.2f) { characterTransform.DOLookAt(target.transform.position, duration, AxisConstraint.Y).Play(); } public void TurnToDirection(Vector3 direction, float duration = 0f) { Vector3 targetDirection = direction.Flatten(); if (targetDirection == Vector3.zero) return; Quaternion targetRotation = Quaternion.LookRotation(targetDirection); characterTransform.DORotateQuaternion(targetRotation, duration).Play(); } } public partial class MovementSubcontrollerBase { [TitleGroup("Ground")] [Tooltip("留空以使用默认配置")] public GroundDetector groundDetector; public bool isOnGround; [TitleGroup("XZ Movement")] public CompoundBool canMove; public float moveSpeed; public float moveAcceleration; public float moveDeceleration; public bool isSprinting; public float sprintSpeedMultiplier = 1.5f; public float runningTime; [TitleGroup("Y Movement & Jump")] public bool canJump; public int maxJumpCount; public float jumpForce = 15f; public float normalGravity = 40f; public float jumpGravity = 60f; public bool isStartJumping; public bool isJumping; public bool isExtraJumping; public float jumpVelocity; public float jumpTime; public float jumpHeldTime; public bool isJumpLanding; [TitleGroup("Rush Stop")] public bool isRushStopping; public bool rushStopped; [TitleGroup("Rotation")] public CompoundBool canRotate; public float targetRotation; public Vector3 targetDirection; public float rotationVelocity; public float rotationSmoothTime; [TitleGroup("Gravity")] public bool isApplyingGravity; public Vector3 currentGravity; public float gravityMultiplier = 1; [TitleGroup("Dash")] public bool canDash; public bool isDashing; public bool afterDash; public float dashMoveMultiplier = 3; public float overrideDashMoveMultiplier = -1; [TitleGroup("Dodge")] public bool canDodge; public bool isDodging; public bool afterDodge; public float dodgeMoveMultiplier = 1; public float overrideDodgeMoveMultiplier = -1; [TitleGroup("Root Motion")] public float rootMotionMoveXMultiplier = 1; public float rootMotionMoveYMultiplier = 1; public float rootMotionMoveZMultiplier = 1; [TitleGroup("Final Movement Calculation")] public Vector3 horizontalMovement; public Vector3 verticalMovement; public float verticalMoveMultiplier = 1; public Vector3 jumpMovement; public Vector3 gravitationalMovement; public Vector3 initiativeMovementVelocity; public Vector3 movementModifier; public Vector3 finalMovementVelocity; } public partial class MovementSubcontrollerBase { public enum CharacterRotationType { ByAiming, ByMovement, } } }