fishnet installed
This commit is contained in:
@ -0,0 +1,159 @@
|
||||
using FishNet.Connection;
|
||||
using FishNet.Managing;
|
||||
using FishNet.Object;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Serialization;
|
||||
|
||||
namespace FishNet.Component.Spawning
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Spawns a player object for clients when they connect.
|
||||
/// Must be placed on or beneath the NetworkManager object.
|
||||
/// </summary>
|
||||
[AddComponentMenu("FishNet/Component/PlayerSpawner")]
|
||||
public class PlayerSpawner : MonoBehaviour
|
||||
{
|
||||
#region Public.
|
||||
/// <summary>
|
||||
/// Called on the server when a player is spawned.
|
||||
/// </summary>
|
||||
public event Action<NetworkObject> OnSpawned;
|
||||
#endregion
|
||||
|
||||
#region Serialized.
|
||||
/// <summary>
|
||||
/// Prefab to spawn for the player.
|
||||
/// </summary>
|
||||
[Tooltip("Prefab to spawn for the player.")]
|
||||
[SerializeField]
|
||||
private NetworkObject _playerPrefab;
|
||||
/// <summary>
|
||||
/// True to add player to the active scene when no global scenes are specified through the SceneManager.
|
||||
/// </summary>
|
||||
[Tooltip("True to add player to the active scene when no global scenes are specified through the SceneManager.")]
|
||||
[SerializeField]
|
||||
private bool _addToDefaultScene = true;
|
||||
/// <summary>
|
||||
/// Areas in which players may spawn.
|
||||
/// </summary>
|
||||
[Tooltip("Areas in which players may spawn.")]
|
||||
[FormerlySerializedAs("_spawns")]
|
||||
public Transform[] Spawns = new Transform[0];
|
||||
#endregion
|
||||
|
||||
#region Private.
|
||||
/// <summary>
|
||||
/// NetworkManager on this object or within this objects parents.
|
||||
/// </summary>
|
||||
private NetworkManager _networkManager;
|
||||
/// <summary>
|
||||
/// Next spawns to use.
|
||||
/// </summary>
|
||||
private int _nextSpawn;
|
||||
#endregion
|
||||
|
||||
private void Start()
|
||||
{
|
||||
InitializeOnce();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (_networkManager != null)
|
||||
_networkManager.SceneManager.OnClientLoadedStartScenes -= SceneManager_OnClientLoadedStartScenes;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes this script for use.
|
||||
/// </summary>
|
||||
private void InitializeOnce()
|
||||
{
|
||||
_networkManager = InstanceFinder.NetworkManager;
|
||||
if (_networkManager == null)
|
||||
{
|
||||
Debug.LogWarning($"PlayerSpawner on {gameObject.name} cannot work as NetworkManager wasn't found on this object or within parent objects.");
|
||||
return;
|
||||
}
|
||||
|
||||
_networkManager.SceneManager.OnClientLoadedStartScenes += SceneManager_OnClientLoadedStartScenes;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a client loads initial scenes after connecting.
|
||||
/// </summary>
|
||||
private void SceneManager_OnClientLoadedStartScenes(NetworkConnection conn, bool asServer)
|
||||
{
|
||||
if (!asServer)
|
||||
return;
|
||||
if (_playerPrefab == null)
|
||||
{
|
||||
Debug.LogWarning($"Player prefab is empty and cannot be spawned for connection {conn.ClientId}.");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 position;
|
||||
Quaternion rotation;
|
||||
SetSpawn(_playerPrefab.transform, out position, out rotation);
|
||||
|
||||
NetworkObject nob = _networkManager.GetPooledInstantiated(_playerPrefab, true);
|
||||
nob.transform.SetPositionAndRotation(position, rotation);
|
||||
_networkManager.ServerManager.Spawn(nob, conn);
|
||||
|
||||
//If there are no global scenes
|
||||
if (_addToDefaultScene)
|
||||
_networkManager.SceneManager.AddOwnerToDefaultScene(nob);
|
||||
|
||||
OnSpawned?.Invoke(nob);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sets a spawn position and rotation.
|
||||
/// </summary>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="rot"></param>
|
||||
private void SetSpawn(Transform prefab, out Vector3 pos, out Quaternion rot)
|
||||
{
|
||||
//No spawns specified.
|
||||
if (Spawns.Length == 0)
|
||||
{
|
||||
SetSpawnUsingPrefab(prefab, out pos, out rot);
|
||||
return;
|
||||
}
|
||||
|
||||
Transform result = Spawns[_nextSpawn];
|
||||
if (result == null)
|
||||
{
|
||||
SetSpawnUsingPrefab(prefab, out pos, out rot);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos = result.position;
|
||||
rot = result.rotation;
|
||||
}
|
||||
|
||||
//Increase next spawn and reset if needed.
|
||||
_nextSpawn++;
|
||||
if (_nextSpawn >= Spawns.Length)
|
||||
_nextSpawn = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets spawn using values from prefab.
|
||||
/// </summary>
|
||||
/// <param name="prefab"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="rot"></param>
|
||||
private void SetSpawnUsingPrefab(Transform prefab, out Vector3 pos, out Quaternion rot)
|
||||
{
|
||||
pos = prefab.position;
|
||||
rot = prefab.rotation;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 211a9f6ec51ddc14f908f5acc0cd0423
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: bf9191e2e07d29749bca3a1ae44e4bc8, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user