177 lines
5.8 KiB
C#
177 lines
5.8 KiB
C#
using SLSUtilities.General;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
|
|
|
|
namespace Cielonos.MainGame.Characters
|
|
{
|
|
public partial class AutomataLandMovementSubcontroller : LandMovementSubcontroller
|
|
{
|
|
public NavMeshAgent navMeshAgent => (owner as Automata)!.behaviorSc.navMeshAgent;
|
|
public LerpFloat moveSpeedX;
|
|
public LerpFloat moveSpeedZ;
|
|
|
|
public override void Initialize()
|
|
{
|
|
base.Initialize();
|
|
navMeshAgent.isStopped = true;
|
|
moveSpeedX = new LerpFloat(0f, 5f);
|
|
moveSpeedZ = new LerpFloat(0f, 5f);
|
|
}
|
|
|
|
private Vector3 lastDirection;
|
|
|
|
protected override void Update()
|
|
{
|
|
base.Update(); // 更新 isOnGround
|
|
HandleNavMeshState();
|
|
}
|
|
|
|
protected override void OnAnimatorMove()
|
|
{
|
|
if (owner.selfTimeSm.DeltaTime == 0 || owner.statusSm.isDead)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (navMeshAgent != null && navMeshAgent.enabled)
|
|
{
|
|
if (!is8WayMovement)
|
|
{
|
|
if (!navMeshAgent.isStopped)
|
|
{
|
|
float distanceVelocity = navMeshAgent.velocity.magnitude;
|
|
float angularVelocity = Vector3.Angle(lastDirection, transform.forward) / owner.selfTimeSm.DeltaTime;
|
|
moveSpeedZ.targetValue = distanceVelocity + (angularVelocity * 0.1f);
|
|
}
|
|
else
|
|
{
|
|
moveSpeedZ.targetValue = 0f;
|
|
}
|
|
|
|
moveSpeedZ.Update(0.2f, 1);
|
|
animator.SetFloat("MoveSpeedZ", moveSpeedZ.currentValue);
|
|
}
|
|
else
|
|
{
|
|
if (!navMeshAgent.isStopped)
|
|
{
|
|
Vector3 distanceVelocity = navMeshAgent.velocity;
|
|
float xValue = Vector3.Dot(distanceVelocity, transform.right);
|
|
float zValue = Vector3.Dot(distanceVelocity, transform.forward);
|
|
moveSpeedX.targetValue = xValue;
|
|
moveSpeedZ.targetValue = zValue;
|
|
}
|
|
else
|
|
{
|
|
moveSpeedX.targetValue = 0f;
|
|
moveSpeedZ.targetValue = 0f;
|
|
}
|
|
|
|
moveSpeedX.Update(0.2f, 1);
|
|
moveSpeedZ.Update(0.2f, 1);
|
|
animator.SetFloat("MoveSpeedX", moveSpeedX.currentValue);
|
|
animator.SetFloat("MoveSpeedZ", moveSpeedZ.currentValue);
|
|
}
|
|
}
|
|
|
|
base.OnAnimatorMove();
|
|
|
|
InitiativeMove();
|
|
|
|
lastDirection = transform.forward;
|
|
}
|
|
|
|
private void HandleNavMeshState()
|
|
{
|
|
if (navMeshAgent == null) return;
|
|
|
|
if (stagnantFirstHalf && !isOnGround && finalMovementVelocity.y <0)
|
|
{
|
|
stagnantFirstHalf = false;
|
|
stagnantLastHalf = true;
|
|
}
|
|
|
|
if (stagnantLastHalf && isOnGround)
|
|
{
|
|
additionalForceSm.additionalForceY.currentValue = 0;
|
|
if (!navMeshAgent.enabled)
|
|
{
|
|
navMeshAgent.enabled = true;
|
|
navMeshAgent.Warp(transform.position);
|
|
}
|
|
|
|
stagnantFirstHalf = false;
|
|
stagnantLastHalf = false;
|
|
}
|
|
}
|
|
|
|
protected override void ApplyGravity()
|
|
{
|
|
base.ApplyGravity();
|
|
}
|
|
|
|
protected override void InitiativeMove()
|
|
{
|
|
if (navMeshAgent.enabled)
|
|
{
|
|
navMeshAgent.Move(finalMovementVelocity);
|
|
navMeshAgent.baseOffset += finalMovementVelocity.y;
|
|
navMeshAgent.baseOffset = Mathf.Max(navMeshAgent.baseOffset, 0f);
|
|
}
|
|
else
|
|
{
|
|
if (owner.collisionSc.useCharacterController)
|
|
{
|
|
owner.collisionSc.characterController.Move(finalMovementVelocity);
|
|
}
|
|
else
|
|
{
|
|
Vector3 startPosition = owner.collisionSc.mainRigidbody.position;
|
|
owner.collisionSc.mainRigidbody.MovePosition(startPosition + finalMovementVelocity);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected override void UpdateFinalMovement()
|
|
{
|
|
base.UpdateFinalMovement();
|
|
}
|
|
}
|
|
|
|
public partial class AutomataLandMovementSubcontroller
|
|
{
|
|
public bool stagnantFirstHalf;
|
|
public bool stagnantLastHalf;
|
|
|
|
/// <summary>
|
|
/// 处理受击位移
|
|
/// </summary>
|
|
/// <param name="force">力的矢量</param>
|
|
/// <param name="isLaunch">是否为“击飞”(无视抗性,重置重力)</param>
|
|
/// <param name="stasisDuration">滞空时间(秒)</param>
|
|
public void ApplyHitImpact(Vector3 force, bool isLaunch, float stasisDuration = 0f)
|
|
{
|
|
// 1. 瞬间切断导航
|
|
if (isLaunch && navMeshAgent.enabled) navMeshAgent.enabled = false;
|
|
|
|
// 2. 施加力
|
|
// 如果是击飞(Launch),则 ignoreResistance 为 true (不扣除初速度)
|
|
|
|
if (!stagnantFirstHalf && !stagnantLastHalf)
|
|
{
|
|
stagnantFirstHalf = true;
|
|
}
|
|
|
|
additionalForceSm.AddForce(force, isLaunch);
|
|
|
|
|
|
// 3. 处理滞空逻辑 (鬼泣式)
|
|
if (stasisDuration > 0)
|
|
{
|
|
jumpVelocity = 0;
|
|
gravitationalMovement = Vector3.zero;
|
|
}
|
|
}
|
|
}
|
|
} |