Files
jelito/Assets/jelycho/Code/Player/PlayerController.cs
2025-07-11 14:40:23 +02:00

204 lines
7.1 KiB
C#
Executable File

using System;
using R3;
using RebootKit.Engine.Foundation;
using RebootKit.Engine.Main;
using RebootReality.jelycho.Player.HUD;
using Unity.Mathematics;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.InputSystem;
using Logger = RebootKit.Engine.Foundation.Logger;
namespace RebootReality.jelycho.Player {
public class PlayerController : NetworkPlayerController {
static readonly Logger s_Logger = new Logger(nameof(PlayerController));
[SerializeField] Config m_Config;
PlayerActor m_Actor;
PlayerHUD m_HUD;
DisposableBag m_OwnerActorDisposableBag = new DisposableBag();
IDisposable m_TargetInteractableLabelDisposable;
public override void OnNetworkSpawn() {
base.OnNetworkSpawn();
if (IsOwner) {
RR.Input.LockCursor();
RR.Input.EnableControls();
m_HUD = Instantiate(m_Config.playerHUDPrefab);
}
}
public override void OnNetworkDespawn() {
base.OnNetworkDespawn();
if (IsOwner) {
RR.Input.UnlockCursor();
RR.Input.DisableControls();
if (m_HUD != null) {
Destroy(m_HUD.gameObject);
m_HUD = null;
}
m_OwnerActorDisposableBag.Dispose();
}
}
[ClientRpc]
public void SetActorClientRpc(ulong networkObjectID) {
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(networkObjectID,
out NetworkObject networkObject)) {
m_Actor = networkObject.GetComponent<PlayerActor>();
s_Logger.Info($"Found Player Actor NetworkObject ID: {networkObjectID}");
} else {
s_Logger.Error($"Failed to find PlayerActor with NetworkObject ID: {networkObjectID}");
m_Actor = null;
}
if (m_Actor is null) {
return;
}
if (IsServer) {
if (RR.World.Context is WorldContext worldContext) {
m_Actor.WarpToServerRpc(worldContext.PlayerSpawnPoint.position);
}
}
if (IsOwner) {
m_OwnerActorDisposableBag.Dispose();
m_OwnerActorDisposableBag = new DisposableBag();
m_Actor.TargetInteractable.Subscribe(interactable => {
if (m_TargetInteractableLabelDisposable != null) {
m_TargetInteractableLabelDisposable.Dispose();
m_TargetInteractableLabelDisposable = null;
}
if (interactable is MonoBehaviour mb) {
m_TargetInteractableLabelDisposable =
m_HUD.ObjectsLabels.CreateLabel(mb.transform, mb.name);
}
})
.AddTo(ref m_OwnerActorDisposableBag);
m_HUD.SetPlayerActor(m_Actor);
}
}
[ClientRpc]
public void SetNullActorClientRpc() {
m_OwnerActorDisposableBag.Dispose();
m_OwnerActorDisposableBag = new DisposableBag();
m_Actor = null;
}
void Update() {
if (m_Actor is null) {
return;
}
if (!IsOwner) {
return;
}
Vector2 lookInput = SensitivityReader.Read(m_Config.lookActionReference.action);
m_Actor.Look(lookInput * FPPConfig.MouseSensitivity.FloatValue);
Vector2 moveInput = m_Config.moveActionReference.action.ReadValue<Vector2>();
m_Actor.SetMoveInput(moveInput);
m_Actor.SetSprint(m_Config.sprintActionReference.action.IsPressed());
if (m_Config.jumpActionReference.action.WasPerformedThisFrame()) {
m_Actor.Jump();
}
if (m_Config.dragObjectActionReference.action.WasPressedThisFrame()) {
m_Actor.StartDrag();
}
if (m_Config.dragObjectActionReference.action.WasReleasedThisFrame()) {
m_Actor.StopDrag();
}
if (m_Config.primaryActionReference.action.WasReleasedThisFrame()) {
m_Actor.PrimaryAction();
}
if (m_Config.secondaryActionReference.action.WasReleasedThisFrame()) {
m_Actor.SecondaryAction();
}
if (m_Config.interactActionReference.action.WasReleasedThisFrame()) {
m_Actor.Interact();
}
for (int i = 0; i < m_Config.inventorySlotSelectActionReferences.Length; i++) {
if (m_Config.inventorySlotSelectActionReferences[i].action.WasReleasedThisFrame()) {
m_Actor.SelectItemSlot(i);
}
}
float slotChangeAxis = m_Config.inventorySlotChangeActionReference.action.ReadValue<float>();
if (math.abs(slotChangeAxis) > 0.5f) {
if (slotChangeAxis > 0) {
m_Actor.SelectNextItemSlot();
} else {
m_Actor.SelectPreviousItemSlot();
}
}
}
[Serializable]
public class Config {
public PlayerHUD playerHUDPrefab;
public InputActionReference moveActionReference;
public InputActionReference lookActionReference;
public InputActionReference jumpActionReference;
public InputActionReference sprintActionReference;
public InputActionReference dragObjectActionReference;
public InputActionReference primaryActionReference;
public InputActionReference secondaryActionReference;
public InputActionReference interactActionReference;
public InputActionReference[] inventorySlotSelectActionReferences;
public InputActionReference inventorySlotChangeActionReference;
}
}
public static class FPPConfig {
[ConfigVar("fpp.mouse.sens", 0.25f, "Mouse look sensitivity")] public static ConfigVar MouseSensitivity;
[ConfigVar("fpp.mouse.invert.y", 0, "Invert mouse look")] public static ConfigVar MouseInvertY;
[ConfigVar("fpp.gamepad.sens", 4.0f, "Gamepad look sensitivity")] public static ConfigVar GamepadSensitivity;
}
public static class SensitivityReader {
public static float2 Read(InputAction action) {
if (action == null || action.activeControl == null) {
return float2.zero;
}
float2 sensitivity = action.ReadValue<Vector2>();
bool isGamepad = action.activeControl.device is Gamepad;
if (isGamepad) {
sensitivity *= FPPConfig.GamepadSensitivity.FloatValue;
} else {
sensitivity *= FPPConfig.MouseSensitivity.FloatValue;
if (FPPConfig.MouseInvertY.IndexValue == 1) {
sensitivity.y *= -1;
}
}
return sensitivity;
}
}
}