This commit is contained in:
MrTorex committed 2026-02-18 20:13:09 +03:00
1 parent 0d5e6b6dec
commit c12d653cbc
647 files changed
+194585 -117

No files matched your search

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0e4799047a8c484abd6ff0e92a5ff093
timeCreated: 1771431588
@@ -0,0 +1,19 @@
using UnityEngine;
namespace Code.Gameplay.Character.Controller
{
public class AirMovementSystem
{
private readonly Vector3 _gravity;
public AirMovementSystem(Vector3 gravity)
{
_gravity = gravity;
}
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
currentVelocity += _gravity * deltaTime;
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 60d5b036992c463590cada0327f0e4d4
timeCreated: 1771431829
@@ -0,0 +1,46 @@
using UnityEngine;
using KinematicCharacterController;
namespace Code.Gameplay.Character.Controller
{
public class GroundMovementSystem
{
private readonly float _maxStableMoveSpeed;
private readonly float _sprintMoveSpeed;
private readonly float _stableMovementSharpness;
public GroundMovementSystem(float maxStableMoveSpeed, float sprintMoveSpeed, float stableMovementSharpness)
{
_maxStableMoveSpeed = maxStableMoveSpeed;
_sprintMoveSpeed = sprintMoveSpeed;
_stableMovementSharpness = stableMovementSharpness;
}
public void UpdateVelocity(
ref Vector3 currentVelocity,
CharacterInputHandler inputHandler,
KinematicCharacterMotor motor,
float deltaTime)
{
var currentVelocityMagnitude = currentVelocity.magnitude;
var effectiveGroundNormal = motor.GroundingStatus.GroundNormal;
currentVelocity = motor.GetDirectionTangentToSurface(currentVelocity, effectiveGroundNormal) *
currentVelocityMagnitude;
var inputRight = Vector3.Cross(inputHandler.MoveInputVector, motor.CharacterUp);
var reorientedInput = Vector3.Cross(effectiveGroundNormal, inputRight).normalized *
inputHandler.MoveInputVector.magnitude;
var targetSpeed = inputHandler.IsSprinting ? _sprintMoveSpeed : _maxStableMoveSpeed;
var targetMovementVelocity = reorientedInput * targetSpeed;
currentVelocity = Vector3.Lerp(
currentVelocity,
targetMovementVelocity,
1f - Mathf.Exp(-_stableMovementSharpness * deltaTime)
);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 65cbfbe68735468997f05a5e80b6910e
timeCreated: 1771431851
+3
View File
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0dce37a9def247adb97d183cf312fcde
timeCreated: 1771431596
@@ -0,0 +1,63 @@
using UnityEngine;
using Code.Gameplay.Character.Core;
using KinematicCharacterController;
namespace Code.Gameplay.Character.Controller
{
public class CharacterInputHandler
{
private readonly float _sprintAngleThresholdCos;
public Vector3 MoveInputVector { get; set; }
public Vector3 LookInputVector { get; set; }
public bool IsSprinting { get; set; }
public Quaternion FirstPersonCameraRotation { get; set; }
public bool ShouldApplyCameraRotation { get; private set; }
public CharacterInputHandler(float sprintAngleThreshold)
{
_sprintAngleThresholdCos = Mathf.Cos(Mathf.Deg2Rad * sprintAngleThreshold);
}
public void ProcessInputs(ref CharacterInputs inputs, KinematicCharacterMotor motor)
{
IsSprinting = inputs.SprintPressed && inputs.MoveAxisForward > _sprintAngleThresholdCos; // Спринт только при движении на заданный в конфиге угол
var moveInputVector =
Vector3.ClampMagnitude(new Vector3(inputs.MoveAxisRight, 0, inputs.MoveAxisForward), 1f);
HandleFirstPersonInputs(ref inputs, moveInputVector, motor);
}
private void HandleFirstPersonInputs(ref CharacterInputs inputs, Vector3 moveInputVector, KinematicCharacterMotor motor)
{
FirstPersonCameraRotation = ExtractHorizontalRotation(inputs.CameraRotation, motor);
ShouldApplyCameraRotation = true;
var cameraPlanarDirection = inputs.CameraPlanarDirection;
var cameraPlanarRotation = Quaternion.LookRotation(cameraPlanarDirection, motor.CharacterUp);
MoveInputVector = cameraPlanarRotation * moveInputVector;
LookInputVector = cameraPlanarDirection;
}
private static Quaternion ExtractHorizontalRotation(Quaternion cameraRotation, KinematicCharacterMotor motor)
{
var cameraForward = cameraRotation * Vector3.forward;
var horizontalForward = Vector3.ProjectOnPlane(cameraForward, Vector3.up).normalized;
if (horizontalForward.sqrMagnitude < 0.01f)
{
horizontalForward = motor.CharacterForward;
}
return Quaternion.LookRotation(horizontalForward, motor.CharacterUp);
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 7cbc2ef1c7c14e1788d9633d4b9267c5
timeCreated: 1771431877
@@ -0,0 +1,15 @@
using UnityEngine;
namespace Code.Gameplay.Character.Core
{
public struct CharacterInputs
{
public float MoveAxisForward;
public float MoveAxisRight;
public Quaternion CameraRotation;
public Vector3 CameraPlanarDirection;
public bool JumpPressed;
public bool SprintPressed;
public bool SlidePressed;
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: f0b3699e82824e42832f381246741e90
timeCreated: 1771431755
@@ -0,0 +1,42 @@
using Code.Gameplay.Camera;
using Code.Gameplay.Character.Controller;
using Code.Input;
using UnityEngine;
namespace Code.Gameplay.Character.Core
{
public class CharacterProvider : MonoBehaviour
{
[SerializeField] private CustomCharacterController customCharacterController;
public CustomCharacterController CustomCharacterController => customCharacterController;
[SerializeField] private Transform cameraFollowPoint;
public Transform GetFollowTransform() => cameraFollowPoint;
private IInputService _inputService;
public void Teleport(Vector3 position, Quaternion rotation)
{
customCharacterController.SetPosition(position);
customCharacterController.SetRotation(rotation);
}
private void HandleCharacterInput()
{
var inputs = new CharacterInputs();
var moveInput = _inputService.MoveInput;
inputs.MoveAxisForward = moveInput.y;
inputs.MoveAxisRight = moveInput.x;
inputs.SprintPressed = _inputService.SprintHeld;
inputs.CameraRotation = FindFirstObjectByType<CameraController>().GetCameraRotation();
inputs.CameraPlanarDirection = FindFirstObjectByType<CameraController>().GetPlanarDirection();
customCharacterController.SetInputs(ref inputs);
}
private void Update()
{
HandleCharacterInput();
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 0073ba8d33504841b4ec7ef63b747249
timeCreated: 1771431716
@@ -0,0 +1,78 @@
using Code.Gameplay.Character.Core;
using KinematicCharacterController;
using UnityEngine;
namespace Code.Gameplay.Character.Controller
{
public class CustomCharacterController : MonoBehaviour, ICharacterController
{
[SerializeField] private KinematicCharacterMotor motor;
[SerializeField] private Transform characterTransform;
private CharacterInputHandler _inputHandler;
private GroundMovementSystem _groundMovement;
private AirMovementSystem _airMovement;
[SerializeField] private float sprintAngleThreshold;
[SerializeField] private float maxStableMoveSpeed;
[SerializeField] private float sprintMoveSpeed;
[SerializeField] private float stableMovementSharpness;
[SerializeField] private Vector3 gravity;
public void SetPosition(Vector3 position) => motor.SetPosition(position);
public void SetRotation(Quaternion rotation) => motor.SetRotation(rotation);
private void Construct()
{
_inputHandler = new CharacterInputHandler(
sprintAngleThreshold
);
_groundMovement = new GroundMovementSystem(
maxStableMoveSpeed,
sprintMoveSpeed,
stableMovementSharpness
);
_airMovement = new AirMovementSystem(
gravity
);
motor.CharacterController = this;
_inputHandler.FirstPersonCameraRotation = motor.Transform.rotation;
}
public void SetInputs(ref CharacterInputs inputs)
{
_inputHandler.ProcessInputs(ref inputs, motor);
}
public void UpdateRotation(ref Quaternion currentRotation, float deltaTime)
{
currentRotation = _inputHandler.FirstPersonCameraRotation;
}
public void UpdateVelocity(ref Vector3 currentVelocity, float deltaTime)
{
var wasGrounded = motor.GroundingStatus.IsStableOnGround;
if (wasGrounded)
{
_groundMovement?.UpdateVelocity(ref currentVelocity, _inputHandler, motor, deltaTime);
}
else
{
_airMovement?.UpdateVelocity(ref currentVelocity, deltaTime);
}
}
public void BeforeCharacterUpdate(float deltaTime) { }
public void PostGroundingUpdate(float deltaTime) { }
public void AfterCharacterUpdate(float deltaTime) { }
public bool IsColliderValidForCollisions(Collider coll) => true;
public void OnGroundHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport) { }
public void OnMovementHit(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, ref HitStabilityReport hitStabilityReport) { }
public void ProcessHitStabilityReport(Collider hitCollider, Vector3 hitNormal, Vector3 hitPoint, Vector3 atCharacterPosition, Quaternion atCharacterRotation, ref HitStabilityReport hitStabilityReport) { }
public void OnDiscreteCollisionDetected(Collider hitCollider) { }
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 3ab3cb1f5b954513a34e58dd8a96d027
timeCreated: 1771431901