275 lines
6.6 KiB
C#
Raw Normal View History

2020-12-07 21:19:16 +00:00
using QuantumUNET.Components;
using System.Collections.Generic;
2020-12-02 12:42:26 +00:00
using UnityEngine;
using UnityEngine.Networking;
2020-12-04 22:14:53 +00:00
namespace QuantumUNET
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
internal class QNetworkScene
2020-12-02 12:42:26 +00:00
{
2021-10-13 18:09:16 +01:00
internal static Dictionary<int, GameObject> guidToPrefab { get; } = new Dictionary<int, GameObject>();
internal static Dictionary<int, QSpawnDelegate> spawnHandlers { get; } = new Dictionary<int, QSpawnDelegate>();
internal static Dictionary<int, UnSpawnDelegate> unspawnHandlers { get; } = new Dictionary<int, UnSpawnDelegate>();
2020-12-23 12:58:45 +00:00
internal Dictionary<NetworkInstanceId, QNetworkIdentity> localObjects { get; } = new Dictionary<NetworkInstanceId, QNetworkIdentity>();
2020-12-02 20:43:16 +00:00
2020-12-02 12:42:26 +00:00
internal void Shutdown()
{
2020-12-07 21:04:52 +00:00
ClearLocalObjects();
2020-12-02 12:42:26 +00:00
ClearSpawners();
}
2020-12-16 08:57:15 +00:00
internal void SetLocalObject(NetworkInstanceId netId, GameObject obj, bool isClient, bool isServer)
2020-12-02 12:42:26 +00:00
{
if (obj == null)
{
2020-12-07 21:04:52 +00:00
localObjects[netId] = null;
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-23 12:58:45 +00:00
QNetworkIdentity networkIdentity = null;
2020-12-07 21:04:52 +00:00
if (localObjects.ContainsKey(netId))
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
networkIdentity = localObjects[netId];
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
if (networkIdentity == null)
{
2020-12-23 12:58:45 +00:00
networkIdentity = obj.GetComponent<QNetworkIdentity>();
2020-12-07 21:04:52 +00:00
localObjects[netId] = networkIdentity;
2020-12-02 12:42:26 +00:00
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
networkIdentity.UpdateClientServer(isClient, isServer);
}
}
2020-12-16 08:57:15 +00:00
internal GameObject FindLocalObject(NetworkInstanceId netId)
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
if (localObjects.ContainsKey(netId))
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
var networkIdentity = localObjects[netId];
2020-12-02 12:42:26 +00:00
if (networkIdentity != null)
{
return networkIdentity.gameObject;
}
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return null;
}
2020-12-23 12:58:45 +00:00
internal bool GetNetworkIdentity(NetworkInstanceId netId, out QNetworkIdentity uv)
2020-12-02 12:42:26 +00:00
{
bool result;
2020-12-02 20:43:16 +00:00
if (localObjects.ContainsKey(netId) && localObjects[netId] != null)
2020-12-02 12:42:26 +00:00
{
2020-12-02 20:43:16 +00:00
uv = localObjects[netId];
2020-12-02 12:42:26 +00:00
result = true;
}
else
{
uv = null;
result = false;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result;
}
2021-08-29 16:46:11 +01:00
internal bool RemoveLocalObject(NetworkInstanceId netId)
=> localObjects.Remove(netId);
2020-12-02 12:42:26 +00:00
2020-12-16 08:57:15 +00:00
internal bool RemoveLocalObjectAndDestroy(NetworkInstanceId netId)
2020-12-02 12:42:26 +00:00
{
bool result;
2020-12-07 21:04:52 +00:00
if (localObjects.ContainsKey(netId))
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
var networkIdentity = localObjects[netId];
Object.Destroy(networkIdentity.gameObject);
2020-12-07 21:04:52 +00:00
result = localObjects.Remove(netId);
2020-12-02 12:42:26 +00:00
}
else
{
result = false;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result;
}
2021-08-29 16:46:11 +01:00
internal void ClearLocalObjects()
=> localObjects.Clear();
2020-12-02 12:42:26 +00:00
2021-10-13 18:09:16 +01:00
internal static void RegisterPrefab(GameObject prefab, int newAssetId)
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var component = prefab.GetComponent<QNetworkIdentity>();
2020-12-02 12:42:26 +00:00
if (component)
{
component.SetDynamicAssetId(newAssetId);
guidToPrefab[component.AssetId] = prefab;
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
Debug.LogError($"Could not register '{prefab.name}' since it contains no NetworkIdentity component");
2020-12-02 12:42:26 +00:00
}
}
internal static void RegisterPrefab(GameObject prefab)
{
2020-12-23 12:58:45 +00:00
var component = prefab.GetComponent<QNetworkIdentity>();
2020-12-02 12:42:26 +00:00
if (component)
{
2020-12-02 20:43:16 +00:00
guidToPrefab[component.AssetId] = prefab;
2020-12-07 21:04:52 +00:00
var componentsInChildren = prefab.GetComponentsInChildren<NetworkIdentity>();
2020-12-02 12:42:26 +00:00
if (componentsInChildren.Length > 1)
{
Debug.LogWarning(
$"The prefab '{prefab.name}' has multiple NetworkIdentity components. There can only be one NetworkIdentity on a prefab, and it must be on the root object.");
2020-12-02 12:42:26 +00:00
}
}
2020-12-18 20:20:54 +00:00
else
2020-12-02 12:42:26 +00:00
{
Debug.LogError($"Could not register '{prefab.name}' since it contains no NetworkIdentity component");
2020-12-02 12:42:26 +00:00
}
}
2021-10-13 18:09:16 +01:00
internal static bool GetPrefab(int assetId, out GameObject prefab)
2020-12-02 12:42:26 +00:00
{
bool result;
2021-10-13 18:09:16 +01:00
if (assetId == 0)
2020-12-02 12:42:26 +00:00
{
prefab = null;
result = false;
}
else if (guidToPrefab.ContainsKey(assetId) && guidToPrefab[assetId] != null)
{
prefab = guidToPrefab[assetId];
result = true;
}
else
{
prefab = null;
result = false;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result;
}
internal static void ClearSpawners()
{
guidToPrefab.Clear();
spawnHandlers.Clear();
unspawnHandlers.Clear();
}
2021-10-13 18:09:16 +01:00
public static void UnregisterSpawnHandler(int assetId)
2020-12-02 12:42:26 +00:00
{
spawnHandlers.Remove(assetId);
unspawnHandlers.Remove(assetId);
}
2021-10-13 18:09:16 +01:00
internal static void RegisterSpawnHandler(int assetId, QSpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
2020-12-02 12:42:26 +00:00
{
if (spawnHandler == null || unspawnHandler == null)
{
Debug.LogError($"RegisterSpawnHandler custom spawn function null for {assetId}");
2020-12-02 12:42:26 +00:00
}
else
{
spawnHandlers[assetId] = spawnHandler;
unspawnHandlers[assetId] = unspawnHandler;
}
}
internal static void UnregisterPrefab(GameObject prefab)
{
2020-12-23 12:58:45 +00:00
var component = prefab.GetComponent<QNetworkIdentity>();
2020-12-02 12:42:26 +00:00
if (component == null)
{
Debug.LogError($"Could not unregister '{prefab.name}' since it contains no NetworkIdentity component");
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-02 20:43:16 +00:00
spawnHandlers.Remove(component.AssetId);
unspawnHandlers.Remove(component.AssetId);
2020-12-02 12:42:26 +00:00
}
}
2020-12-23 12:58:45 +00:00
internal static void RegisterPrefab(GameObject prefab, QSpawnDelegate spawnHandler, UnSpawnDelegate unspawnHandler)
2020-12-02 12:42:26 +00:00
{
2020-12-23 12:58:45 +00:00
var component = prefab.GetComponent<QNetworkIdentity>();
2020-12-02 12:42:26 +00:00
if (component == null)
{
Debug.LogError($"Could not register '{prefab.name}' since it contains no NetworkIdentity component");
2020-12-02 12:42:26 +00:00
}
else if (spawnHandler == null || unspawnHandler == null)
{
Debug.LogError($"RegisterPrefab custom spawn function null for {component.AssetId}");
2020-12-02 12:42:26 +00:00
}
2021-10-13 18:09:16 +01:00
else if (component.AssetId == 0)
2020-12-02 12:42:26 +00:00
{
Debug.LogError($"RegisterPrefab game object {prefab.name} has no prefab. Use RegisterSpawnHandler() instead?");
2020-12-02 12:42:26 +00:00
}
else
{
2020-12-02 20:43:16 +00:00
spawnHandlers[component.AssetId] = spawnHandler;
unspawnHandlers[component.AssetId] = unspawnHandler;
2020-12-02 12:42:26 +00:00
}
}
2021-10-13 18:09:16 +01:00
internal static bool GetSpawnHandler(int assetId, out QSpawnDelegate handler)
2020-12-02 12:42:26 +00:00
{
bool result;
if (spawnHandlers.ContainsKey(assetId))
{
handler = spawnHandlers[assetId];
result = true;
}
else
{
handler = null;
result = false;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result;
}
2021-10-13 18:09:16 +01:00
internal static bool InvokeUnSpawnHandler(int assetId, GameObject obj)
2020-12-02 12:42:26 +00:00
{
bool result;
if (unspawnHandlers.ContainsKey(assetId) && unspawnHandlers[assetId] != null)
{
2020-12-07 21:04:52 +00:00
var unSpawnDelegate = unspawnHandlers[assetId];
2020-12-02 12:42:26 +00:00
unSpawnDelegate(obj);
result = true;
}
else
{
result = false;
}
2021-06-18 22:39:21 +01:00
2020-12-02 12:42:26 +00:00
return result;
}
internal void DestroyAllClientObjects()
{
2020-12-07 21:04:52 +00:00
foreach (var key in localObjects.Keys)
2020-12-02 12:42:26 +00:00
{
2020-12-07 21:04:52 +00:00
var networkIdentity = localObjects[key];
2020-12-02 12:42:26 +00:00
if (networkIdentity != null && networkIdentity.gameObject != null)
{
if (!InvokeUnSpawnHandler(networkIdentity.AssetId, networkIdentity.gameObject))
{
if (networkIdentity.SceneId.IsEmpty())
{
Object.Destroy(networkIdentity.gameObject);
2020-12-02 12:42:26 +00:00
}
else
{
networkIdentity.MarkForReset();
networkIdentity.gameObject.SetActive(false);
}
}
}
}
2021-06-18 22:39:21 +01:00
2020-12-07 21:04:52 +00:00
ClearLocalObjects();
2020-12-02 12:42:26 +00:00
}
}
}