using System; using R3; using RebootKit.Engine.Foundation; using RebootKit.Engine.Main; using RebootKit.Engine.Network; using RebootKit.Engine.Simulation; using RebootReality.jelycho.Player.HUD; using Unity.Mathematics; using UnityEngine; 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; IInteractable m_Interactable; void Awake() { m_HUD = Instantiate(m_Config.playerHUDPrefab); } void OnDestroy() { if (m_HUD != null) { Destroy(m_HUD.gameObject); m_HUD = null; } m_OwnerActorDisposableBag.Dispose(); } void OnEnable() { RR.Input.LockCursor(); RR.Input.EnableControls(); } void OnDisable() { RR.Input.UnlockCursor(); RR.Input.DisableControls(); } protected override void OnPossessActor(Actor actor) { if (actor is PlayerActor playerActor) { m_Actor = playerActor; } else { m_Actor = null; s_Logger.Error($"Tried to possess non-PlayerActor: {actor.GetType().Name}"); return; } // if (IsOwner) { m_Actor.SetupAsOwner(); m_OwnerActorDisposableBag.Dispose(); m_OwnerActorDisposableBag = new DisposableBag(); m_Actor.TargetInteractable.Subscribe(interactable => { m_Interactable?.SetHighlight(false); if (m_TargetInteractableLabelDisposable != null) { m_TargetInteractableLabelDisposable.Dispose(); m_TargetInteractableLabelDisposable = null; } m_Interactable = interactable; m_Interactable?.SetHighlight(true); if (interactable is Actor interactableActor) { m_TargetInteractableLabelDisposable = m_HUD.ObjectsLabels.CreateLabel(interactableActor.transform, interactableActor.ActorName); } }) .AddTo(ref m_OwnerActorDisposableBag); m_HUD.SetPlayerActor(m_Actor); // } // if (IsServer) { // if (RR.World.Context is WorldContext worldContext) { // m_Actor.WarpTo(worldContext.PlayerSpawnPoint.position); // } // } } protected override void OnUnpossessActor(Actor actor) { base.OnUnpossessActor(actor); m_OwnerActorDisposableBag.Dispose(); m_OwnerActorDisposableBag = new DisposableBag(); m_Actor = null; } void Update() { if (m_Actor is null) { return; } Vector2 lookInput = SensitivityReader.Read(m_Config.lookActionReference.action); m_Actor.Look(lookInput * FPPConfig.MouseSensitivity.FloatValue); Vector2 moveInput = m_Config.moveActionReference.action.ReadValue(); m_Actor.SetMoveInput(moveInput); m_Actor.SetSprint(m_Config.sprintActionReference.action.IsPressed()); if (m_Config.jumpActionReference.action.WasPerformedThisFrame()) { m_Actor.Jump(); } if (m_Config.dropItemActionReference.action.WasReleasedThisFrame()) { m_Actor.DropItem(); } if (m_Config.kickActionReference.action.WasReleasedThisFrame()) { m_Actor.Kick(); } if (m_Config.primaryActionReference.action.WasPressedThisFrame()) { m_Actor.BeginPrimaryAction(); } if (m_Config.primaryActionReference.action.IsPressed()) { m_Actor.HoldingPrimaryAction(); } if (m_Config.primaryActionReference.action.WasReleasedThisFrame()) { m_Actor.EndPrimaryAction(); } 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(); 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 dropItemActionReference; public InputActionReference kickActionReference; 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(); 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; } } }