feat: Samyaza player controls

This commit is contained in:
Alexandre Coirier
2026-05-27 00:28:20 +02:00
parent ed0aadb6c6
commit ae1f5b3ae2
5 changed files with 329 additions and 101 deletions
@@ -20,6 +20,7 @@ namespace OctoCore.Components
public bool IsRunning;
public float Yaw;
public float Pitch;
public float SpeedMultiplier = 1;
public OctoPlayerDriver Driver;
}
@@ -41,6 +42,12 @@ namespace OctoCore.Components
[Tooltip("Allow looking around.")]
public bool AllowLook = true;
[Tooltip("Allow run.")]
public bool AllowRun = true;
[Tooltip("Allow jump.")]
public bool AllowJump = true;
[Tooltip("Walk speed (km/h).")]
public float WalkSpeed = 10;
@@ -86,9 +93,15 @@ namespace OctoCore.Components
[Tooltip("Maximum pitch (looking up).")]
public float MaxPitch = 80f;
[Tooltip("Reference yaw.")]
[Range(-180, 180)] public float ReferenceYaw = 0;
[Tooltip("Range yaw.")]
[Range(0, 360)] public float RangeYaw = 360;
}
[OctoReadOnly] public StateMachine State;
[SerializeField, OctoReadOnly] private StateMachine _state;
[SerializeField] private References _references;
[SerializeField] private Settings _settings;
[SerializeField] private Mapping _mapping;
@@ -107,8 +120,9 @@ namespace OctoCore.Components
private Vector3 _moveInertia;
private Vector3 _moveDirection;
public bool IsPaused => State.IsPaused;
public bool IsPaused => _state.IsPaused;
public float Radius => _references.Controller ? _references.Controller.radius : 0;
public StateMachine State => _state;
public FirstPerson _FirstPerson => _firstPerson;
void OnEnable()
@@ -121,11 +135,11 @@ namespace OctoCore.Components
OctoCore.Instance.Inputs.SubscribeAction(_mapping.RunAction, Run);
OctoCore.Instance.Inputs.SubscribeAction(_mapping.JumpAction, Jump);
State.Yaw = transform.eulerAngles.y;
_state.Yaw = transform.eulerAngles.y;
State.IsFocussed = Application.isFocused;
_state.IsFocussed = Application.isFocused;
Pause(State.IsPaused);
Pause(_state.IsPaused);
}
void OnDisable()
@@ -156,12 +170,12 @@ namespace OctoCore.Components
public void Teleport(Vector3 position, Quaternion rotation)
{
State.IsPaused = _jumpInput = _jumpping = _runInput = false;
_state.IsPaused = _jumpInput = _jumpping = _runInput = false;
_runInertia = _jumpLerp = _jumpTime = _jumpAltitude = 0;
_moveInput = _lookInput = Vector2.zero;
_moveInertia = _moveDirection = Vector3.zero;
State.Yaw = rotation.eulerAngles.y;
State.Pitch = 0;
_state.Yaw = rotation.eulerAngles.y;
_state.Pitch = 0;
if (_references.Controller)
_references.Controller.enabled = false;
@@ -175,24 +189,26 @@ namespace OctoCore.Components
public void Pause(bool pause)
{
State.IsPaused = pause;
_state.IsPaused = pause;
if (OctoCore.Instance)
OctoCore.Instance.UI.SetCursor();
}
public void SetSppedMultiplier(float multiplier) { _state.SpeedMultiplier = multiplier; }
public void AllowMove(bool allow) { _settings.AllowMove = allow; }
public void Drive(OctoPlayerDriver driver) { State.Driver = driver; }
public void ReleaseDrive() { State.Driver = null; }
public void Drive(OctoPlayerDriver driver) { _state.Driver = driver; }
public void ReleaseDrive() { _state.Driver = null; }
public void SetYaw(float yaw) { State.Yaw = yaw; }
public void SetPitch(float pitch) { State.Yaw = pitch; }
public void SetYaw(float yaw) { _state.Yaw = yaw; }
public void SetPitch(float pitch) { _state.Yaw = pitch; }
private void Move(Vector2 value) { _moveInput = value; }
private void Look(Vector2 value) { _lookInput = value; }
private void Run() { _runInput = true; }
private void Jump() { _jumpInput = true; }
private void Run() { _runInput = _settings.AllowRun; }
private void Jump() { _jumpInput = _settings.AllowJump; }
private void HandleFocus()
{
@@ -220,16 +236,16 @@ namespace OctoCore.Components
if (!Application.isFocused || escapePressed)
{
if (State.IsFocussed)
if (_state.IsFocussed)
{
State.IsFocussed = false;
_wasPausedBeforeUnfocuss = State.IsPaused;
_state.IsFocussed = false;
_wasPausedBeforeUnfocuss = _state.IsPaused;
Pause(true);
}
}
else if (!State.IsFocussed && mouseClicked)
else if (!_state.IsFocussed && mouseClicked)
{
State.IsFocussed = true;
_state.IsFocussed = true;
if (!_wasPausedBeforeUnfocuss)
Pause(false);
}
@@ -237,7 +253,7 @@ namespace OctoCore.Components
private void HandleMovement()
{
_moveInput = (State.IsPaused || !State.IsFocussed || !_settings.AllowMove) ? Vector2.zero : Vector2.ClampMagnitude(_moveInput, 1);
_moveInput = (_state.IsPaused || !_state.IsFocussed || !_settings.AllowMove) ? Vector2.zero : Vector2.ClampMagnitude(_moveInput, 1);
Camera cam = (_firstPerson.Camera && _firstPerson.Camera.enabled && _firstPerson.Camera.gameObject.activeInHierarchy) ? _firstPerson.Camera : Camera.main;
bool accelerating = _moveInput.magnitude > .1f;
@@ -261,8 +277,8 @@ namespace OctoCore.Components
move = camRight * move.x + camForward * move.z;
}
if (State.Driver)
State.Driver.ApplyMoveInfluence(move, t, out move);
if (_state.Driver)
_state.Driver.ApplyMoveInfluence(move, t, out move);
float deltaSmooth = t * (accelerating ? 30 : 15);
_moveDirection = Vector3.Lerp(_moveDirection, move, deltaSmooth * 1.5f);
@@ -273,9 +289,9 @@ namespace OctoCore.Components
if (!accelerating && _moveInertia.magnitude < .01f) _moveInertia = Vector3.zero;
_runInertia = Mathf.Lerp(_runInertia, _runInput ? 1 : 0, t * (accelerating ? 5 : 3));
State.IsRunning = _runInertia > .1f;
_state.IsRunning = _runInertia > .1f;
Vector3 moveDelta = _moveInertia * t * Mathf.Lerp(_settings.WalkSpeed, _settings.RunSpeed, _runInertia);
Vector3 moveDelta = _moveInertia * t * Mathf.Lerp(_settings.WalkSpeed, _settings.RunSpeed, _runInertia) * _state.SpeedMultiplier;
if (isGrounded && _jumpInput && !_jumpping)
{
@@ -328,24 +344,29 @@ namespace OctoCore.Components
switch (_settings.Mode)
{
case PlayerModes.FirstPerson:
if (cam && !State.IsPaused)
if (cam && !_state.IsPaused)
{
Vector2 delta = (State.IsPaused || !State.IsFocussed) ? Vector2.zero : _lookInput;
Vector2 delta = (_state.IsPaused || !_state.IsFocussed) ? Vector2.zero : _lookInput;
if (_settings.AllowLook)
{
float mouseX = delta.x * _firstPerson.SensitivityX;
float mouseY = delta.y * _firstPerson.SensitivityY * -1;
State.Yaw += mouseX;
State.Pitch = Mathf.Clamp(State.Pitch + mouseY, _firstPerson.MinPitch, _firstPerson.MaxPitch);
_state.Yaw += mouseX;
float halfRange = _firstPerson.RangeYaw * 0.5f;
float deltaYaw = Mathf.DeltaAngle(_firstPerson.ReferenceYaw, _state.Yaw);
deltaYaw = Mathf.Clamp(deltaYaw, -halfRange, halfRange);
_state.Yaw = _firstPerson.ReferenceYaw + deltaYaw;
_state.Pitch = Mathf.Clamp(_state.Pitch + mouseY, _firstPerson.MinPitch, _firstPerson.MaxPitch);
}
if (State.Driver)
State.Driver.ApplyLookInfluence(State.Yaw, State.Pitch, Time.deltaTime, out State.Yaw, out State.Pitch);
if (_state.Driver)
_state.Driver.ApplyLookInfluence(_state.Yaw, _state.Pitch, Time.deltaTime, out _state.Yaw, out _state.Pitch);
Quaternion YawRot = Quaternion.Euler(0, State.Yaw, 0);
Quaternion PitchRot = Quaternion.Euler(State.Pitch, 0, 0);
Quaternion YawRot = Quaternion.Euler(0, _state.Yaw, 0);
Quaternion PitchRot = Quaternion.Euler(_state.Pitch, 0, 0);
transform.rotation = YawRot;
cam.transform.localRotation = PitchRot;
@@ -30,6 +30,7 @@ namespace OctoCore.Components
[Range(.1f, 3)] public float LookAtSmooth = 1;
[Range(0, 1)] public float LookAtPoint = .5f;
public AnimationCurve DriveCurve = AnimationCurve.EaseInOut(0, 0, 1 , 1);
public AnimationCurve LookCurve = AnimationCurve.EaseInOut(0, 0, 1 , 1);
}
[System.Serializable]
@@ -109,7 +110,7 @@ namespace OctoCore.Components
public void ApplyMoveInfluence(Vector3 inMove, float delta, out Vector3 outMove)
{
if (!OctoPlayer.Instance || !OctoPlayer.Instance._FirstPerson.Camera)
if (!OctoPlayer.Instance || !OctoPlayer.Instance._FirstPerson.Camera || !_references.Target)
{
outMove = inMove;
return;
@@ -140,7 +141,7 @@ namespace OctoCore.Components
public void ApplyLookInfluence(float inYaw, float inPitch, float deltaTime, out float outYaw, out float outPitch)
{
if (!OctoPlayer.Instance || !OctoPlayer.Instance._FirstPerson.Camera)
if (!OctoPlayer.Instance || !OctoPlayer.Instance._FirstPerson.Camera || !_references.LookAt)
{
outYaw = inYaw;
outPitch = inPitch;
@@ -158,7 +159,7 @@ namespace OctoCore.Components
float lookAtPitch = Mathf.Asin(-lookAt.y) * Mathf.Rad2Deg;
_state.LookInfluence = Mathf.InverseLerp(_settings.LookAtPoint, 1, _state.MoveInfluence) * _settings.LookAtStrength;
float lookInfluence = _settings.DriveCurve.Evaluate(_state.LookInfluence);
float lookInfluence = _settings.LookCurve.Evaluate(_state.LookInfluence);
float t = deltaTime * _settings.LookAtSmooth;
_state.YawRange = Mathf.Lerp(_state.YawRange, Mathf.Lerp(180, 0, lookInfluence), t);
@@ -0,0 +1,57 @@
using OctoCore.Components;
using UnityEngine;
namespace OctoCore
{
public class OctoPlayerSpeedArea : MonoBehaviour
{
[System.Serializable]
public class Settings
{
public float MinRadius = 1;
public float MaxRadius = 4;
[Space(10)]
public float MinSpeedMultiplier = 0;
public float MaxSpeedMultiplier = 1;
[Space(10)]
public AnimationCurve SpeedCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
}
[SerializeField] private Settings _settings;
void OnDrawGizmos()
{
UnityEditor.Handles.color = Color.cyan;
UnityEditor.Handles.matrix = transform.localToWorldMatrix;
UnityEditor.Handles.DrawWireDisc(Vector3.zero, Vector3.up, _settings.MinRadius);
UnityEditor.Handles.DrawWireDisc(Vector3.zero, Vector3.up, _settings.MaxRadius);
}
void Start()
{
}
void Update()
{
if (!OctoPlayer.Instance)
return;
float dist = Vector3.Distance(transform.position, OctoPlayer.Instance.transform.position);
if (dist < _settings.MaxRadius)
{
float t = Mathf.InverseLerp(_settings.MinRadius, _settings.MaxRadius, dist);
float speedMultiplier = Mathf.Lerp(_settings.MinSpeedMultiplier, _settings.MaxSpeedMultiplier, t);
OctoPlayer.Instance.SetSppedMultiplier(speedMultiplier);
}
}
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 516425b0868f3994c832b62ccc7be87a