Files
Cielonos/Assets/Scripts/MainGame/Characters/Base/Subcontrollers/MovementSubcontrollerBase.cs

181 lines
6.5 KiB
C#
Raw Normal View History

2025-11-25 08:19:33 -05:00
using DG.Tweening;
using Sirenix.OdinInspector;
2026-02-13 09:22:11 -05:00
using SLSUtilities.General;
2025-11-25 08:19:33 -05:00
using UnityEngine;
using UnityEngine.Serialization;
namespace Cielonos.MainGame.Characters
{
public partial class MovementSubcontrollerBase : SubcontrollerBase<CharacterBase>
{
protected CharacterBase character => owner;
protected float DeltaTime => owner.selfTimeSm.DeltaTime;
[Tooltip("角色旋转方式ByMovement为ARPG式默认移动旋转ByAiming为八向移动")]
public CharacterRotationType rotationType;
2026-02-13 09:22:11 -05:00
public AdditionalForceSubmodule additionalForceSm;
2025-11-25 08:19:33 -05:00
[HideInEditorMode]
public Transform characterTransform;
public override void Initialize()
{
base.Initialize();
2026-02-13 09:22:11 -05:00
additionalForceSm ??= new AdditionalForceSubmodule(this);
canMove = new CompoundBool(true);
canRotate = new CompoundBool(true);
2025-11-25 08:19:33 -05:00
canDash = true;
canDodge = true;
canJump = true;
maxJumpCount = 1;
isApplyingGravity = true;
characterTransform = character.transform;
2025-12-08 05:27:53 -05:00
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"));
}
2025-11-25 08:19:33 -05:00
}
2026-04-30 07:06:38 -04:00
public void SmartTurnToTarget(CharacterBase target, float maxTurnAngle = 360f)
2025-11-25 08:19:33 -05:00
{
2026-04-28 15:46:32 -04:00
Vector3 directionToTarget = (target.centerPoint.position - owner.centerPoint.position).Flatten();
if (directionToTarget.sqrMagnitude < 0.001f) return;
float angleToTarget = Vector3.SignedAngle(owner.transform.forward, directionToTarget, Vector3.up);
float absAngle = Mathf.Abs(angleToTarget);
// 超过最大角度不转身
if (absAngle > maxTurnAngle) return;
// 小角度瞬间转身
if (absAngle <= 45f)
{
owner.transform.rotation = Quaternion.LookRotation(directionToTarget);
}
// 大角度平滑转身
else
{
float duration = Mathf.Lerp(0.1f, 0.2f, (absAngle - 45f) / 135f);
owner.transform.DORotateQuaternion(Quaternion.LookRotation(directionToTarget), duration).Play();
}
2025-11-25 08:19:33 -05:00
}
2026-03-20 12:07:44 -04:00
public void TurnToTargetByAngle(CharacterBase target, float angularSpeed)
{
Vector3 directionToTarget = (target.transform.position - characterTransform.position).Flatten();
if (directionToTarget == Vector3.zero) return;
float targetAngle = Mathf.Atan2(directionToTarget.x, directionToTarget.z) * Mathf.Rad2Deg;
float currentAngle = characterTransform.eulerAngles.y;
float newAngle = Mathf.MoveTowardsAngle(currentAngle, targetAngle, angularSpeed * DeltaTime);
characterTransform.rotation = Quaternion.Euler(0, newAngle, 0);
}
2025-12-17 04:19:38 -05:00
public void TurnToDirection(Vector3 direction, float duration = 0f)
{
2026-02-13 09:22:11 -05:00
Vector3 targetDirection = direction.Flatten();
if (targetDirection == Vector3.zero) return;
2025-12-17 04:19:38 -05:00
2026-02-13 09:22:11 -05:00
Quaternion targetRotation = Quaternion.LookRotation(targetDirection);
characterTransform.DORotateQuaternion(targetRotation, duration).Play();
2025-12-17 04:19:38 -05:00
}
2025-11-25 08:19:33 -05:00
}
public partial class MovementSubcontrollerBase
{
[TitleGroup("Ground")]
[Tooltip("留空以使用默认配置")]
public GroundDetector groundDetector;
public bool isOnGround;
2026-02-13 09:22:11 -05:00
[TitleGroup("XZ Movement")]
public CompoundBool canMove;
2026-03-20 12:07:44 -04:00
public bool is8WayMovement;
2025-11-25 08:19:33 -05:00
public float moveSpeed;
public float moveAcceleration;
public float moveDeceleration;
public bool isSprinting;
public float sprintSpeedMultiplier = 1.5f;
public float runningTime;
2026-02-13 09:22:11 -05:00
[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;
2025-11-25 08:19:33 -05:00
[TitleGroup("Rush Stop")]
public bool isRushStopping;
public bool rushStopped;
[TitleGroup("Rotation")]
2026-02-13 09:22:11 -05:00
public CompoundBool canRotate;
2025-11-25 08:19:33 -05:00
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;
2026-02-13 09:22:11 -05:00
public float overrideDashMoveMultiplier = -1;
2025-11-25 08:19:33 -05:00
[TitleGroup("Dodge")]
public bool canDodge;
public bool isDodging;
public bool afterDodge;
public float dodgeMoveMultiplier = 1;
2026-02-13 09:22:11 -05:00
public float overrideDodgeMoveMultiplier = -1;
2025-11-25 08:19:33 -05:00
[TitleGroup("Root Motion")]
public float rootMotionMoveXMultiplier = 1;
public float rootMotionMoveYMultiplier = 1;
public float rootMotionMoveZMultiplier = 1;
[TitleGroup("Final Movement Calculation")]
public Vector3 horizontalMovement;
2026-02-13 09:22:11 -05:00
public Vector3 verticalMovement;
public float verticalMoveMultiplier = 1;
public Vector3 jumpMovement;
2025-11-25 08:19:33 -05:00
public Vector3 gravitationalMovement;
public Vector3 initiativeMovementVelocity;
public Vector3 movementModifier;
public Vector3 finalMovementVelocity;
}
public partial class MovementSubcontrollerBase
{
public enum CharacterRotationType
{
ByAiming,
ByMovement,
}
}
}