aha
This commit is contained in:
110
Assets/Mirror/Examples/Room/Scripts/NetworkRoomManagerExt.cs
Normal file
110
Assets/Mirror/Examples/Room/Scripts/NetworkRoomManagerExt.cs
Normal file
@ -0,0 +1,110 @@
|
||||
using UnityEngine;
|
||||
|
||||
/*
|
||||
Documentation: https://mirror-networking.gitbook.io/docs/components/network-manager
|
||||
API Reference: https://mirror-networking.com/docs/api/Mirror.NetworkManager.html
|
||||
*/
|
||||
|
||||
namespace Mirror.Examples.NetworkRoom
|
||||
{
|
||||
[AddComponentMenu("")]
|
||||
public class NetworkRoomManagerExt : NetworkRoomManager
|
||||
{
|
||||
[Header("Spawner Setup")]
|
||||
[Tooltip("Reward Prefab for the Spawner")]
|
||||
public GameObject rewardPrefab;
|
||||
public byte poolSize = 10;
|
||||
|
||||
public static new NetworkRoomManagerExt singleton => NetworkManager.singleton as NetworkRoomManagerExt;
|
||||
|
||||
/// <summary>
|
||||
/// This is called on the server when a networked scene finishes loading.
|
||||
/// </summary>
|
||||
/// <param name="sceneName">Name of the new scene.</param>
|
||||
public override void OnRoomServerSceneChanged(string sceneName)
|
||||
{
|
||||
// spawn the initial batch of Rewards
|
||||
if (sceneName == GameplayScene)
|
||||
{
|
||||
Spawner.InitializePool(rewardPrefab, poolSize);
|
||||
Spawner.InitialSpawn();
|
||||
}
|
||||
else
|
||||
Spawner.ClearPool();
|
||||
}
|
||||
|
||||
public override void OnRoomClientSceneChanged()
|
||||
{
|
||||
// Don't initialize the pool for host client because it's
|
||||
// already initialized in OnRoomServerSceneChanged
|
||||
if (NetworkServer.active) return;
|
||||
|
||||
if (networkSceneName == GameplayScene)
|
||||
Spawner.InitializePool(rewardPrefab, poolSize);
|
||||
else
|
||||
Spawner.ClearPool();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called just after GamePlayer object is instantiated and just before it replaces RoomPlayer object.
|
||||
/// This is the ideal point to pass any data like player name, credentials, tokens, colors, etc.
|
||||
/// into the GamePlayer object as it is about to enter the Online scene.
|
||||
/// </summary>
|
||||
/// <param name="roomPlayer"></param>
|
||||
/// <param name="gamePlayer"></param>
|
||||
/// <returns>true unless some code in here decides it needs to abort the replacement</returns>
|
||||
public override bool OnRoomServerSceneLoadedForPlayer(NetworkConnectionToClient conn, GameObject roomPlayer, GameObject gamePlayer)
|
||||
{
|
||||
PlayerScore playerScore = gamePlayer.GetComponent<PlayerScore>();
|
||||
playerScore.index = roomPlayer.GetComponent<NetworkRoomPlayer>().index;
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void OnRoomStopClient()
|
||||
{
|
||||
base.OnRoomStopClient();
|
||||
}
|
||||
|
||||
public override void OnRoomStopServer()
|
||||
{
|
||||
base.OnRoomStopServer();
|
||||
}
|
||||
|
||||
/*
|
||||
This code below is to demonstrate how to do a Start button that only appears for the Host player
|
||||
showStartButton is a local bool that's needed because OnRoomServerPlayersReady is only fired when
|
||||
all players are ready, but if a player cancels their ready state there's no callback to set it back to false
|
||||
Therefore, allPlayersReady is used in combination with showStartButton to show/hide the Start button correctly.
|
||||
Setting showStartButton false when the button is pressed hides it in the game scene since NetworkRoomManager
|
||||
is set as DontDestroyOnLoad = true.
|
||||
*/
|
||||
|
||||
bool showStartButton;
|
||||
|
||||
public override void OnRoomServerPlayersReady()
|
||||
{
|
||||
// calling the base method calls ServerChangeScene as soon as all players are in Ready state.
|
||||
if (Utils.IsHeadless())
|
||||
{
|
||||
base.OnRoomServerPlayersReady();
|
||||
}
|
||||
else
|
||||
{
|
||||
showStartButton = true;
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnGUI()
|
||||
{
|
||||
base.OnGUI();
|
||||
|
||||
if (allPlayersReady && showStartButton && GUI.Button(new Rect(150, 300, 120, 20), "START GAME"))
|
||||
{
|
||||
// set to false to hide it in the game scene
|
||||
showStartButton = false;
|
||||
|
||||
ServerChangeScene(GameplayScene);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e7d8650c751710349bb9546d1697b9cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/Room/Scripts/NetworkRoomManagerExt.cs
|
||||
uploadId: 736421
|
38
Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs
Normal file
38
Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Examples.NetworkRoom
|
||||
{
|
||||
[AddComponentMenu("")]
|
||||
public class NetworkRoomPlayerExt : NetworkRoomPlayer
|
||||
{
|
||||
public override void OnStartClient()
|
||||
{
|
||||
//Debug.Log($"OnStartClient {gameObject}");
|
||||
}
|
||||
|
||||
public override void OnClientEnterRoom()
|
||||
{
|
||||
//Debug.Log($"OnClientEnterRoom {SceneManager.GetActiveScene().path}");
|
||||
}
|
||||
|
||||
public override void OnClientExitRoom()
|
||||
{
|
||||
//Debug.Log($"OnClientExitRoom {SceneManager.GetActiveScene().path}");
|
||||
}
|
||||
|
||||
public override void IndexChanged(int oldIndex, int newIndex)
|
||||
{
|
||||
//Debug.Log($"IndexChanged {newIndex}");
|
||||
}
|
||||
|
||||
public override void ReadyStateChanged(bool oldReadyState, bool newReadyState)
|
||||
{
|
||||
//Debug.Log($"ReadyStateChanged {newReadyState}");
|
||||
}
|
||||
|
||||
public override void OnGUI()
|
||||
{
|
||||
base.OnGUI();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 41fc608223969754e817c29908fdb1d3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/Room/Scripts/NetworkRoomPlayerExt.cs
|
||||
uploadId: 736421
|
19
Assets/Mirror/Examples/Room/Scripts/PlayerScore.cs
Normal file
19
Assets/Mirror/Examples/Room/Scripts/PlayerScore.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Examples.NetworkRoom
|
||||
{
|
||||
[AddComponentMenu("")]
|
||||
public class PlayerScore : NetworkBehaviour
|
||||
{
|
||||
[SyncVar]
|
||||
public int index;
|
||||
|
||||
[SyncVar]
|
||||
public uint score;
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
GUI.Box(new Rect(10f + (index * 110), 10f, 100f, 25f), $"P{index}: {score:0000000}");
|
||||
}
|
||||
}
|
||||
}
|
18
Assets/Mirror/Examples/Room/Scripts/PlayerScore.cs.meta
Normal file
18
Assets/Mirror/Examples/Room/Scripts/PlayerScore.cs.meta
Normal file
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1ba998ee2eff92a419f4377519caf095
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/Room/Scripts/PlayerScore.cs
|
||||
uploadId: 736421
|
65
Assets/Mirror/Examples/Room/Scripts/Reward.cs
Normal file
65
Assets/Mirror/Examples/Room/Scripts/Reward.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Examples.NetworkRoom
|
||||
{
|
||||
[AddComponentMenu("")]
|
||||
[RequireComponent(typeof(Common.RandomColor))]
|
||||
public class Reward : NetworkBehaviour
|
||||
{
|
||||
[Header("Components")]
|
||||
public Common.RandomColor randomColor;
|
||||
|
||||
[Header("Diagnostics")]
|
||||
[ReadOnly, SerializeField]
|
||||
bool available;
|
||||
|
||||
protected override void OnValidate()
|
||||
{
|
||||
if (Application.isPlaying) return;
|
||||
|
||||
base.OnValidate();
|
||||
Reset();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
// Default position out of reach
|
||||
transform.position = new Vector3(0, -1000, 0);
|
||||
|
||||
if (randomColor == null)
|
||||
randomColor = GetComponent<Common.RandomColor>();
|
||||
}
|
||||
|
||||
public override void OnStartServer()
|
||||
{
|
||||
available = true;
|
||||
}
|
||||
|
||||
[ServerCallback]
|
||||
void OnTriggerEnter(Collider other)
|
||||
{
|
||||
// Don't process collisions when it's in the pool
|
||||
if (!gameObject.activeSelf) return;
|
||||
|
||||
// Set up physics layers to prevent this from being called by non-players
|
||||
// and eliminate the need for a tag check here.
|
||||
if (!other.CompareTag("Player")) return;
|
||||
|
||||
// This is a fast switch to prevent two players claiming the reward in a bang-bang close contest for it.
|
||||
// First to trigger turns it off, pending the object being destroyed a few frames later.
|
||||
if (!available)
|
||||
return;
|
||||
|
||||
available = false;
|
||||
|
||||
// Calculate the points from the color...lighter scores higher as the average approaches 255
|
||||
// UnityEngine.Color RGB values are byte 0 to 255
|
||||
uint points = (uint)((randomColor.color.r + randomColor.color.g + randomColor.color.b) / 3);
|
||||
|
||||
// award the points via SyncVar on Player's PlayerScore
|
||||
other.GetComponent<PlayerScore>().score += points;
|
||||
|
||||
Spawner.RecycleReward(gameObject);
|
||||
}
|
||||
}
|
||||
}
|
18
Assets/Mirror/Examples/Room/Scripts/Reward.cs.meta
Normal file
18
Assets/Mirror/Examples/Room/Scripts/Reward.cs.meta
Normal file
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a22f9eb8ebad79e47babf4c051a714ee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/Room/Scripts/Reward.cs
|
||||
uploadId: 736421
|
104
Assets/Mirror/Examples/Room/Scripts/Spawner.cs
Normal file
104
Assets/Mirror/Examples/Room/Scripts/Spawner.cs
Normal file
@ -0,0 +1,104 @@
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Mirror.Examples.NetworkRoom
|
||||
{
|
||||
internal static class Spawner
|
||||
{
|
||||
static GameObject prefab;
|
||||
static byte poolSize = 10;
|
||||
static Pool<GameObject> pool;
|
||||
static ushort counter;
|
||||
|
||||
internal static void InitializePool(GameObject poolPrefab, byte count)
|
||||
{
|
||||
prefab = poolPrefab;
|
||||
poolSize = count;
|
||||
|
||||
NetworkClient.RegisterPrefab(prefab, SpawnHandler, UnspawnHandler);
|
||||
pool = new Pool<GameObject>(CreateNew, poolSize);
|
||||
}
|
||||
|
||||
internal static void ClearPool()
|
||||
{
|
||||
if (prefab == null) return;
|
||||
|
||||
NetworkClient.UnregisterPrefab(prefab);
|
||||
|
||||
if (pool == null) return;
|
||||
|
||||
// destroy all objects in pool
|
||||
while (pool.Count > 0)
|
||||
Object.Destroy(pool.Get());
|
||||
|
||||
counter = 0;
|
||||
pool = null;
|
||||
}
|
||||
|
||||
static GameObject SpawnHandler(SpawnMessage msg) => Get(msg.position, msg.rotation);
|
||||
|
||||
static void UnspawnHandler(GameObject spawned) => Return(spawned);
|
||||
|
||||
static GameObject CreateNew()
|
||||
{
|
||||
// use this object as parent so that objects dont crowd hierarchy
|
||||
GameObject next = Object.Instantiate(prefab);
|
||||
counter++;
|
||||
next.name = $"{prefab.name}_pooled_{counter:00}";
|
||||
next.SetActive(false);
|
||||
return next;
|
||||
}
|
||||
|
||||
public static GameObject Get(Vector3 position, Quaternion rotation)
|
||||
{
|
||||
GameObject next = pool.Get();
|
||||
|
||||
// set position/rotation and set active
|
||||
next.transform.SetPositionAndRotation(position, rotation);
|
||||
next.SetActive(true);
|
||||
return next;
|
||||
}
|
||||
|
||||
// Used to put object back into pool so they can b
|
||||
// Should be used on server after unspawning an object
|
||||
// Used on client by NetworkClient to unspawn objects
|
||||
public static void Return(GameObject spawned)
|
||||
{
|
||||
// disable object
|
||||
spawned.SetActive(false);
|
||||
|
||||
// move the object out of reach so OnTriggerEnter doesn't get called
|
||||
spawned.transform.position = new Vector3(0, -1000, 0);
|
||||
|
||||
// add back to pool
|
||||
pool.Return(spawned);
|
||||
}
|
||||
|
||||
[ServerCallback]
|
||||
internal static void InitialSpawn()
|
||||
{
|
||||
for (byte i = 0; i < poolSize; i++)
|
||||
SpawnReward();
|
||||
}
|
||||
|
||||
[ServerCallback]
|
||||
internal static void SpawnReward()
|
||||
{
|
||||
Vector3 spawnPosition = new Vector3(Random.Range(-19, 20), 1, Random.Range(-19, 20));
|
||||
NetworkServer.Spawn(Get(spawnPosition, Quaternion.identity));
|
||||
}
|
||||
|
||||
[ServerCallback]
|
||||
internal static async void RecycleReward(GameObject reward)
|
||||
{
|
||||
NetworkServer.UnSpawn(reward);
|
||||
await DelayedSpawn();
|
||||
}
|
||||
|
||||
static async Task DelayedSpawn()
|
||||
{
|
||||
await Task.Delay(new System.TimeSpan(0, 0, 1));
|
||||
SpawnReward();
|
||||
}
|
||||
}
|
||||
}
|
18
Assets/Mirror/Examples/Room/Scripts/Spawner.cs.meta
Normal file
18
Assets/Mirror/Examples/Room/Scripts/Spawner.cs.meta
Normal file
@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bf5c082d04f7ea459fcd30e60b5bd70
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 129321
|
||||
packageName: Mirror
|
||||
packageVersion: 96.0.1
|
||||
assetPath: Assets/Mirror/Examples/Room/Scripts/Spawner.cs
|
||||
uploadId: 736421
|
Reference in New Issue
Block a user