using UnityEngine; using Fusion; using Opsive.UltimateCharacterController.Networking; using Opsive.UltimateCharacterController.Networking.Character; using Opsive.UltimateCharacterController.Character; using Opsive.UltimateCharacterController.Camera; // Corrected namespace using Opsive.UltimateCharacterController.Input; // Corrected namespace namespace Hallucinate.Network { // Ensure Opsive components load before this [DefaultExecutionOrder(100)] public class FusionClientMovementBridge : NetworkBehaviour, INetworkInfo, INetworkCharacter { public override void Spawned() { // Because we passed State Authority to the client in BasicSpawner, // HasStateAuthority is true ONLY for the local player. bool isLocal = Object.HasStateAuthority; // 1. Isolate Input: Only the local player should read keyboard/mouse inputs. var locoHandler = GetComponent(); if (locoHandler != null) locoHandler.enabled = isLocal; var activeInput = GetComponent(); // Corrected class reference if (activeInput != null) activeInput.enabled = isLocal; // 2. Isolate Camera: Only attach the camera if this is the local player. if (isLocal) { var cameraController = UnityEngine.Object.FindFirstObjectByType(); if (cameraController != null) { cameraController.Character = gameObject; } } } // --- INetworkInfo Implementation --- public bool IsLocalPlayer() => Object.HasStateAuthority; public bool IsServer() => Runner.IsServer; // Return FALSE because we are doing Client-Authoritative movement! public bool IsServerAuthoritative() => false; // --- INetworkCharacter Implementation --- // Since we are using Fusion's NetworkTransform to sync position, // we can leave these methods empty. Opsive will handle the local // movement, and Fusion's NetworkTransform will drag the remote players. public void SetPosition(Vector3 position, bool snapAnimator) { } public void SetRotation(Quaternion rotation, bool snapAnimator) { } public void SetPositionAndRotation(Vector3 position, Quaternion rotation, bool snapAnimator) { } public void ResetRotationPosition() { } public void SetActive(bool active, bool uiEvent) { } // Optional interface stubs for weapons/items (leave empty for now to focus on movement) public void LoadDefaultLoadout() { } public void EquipUnequipItem(uint itemID, int slotID, bool equip) { } public void ItemIdentifierPickup(uint id, int amount, int slot, bool immediate, bool force) { } public void RemoveAllItems() { } // New missing interface stubs for Shooter/Melee compiled code public void Fire(Opsive.UltimateCharacterController.Items.Actions.ItemAction itemAction, float strength) { } public void StartItemReload(Opsive.UltimateCharacterController.Items.Actions.ItemAction itemAction) { } public void ReloadItem(Opsive.UltimateCharacterController.Items.Actions.ItemAction itemAction, bool fullClip) { } public void ItemReloadComplete(Opsive.UltimateCharacterController.Items.Actions.ItemAction itemAction, bool success, bool immediateReload) { } public void MeleeHitCollider(Opsive.UltimateCharacterController.Items.Actions.ItemAction itemAction, int hitboxIndex, RaycastHit raycastHit, GameObject hitGameObject, UltimateCharacterLocomotion hitCharacterLocomotion) { } public void ThrowItem(Opsive.UltimateCharacterController.Items.Actions.ItemAction action) { } public void EnableThrowableObjectMeshRenderers(Opsive.UltimateCharacterController.Items.Actions.ItemAction action) { } public void StartStopBeginEndMagicActions(Opsive.UltimateCharacterController.Items.Actions.ItemAction action, bool begin, bool start) { } public void MagicCast(Opsive.UltimateCharacterController.Items.Actions.ItemAction action, int index, uint castID, Vector3 dir, Vector3 target) { } public void MagicImpact(Opsive.UltimateCharacterController.Items.Actions.ItemAction action, uint castID, GameObject source, GameObject target, Vector3 pos, Vector3 norm) { } public void StopMagicCast(Opsive.UltimateCharacterController.Items.Actions.ItemAction action, int index, uint castID) { } public void ToggleFlashlight(Opsive.UltimateCharacterController.Items.Actions.ItemAction action, bool active) { } public void PushRigidbody(Rigidbody rb, Vector3 force, Vector3 point) { } } }