update phtono
This commit is contained in:
@@ -53,6 +53,46 @@ namespace Hallucinate.UI
|
||||
DontDestroyOnLoad(gameObject);
|
||||
}
|
||||
|
||||
private async void Start()
|
||||
{
|
||||
// Auto-connect if we bypass the UI and start directly in the Main Scene
|
||||
if (UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Main Scene")
|
||||
{
|
||||
Debug.Log("[BasicSpawner] Auto-starting Fusion in AutoHostOrClient mode for testing...");
|
||||
|
||||
if (_isStarting) return;
|
||||
_isStarting = true;
|
||||
|
||||
try
|
||||
{
|
||||
await EnsureRunnerExists();
|
||||
var sceneManager = gameObject.GetComponent<NetworkSceneManagerDefault>();
|
||||
if (sceneManager == null) sceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>();
|
||||
|
||||
var result = await _runner.StartGame(new StartGameArgs()
|
||||
{
|
||||
GameMode = GameMode.Shared,
|
||||
SessionName = "QuickTestRoom", // Hardcoded session for instant testing
|
||||
SceneManager = sceneManager,
|
||||
Scene = SceneRef.FromIndex(UnityEngine.SceneManagement.SceneManager.GetActiveScene().buildIndex)
|
||||
});
|
||||
|
||||
if (result.Ok)
|
||||
{
|
||||
Debug.Log("[BasicSpawner] Auto Connect SUCCESS!");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError($"[BasicSpawner] Auto Connect FAILED: {result.ShutdownReason}");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isStarting = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public PlayerProfile LocalPlayerProfile { get; private set; }
|
||||
public void SetLocalPlayerProfile(PlayerProfile _profile)
|
||||
{
|
||||
@@ -91,8 +131,13 @@ namespace Hallucinate.UI
|
||||
|
||||
if (this == null) return; // BasicSpawner itself might be destroyed
|
||||
|
||||
Debug.Log("[BasicSpawner] Creating new NetworkRunner component.");
|
||||
_runner = gameObject.AddComponent<NetworkRunner>();
|
||||
_runner = gameObject.GetComponent<NetworkRunner>();
|
||||
if (_runner == null)
|
||||
{
|
||||
Debug.Log("[BasicSpawner] Creating new NetworkRunner component.");
|
||||
_runner = gameObject.AddComponent<NetworkRunner>();
|
||||
}
|
||||
|
||||
_runner.ProvideInput = true;
|
||||
_runner.AddCallbacks(this);
|
||||
}
|
||||
@@ -244,18 +289,13 @@ namespace Hallucinate.UI
|
||||
|
||||
public void OnPlayerJoined(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
Debug.Log($"[BasicSpawner] PlayerJoined: {player.PlayerId}");
|
||||
|
||||
// In Shared Mode, there is no Server. Each client is responsible for spawning their own player.
|
||||
if (player == runner.LocalPlayer)
|
||||
{
|
||||
SendLocalMetaData(player);
|
||||
}
|
||||
|
||||
// If the server receives a player join event and the scene is already loaded, spawn them immediately
|
||||
if (runner.IsServer && UnityEngine.SceneManagement.SceneManager.GetActiveScene().name == "Main Scene")
|
||||
{
|
||||
if (!_spawnedCharacters.ContainsKey(player))
|
||||
{
|
||||
SpawnPlayer(runner, player);
|
||||
}
|
||||
SpawnPlayer(runner, player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,9 +474,12 @@ namespace Hallucinate.UI
|
||||
|
||||
private void SpawnPlayer(NetworkRunner runner, PlayerRef player)
|
||||
{
|
||||
Debug.Log($"[BasicSpawner] Spawning Player {player.PlayerId} at {Time.time}");
|
||||
Vector3 spawnPosition = (player == runner.LocalPlayer) ? new Vector3(-8, 2, 0) : new Vector3(8, 2, 0);
|
||||
var networkPlayerObject = runner.Spawn(_playerPrefab, spawnPosition, Quaternion.identity, player);
|
||||
|
||||
// In Shared Mode, runner.Spawn automatically grants State Authority to the caller.
|
||||
// We just need to assign Input Authority.
|
||||
networkPlayerObject.AssignInputAuthority(player);
|
||||
|
||||
_spawnedCharacters[player] = networkPlayerObject;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user