Implement player network spawning and position synchronization
This commit is contained in:
112
Assets/Scripts/Components/PlayerComponent.cs
Normal file
112
Assets/Scripts/Components/PlayerComponent.cs
Normal file
@@ -0,0 +1,112 @@
|
||||
using HurricaneVR.Framework.Components;
|
||||
using HurricaneVR.Framework.Core.Player;
|
||||
using Meta.XR.MultiplayerBlocks.NGO;
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using Unity.Netcode.Components;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
using Zenject;
|
||||
using static Unity.Burst.Intrinsics.X86.Avx;
|
||||
|
||||
public class PlayerComponent : NetworkBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private NetworkObject networkObject;
|
||||
|
||||
[SerializeField]
|
||||
private HVRTeleporter teleporter;
|
||||
|
||||
[SerializeField]
|
||||
private HVRPlayerController controller;
|
||||
|
||||
[SerializeField]
|
||||
private CharacterController characterController;
|
||||
|
||||
[ReadOnly]
|
||||
[SerializeField]
|
||||
private float fadeDuration = 2f;
|
||||
|
||||
[SerializeField]
|
||||
public GameManager gameManager;
|
||||
|
||||
public Vector3 Position
|
||||
{
|
||||
get { return controller.transform.position; }
|
||||
}
|
||||
|
||||
public Vector3 Rotation
|
||||
{
|
||||
get { return controller.transform.eulerAngles; }
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
base.OnNetworkSpawn();
|
||||
|
||||
name = $"Player - {networkObject.OwnerClientId}"
|
||||
+ (networkObject.IsLocalPlayer ? " (local)" : "");
|
||||
|
||||
if (!networkObject.IsOwner)
|
||||
{
|
||||
StartCoroutine(DestroyMultiplayerComponents());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator DestroyMultiplayerComponents()
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
DestroyDependencies();
|
||||
|
||||
foreach (var t in new[]
|
||||
{
|
||||
typeof(UniversalAdditionalCameraData),
|
||||
})
|
||||
{
|
||||
foreach (var component in GetComponentsInChildren(t))
|
||||
{
|
||||
Destroy(component);
|
||||
}
|
||||
}
|
||||
|
||||
controller.RemoveMultiplayerComponents();
|
||||
}
|
||||
|
||||
public void DestroyDependencies()
|
||||
{
|
||||
Destroy(controller.RightHand.ForceGrabber._anchor.gameObject);
|
||||
Destroy(controller.LeftHand.ForceGrabber._anchor.gameObject);
|
||||
Destroy(controller.LeftHand._anchor);
|
||||
Destroy(controller.RightHand._anchor);
|
||||
}
|
||||
|
||||
public void DestroyWithDependencies()
|
||||
{
|
||||
DestroyDependencies();
|
||||
Destroy(gameObject);
|
||||
}
|
||||
|
||||
public void Teleport(Vector3 position, Vector3 direction)
|
||||
{
|
||||
teleporter.Teleport(position, direction);
|
||||
}
|
||||
|
||||
public void FadeScreen(float to, float duration)
|
||||
{
|
||||
controller.ScreenFader.Fade(to, duration);
|
||||
}
|
||||
|
||||
public void FadeIn()
|
||||
{
|
||||
controller.ScreenFader.Fade(1, fadeDuration);
|
||||
}
|
||||
|
||||
public void FadeOut()
|
||||
{
|
||||
controller.ScreenFader.Fade(0, fadeDuration);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Components/PlayerComponent.cs.meta
Normal file
11
Assets/Scripts/Components/PlayerComponent.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 983bb31c4dab2d84b857006f5099d030
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
9
Assets/Scripts/Editor/OdinNetworkBehaviourEditor.cs
Normal file
9
Assets/Scripts/Editor/OdinNetworkBehaviourEditor.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
using Sirenix.OdinInspector.Editor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(NetworkBehaviour), true)]
|
||||
public class OdinNetworkBehaviourEditor : OdinEditor { }
|
||||
11
Assets/Scripts/Editor/OdinNetworkBehaviourEditor.cs.meta
Normal file
11
Assets/Scripts/Editor/OdinNetworkBehaviourEditor.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4a312837e470c54faa1f6a28f0a201e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -19,8 +19,9 @@ public class PlayerSpawner : MonoBehaviour
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
public void Spawn(GameObject player)
|
||||
public void Spawn(PlayerComponent player)
|
||||
{
|
||||
player.GetComponent<HVRTeleporter>().Teleport(spawns.First().position);
|
||||
var spawn = spawns.First();
|
||||
player.Teleport(spawn.position, spawn.eulerAngles);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
using HurricaneVR.Framework.Core;
|
||||
using HurricaneVR.Framework.Core.Player;
|
||||
using HurricaneVR.Framework.Core.Utils;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using Zenject;
|
||||
|
||||
public class GlobalInstaller : MonoInstaller
|
||||
{
|
||||
|
||||
|
||||
[SerializeField]
|
||||
private GameObject musicPlayerPrefab;
|
||||
|
||||
@@ -15,10 +14,16 @@ public class GlobalInstaller : MonoInstaller
|
||||
private GameObject hvrGlobalPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject playerPrefab;
|
||||
private GameObject sceneManagerPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject sceneManagerPrefab;
|
||||
private GameObject networkManagerPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject gameManagerPrefab;
|
||||
|
||||
[SerializeField]
|
||||
private GameObject playerPrefab;
|
||||
|
||||
public override void Start()
|
||||
{
|
||||
@@ -46,12 +51,12 @@ public class GlobalInstaller : MonoInstaller
|
||||
})
|
||||
.NonLazy();
|
||||
|
||||
Container.Bind<HVRPlayerController>()
|
||||
.FromComponentInNewPrefab(playerPrefab)
|
||||
Container.Bind<GameManager>()
|
||||
.FromComponentInNewPrefab(gameManagerPrefab)
|
||||
.AsSingle()
|
||||
.OnInstantiated<HVRPlayerController>((ctx, obj) =>
|
||||
.OnInstantiated<GameManager>((ctx, obj) =>
|
||||
{
|
||||
obj.transform.parent.name = playerPrefab.name;
|
||||
obj.name = gameManagerPrefab.name;
|
||||
})
|
||||
.NonLazy();
|
||||
|
||||
@@ -63,5 +68,23 @@ public class GlobalInstaller : MonoInstaller
|
||||
obj.name = sceneManagerPrefab.name;
|
||||
})
|
||||
.NonLazy();
|
||||
|
||||
Container.Bind<NetworkManager>()
|
||||
.FromComponentInNewPrefab(networkManagerPrefab)
|
||||
.AsSingle()
|
||||
.OnInstantiated<NetworkManager>((ctx, obj) =>
|
||||
{
|
||||
obj.name = networkManagerPrefab.name;
|
||||
})
|
||||
.NonLazy();
|
||||
|
||||
Container.Bind<PlayerComponent>()
|
||||
.FromComponentInNewPrefab(playerPrefab)
|
||||
.AsSingle()
|
||||
.OnInstantiated<PlayerComponent>((ctx, obj) =>
|
||||
{
|
||||
obj.name = playerPrefab.name;
|
||||
})
|
||||
.NonLazy();
|
||||
}
|
||||
}
|
||||
54
Assets/Scripts/Managers/ConnectionManager.cs
Normal file
54
Assets/Scripts/Managers/ConnectionManager.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using Zenject;
|
||||
|
||||
public class ConnectionManager : NetworkBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
private NetworkManager networkManager;
|
||||
|
||||
[Inject]
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
private GameManager gameManager;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
networkManager.OnClientConnectedCallback += OnClientConnectedCallback;
|
||||
networkManager.OnClientDisconnectCallback += OnClientDisconnectCallback;
|
||||
}
|
||||
|
||||
private void OnClientConnectedCallback(ulong clientId)
|
||||
{
|
||||
Debug.Log($"Client-{clientId} is connected and can spawn {nameof(NetworkObject)}s.");
|
||||
|
||||
if (networkManager.LocalClientId == clientId)
|
||||
{
|
||||
StartCoroutine(SpawnLocalPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerator SpawnLocalPlayer()
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
var playerObject = networkManager.LocalClient.PlayerObject;
|
||||
var player = playerObject.GetComponent<PlayerComponent>();
|
||||
player.gameManager = gameManager;
|
||||
gameManager.PlayerSpawnedOnNetwork(player);
|
||||
yield return null;
|
||||
}
|
||||
|
||||
private void OnClientDisconnectCallback(ulong clientId)
|
||||
{
|
||||
Debug.Log($"Client-{clientId} is disconnected and can spawn {nameof(NetworkObject)}s.");
|
||||
|
||||
if (networkManager.LocalClientId == clientId)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Managers/ConnectionManager.cs.meta
Normal file
11
Assets/Scripts/Managers/ConnectionManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cb16de57aad3ebe42bb3df246dc58d5f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
27
Assets/Scripts/Managers/GameManager.cs
Normal file
27
Assets/Scripts/Managers/GameManager.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using Zenject;
|
||||
|
||||
public class GameManager : NetworkBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
[Inject]
|
||||
private PlayerComponent localPlayer;
|
||||
public PlayerComponent LocalPlayer {
|
||||
get { return localPlayer; }
|
||||
}
|
||||
|
||||
public void PlayerSpawnedOnNetwork(PlayerComponent player)
|
||||
{
|
||||
if (player.IsLocalPlayer)
|
||||
{
|
||||
player.Teleport(localPlayer.Position, localPlayer.Rotation);
|
||||
localPlayer.DestroyWithDependencies();
|
||||
localPlayer = player;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Managers/GameManager.cs.meta
Normal file
11
Assets/Scripts/Managers/GameManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d357a0b6e2db94a4aadef95ef4fff758
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -33,7 +33,7 @@ public class LevelManager : MonoBehaviour
|
||||
[Inject]
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
private HVRPlayerController playerController;
|
||||
private GameManager gameManager;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@@ -44,7 +44,8 @@ public class LevelManager : MonoBehaviour
|
||||
musicManager.Play(level.pauseClip);
|
||||
}
|
||||
|
||||
playerSpawner.Spawn(playerController.gameObject);
|
||||
var player = gameManager.LocalPlayer;
|
||||
playerSpawner.Spawn(player);
|
||||
}
|
||||
|
||||
public void OnEnemyReachedFinish(EnemyComponent enemy)
|
||||
|
||||
@@ -2,10 +2,11 @@ using HurricaneVR.Framework.Core.Player;
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using Zenject;
|
||||
|
||||
public class LobbyManager : MonoBehaviour
|
||||
public class LobbyManager : NetworkBehaviour
|
||||
{
|
||||
[Inject]
|
||||
[SerializeField]
|
||||
@@ -20,7 +21,7 @@ public class LobbyManager : MonoBehaviour
|
||||
[Inject]
|
||||
[SerializeField]
|
||||
[ReadOnly]
|
||||
private HVRPlayerController playerController;
|
||||
private GameManager gameManager;
|
||||
|
||||
[SerializeField]
|
||||
private AudioClip backgroundMusicClip;
|
||||
@@ -29,6 +30,7 @@ public class LobbyManager : MonoBehaviour
|
||||
{
|
||||
musicManager.Play(backgroundMusicClip);
|
||||
|
||||
playerSpawner.Spawn(playerController.gameObject);
|
||||
var player = gameManager.LocalPlayer;
|
||||
playerSpawner.Spawn(player);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ public class SceneManager : MonoBehaviour
|
||||
[Inject]
|
||||
[ReadOnly]
|
||||
[SerializeField]
|
||||
private HVRPlayerController playerController;
|
||||
private GameManager gameManager;
|
||||
|
||||
[ReadOnly]
|
||||
[SerializeField]
|
||||
@@ -36,7 +36,7 @@ public class SceneManager : MonoBehaviour
|
||||
|
||||
private IEnumerator SwitchToScene(Scene scene)
|
||||
{
|
||||
playerController.ScreenFader.Fade(1, fadeDuration);
|
||||
gameManager.LocalPlayer.FadeScreen(1, fadeDuration);
|
||||
|
||||
var operation = UnityEngine.SceneManagement.SceneManager
|
||||
.LoadSceneAsync((int)scene);
|
||||
@@ -55,6 +55,6 @@ public class SceneManager : MonoBehaviour
|
||||
|
||||
this.scene = scene;
|
||||
|
||||
playerController.ScreenFader.Fade(0, fadeDuration);
|
||||
gameManager.LocalPlayer.FadeScreen(0, fadeDuration);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user