update phtono

This commit is contained in:
2026-06-25 19:33:30 +07:00
parent 003fcf6b6f
commit 5d1af952b1
6 changed files with 262 additions and 174 deletions

View File

@@ -10,32 +10,73 @@ namespace Hallucinate.Network
{
// Ensure Opsive components load before this
[DefaultExecutionOrder(100)]
public class FusionClientMovementBridge : NetworkBehaviour, INetworkInfo, INetworkCharacter
public class FusionClientMovementBridge : NetworkBehaviour, INetworkInfo, INetworkCharacter, ILookSource
{
// --- ILookSource Implementation (Dummy values for Proxy characters) ---
public GameObject GameObject => gameObject;
public Transform Transform => transform;
public float LookDirectionDistance => 100f;
public float Pitch => 0f;
public Vector3 LookPosition() => transform.position + Vector3.up * 1.5f; // Rough head height
public Vector3 LookDirection(bool characterLookDirection) => transform.forward;
public Vector3 LookDirection(Vector3 lookPosition, bool characterLookDirection, int layerMask, bool useRecoil) => transform.forward;
private void Awake()
{
// Temporarily disable the Locomotion component so it unregisters from KinematicObjectManager.
// This prevents the frame-0 crash before we can safely attach the Look Source in Start().
var loco = GetComponent<UltimateCharacterLocomotion>();
if (loco != null) loco.enabled = false;
// MUST also disable the handler, otherwise it tries to update a disabled character (Index -1)
var handler = GetComponent<UltimateCharacterLocomotionHandler>();
if (handler != null) handler.enabled = false;
}
private void Start()
{
// Now that all Opsive components have finished Awake() and are fully initialized,
// we can safely attach the Look Source without causing NullReferenceExceptions in CharacterIK.
Opsive.Shared.Events.EventHandler.ExecuteEvent<ILookSource>(gameObject, "OnCharacterAttachLookSource", this);
// Re-enable Locomotion. It will run OnEnable() and safely register back to KinematicObjectManager.
var loco = GetComponent<UltimateCharacterLocomotion>();
if (loco != null) loco.enabled = true;
// If Fusion has already spawned us, restore the handler for the local player
if (Object != null && Object.IsValid)
{
var handler = GetComponent<UltimateCharacterLocomotionHandler>();
if (handler != null) handler.enabled = Object.HasInputAuthority;
}
}
public override void Spawned()
{
// We use InputAuthority to identify the local player because this is Host mode.
bool isLocal = Object.HasInputAuthority;
// 1. Isolate Input: Only the local player should read keyboard/mouse inputs.
var locoHandler = GetComponent<UltimateCharacterLocomotionHandler>();
if (locoHandler != null) locoHandler.enabled = isLocal;
var activeInput = GetComponent<UnityInput>(); // Corrected class reference
var activeInput = GetComponent<UnityInput>();
if (activeInput != null) activeInput.enabled = isLocal;
// 2. Isolate Camera: Only attach the camera if this is the local player.
// Safely enable the handler only if Locomotion is already enabled (to prevent index -1 crash)
var loco = GetComponent<UltimateCharacterLocomotion>();
var handler = GetComponent<UltimateCharacterLocomotionHandler>();
if (handler != null && loco != null && loco.enabled)
{
handler.enabled = isLocal;
}
if (isLocal)
{
var cameraController = UnityEngine.Object.FindFirstObjectByType<CameraController>();
if (cameraController != null)
{
cameraController.enabled = true;
// This will override our dummy LookSource with the actual Camera
cameraController.Character = gameObject;
}
// CRITICAL: Disable NetworkTransform on the local client so Fusion doesn't pull the character back!
var nt = GetComponent<NetworkTransform>();
if (nt != null) nt.enabled = false;
}
}