105 lines
3.7 KiB
C#
105 lines
3.7 KiB
C#
using UnityEngine;
|
|
using OctoCore.Components;
|
|
using Unheimlich.Core;
|
|
using Unheimlich.Features.Player.Data;
|
|
using Unheimlich.Features.Dialogue;
|
|
using Unheimlich.Core.Interaction;
|
|
using Unheimlich.World.CameraSystem;
|
|
using InputManager = Unheimlich.Core.Input.InputManager;
|
|
|
|
namespace Unheimlich.Features.Player
|
|
{
|
|
/// <summary>
|
|
/// Central hub for all player systems.
|
|
/// Exposes components and settings with zero Inspector refs needed for other scripts.
|
|
/// </summary>
|
|
[RequireComponent(typeof(OctoPlayer))]
|
|
[RequireComponent(typeof(CharacterController))]
|
|
public class PlayerController : Singleton<PlayerController>
|
|
{
|
|
// Auto-found components (exposed publicly, found once in Awake)
|
|
public OctoPlayer Movement { get; private set; }
|
|
public CharacterController CharController { get; private set; }
|
|
public Camera PlayerCamera { get; private set; }
|
|
public Transform CameraTransform { get; private set; }
|
|
public Transform CameraPivot { get; private set; }
|
|
public CameraEffects CameraEffects { get; private set; }
|
|
public InputManager Inputs => InputManager.Instance;
|
|
|
|
// Cached sprint InputAction — resolved once in OnAwake to avoid per-frame foreach.
|
|
private UnityEngine.InputSystem.InputAction _sprintAction;
|
|
|
|
/// <summary>
|
|
/// True when the character is physically moving (based on CharacterController velocity,
|
|
/// not raw input — correctly synced with OctoPlayer's inertia).
|
|
/// </summary>
|
|
public bool IsMoving => CharController != null && CharController.velocity.magnitude > 0.1f;
|
|
|
|
/// <summary>
|
|
/// True while the sprint input is held and the player is moving.
|
|
/// </summary>
|
|
public bool IsRunning => _sprintAction != null && _sprintAction.IsPressed() && IsMoving;
|
|
|
|
protected override void OnAwake()
|
|
{
|
|
// Auto-find all components once
|
|
Movement = GetComponent<OctoPlayer>();
|
|
CharController = GetComponent<CharacterController>();
|
|
CameraEffects = GetComponent<CameraEffects>();
|
|
|
|
PlayerCamera = GetComponentInChildren<Camera>();
|
|
|
|
if (PlayerCamera != null)
|
|
{
|
|
CameraTransform = PlayerCamera.transform;
|
|
CameraPivot = CameraTransform.parent;
|
|
}
|
|
|
|
CacheSprintAction();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves the Sprint InputAction once from OctoCore to avoid per-frame foreach iteration.
|
|
/// </summary>
|
|
private void CacheSprintAction()
|
|
{
|
|
if (OctoCore.OctoCore.Instance?.Inputs?.Actions == null) return;
|
|
|
|
foreach (var actionInfo in OctoCore.OctoCore.Instance.Inputs.Actions)
|
|
{
|
|
if (actionInfo.Name == "Sprint" && actionInfo.Reference != null)
|
|
{
|
|
_sprintAction = actionInfo.Reference.action;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Teleport
|
|
public void Teleport(Vector3 position, Quaternion rotation)
|
|
{
|
|
Movement.Teleport(position, rotation);
|
|
PlayerEvents.TriggerTeleport(position, rotation);
|
|
}
|
|
|
|
// Helper methods
|
|
public Vector3 GetForward()
|
|
{
|
|
if (PlayerCamera == null) return transform.forward;
|
|
|
|
Vector3 forward = PlayerCamera.transform.forward;
|
|
forward.y = 0;
|
|
return forward.normalized;
|
|
}
|
|
|
|
public Vector3 GetRight()
|
|
{
|
|
if (PlayerCamera == null) return transform.right;
|
|
|
|
Vector3 right = PlayerCamera.transform.right;
|
|
right.y = 0;
|
|
return right.normalized;
|
|
}
|
|
}
|
|
}
|