2026-06-26 11:18:49 +01:00

147 lines
5.8 KiB
C#

using Intrepid.Core.Entities;
using Intrepid.Core.Grounding;
using Intrepid.GameManagers;
using Intrepid.Gameplay.Entities.Player.Sentinel.Events;
using Intrepid.Gameplay.Flooring;
using Intrepid.Utilities;
using UnityEngine;
namespace Intrepid.Gameplay.Entities.Player.Sentinel
{
public class SentinelEntity : Entity
{
[GroupInjections, SerializeField] private Rigidbody unityRigidbody;
[GroupInjections, SerializeField] private CapsuleCollider capsuleCollider;
[GroupInjections, SerializeField] private Transform modelTransform;
[GroupInjections, SerializeField] private EntityModelAnimation modelAnimation;
[GroupInjections, SerializeField] private FloorDetection floorDetection;
[GroupInjections, SerializeField] private EntityMotorSmoothRotation motorSmoothRotation;
[GroupInjections, SerializeField] private EntityMotorPhysicsContact motorPhysicsContact;
[GroupInjections, SerializeField] private EntityMotorTopDown motorTopDown;
private Vector3 _desiredForward = Vector3.forward;
private Vector3 _intendedDesiredVelocity = Vector3.zero;
protected SentinelBrain Brain => EntityBrain as SentinelBrain;
private Rigidbody UnityRigidbody => unityRigidbody;
private CapsuleCollider CapsuleCollider => capsuleCollider;
// private EntityMotorSmoothRotation MotorSmoothRotation => motorSmoothRotation;
private EntityMotorPhysicsContact MotorPhysicsContact => motorPhysicsContact;
private EntityMotorTopDown MotorTopDown => motorTopDown;
public Transform RigidBodyTransform => unityRigidbody.transform;
public EntityModelAnimation ModelAnimation => modelAnimation;
public Vector2 DesiredVelocity { get; set; }
public Vector3 LinearVelocity { get; private set; }
public Vector2 Forward => new Vector2(_desiredForward.x, _desiredForward.z).normalized;
public bool IsGrounded => MotorTopDown.IsGrounded;
public GroundProfiles CurrentGroundProfiles => MotorTopDown.CurrentGroundProfiles;
public FloorDetection FloorDetection => floorDetection;
public Vector3 Position
{
get => UnityRigidbody.position;
set => UnityRigidbody.position = value;
}
public override void DeployEntity(Vector3 position, Vector2 direction)
{
Position = position;
ChangeOrientation(direction);
UnityRigidbody.isKinematic = false;
CapsuleCollider.enabled = true;
MotorTopDown.enabled = true;
MotorPhysicsContact.enabled = true;
RefreshMovementNormal();
}
public override void RetreatEntity()
{
UnityRigidbody.isKinematic = true;
CapsuleCollider.enabled = false;
MotorTopDown.enabled = false;
MotorPhysicsContact.enabled = false;
}
private void Start()
{
RetreatEntity();
}
public void ChangeOrientation(Vector2 direction)
{
if (direction.sqrMagnitude <= GonConstants.CommonZeroSqrt)
{
return;
}
_desiredForward.x = direction.x;
_desiredForward.y = 0;
_desiredForward.z = direction.y;
_desiredForward = _desiredForward.normalized;
}
public override void UpdateFromUpdatable()
{
if (!Brain.IsEnabled) return;
modelTransform.rotation = Quaternion.LookRotation(_desiredForward, Vector3.up);
//MotorSmoothRotation.TurnModel(modelTransform, _desiredForward);
base.UpdateFromUpdatable();
}
public override void FixedUpdateFromUpdatable()
{
if (!Brain.IsEnabled) return;
base.FixedUpdateFromUpdatable();
_intendedDesiredVelocity = new Vector3(DesiredVelocity.x, 0, DesiredVelocity.y);
LinearVelocity = MotorPhysicsContact.AdjustVelocityByContacts(DesiredVelocity);
var moveOptions = Brain.Controls.IsDashing
? EntityMotorMoveOptions.GapCrossing
: EntityMotorMoveOptions.Default;
MotorTopDown.Move(UnityRigidbody, LinearVelocity, Time.fixedDeltaTime, moveOptions);
MotorPhysicsContact.ResetContactCounter();
}
private void OnCollisionEnter(Collision collision)
{
if (!Brain.IsEnabled) return;
MotorPhysicsContact.RegisterCollisionContacts(collision, MotorTopDown.MaxSlopeAngle);
TryRaiseImpact(LinearVelocity);
}
private void OnCollisionStay(Collision collision)
{
if (!Brain.IsEnabled) return;
MotorPhysicsContact.RegisterCollisionContacts(collision, MotorTopDown.MaxSlopeAngle);
TryRaiseImpact(_intendedDesiredVelocity);
}
private void TryRaiseImpact(Vector3 intendedVelocity)
{
if (MotorPhysicsContact.HasImpactAgainstRegisteredContacts(intendedVelocity, 25f, out var bounceDirection))
{
var force = new Vector2(bounceDirection.x, bounceDirection.z) * intendedVelocity.magnitude;
Proxy.Instance.EventBus.Raise(new ForceBackOnImpactEvent
{
Force = force,
});
}
}
public void RefreshMovementNormal()
{
MotorTopDown.RefreshStableGroundNormalAt(UnityRigidbody.position);
}
public void ResetLastSafeGroundPosition()
{
UnityRigidbody.position = MotorTopDown.LastSafeGroundPosition;
MotorTopDown.ResetFallingToAbyss();
}
}
}