93 lines
3.4 KiB
C#
93 lines
3.4 KiB
C#
using UnityEngine;
|
|
using VRC.SDKBase;
|
|
|
|
namespace VRC.SDK3.ClientSim
|
|
{
|
|
/// <summary>
|
|
/// System that handles spawning new players for ClientSim.
|
|
/// New players will then be initialized through the PlayerManager.
|
|
/// </summary>
|
|
[AddComponentMenu("")]
|
|
public class ClientSimPlayerSpawner : ClientSimBehaviour
|
|
{
|
|
[SerializeField]
|
|
private GameObject localPlayerPrefab;
|
|
[SerializeField]
|
|
private GameObject remotePlayerPrefab;
|
|
|
|
private IClientSimSceneManager _sceneManager;
|
|
private IClientSimPlayerManager _playerManager;
|
|
private IClientSimBlacklistManager _blacklistManager;
|
|
private IClientSimEventDispatcher _eventDispatcher;
|
|
private Transform _parent;
|
|
|
|
public void Initialize(
|
|
IClientSimSceneManager sceneManager,
|
|
IClientSimPlayerManager playerManager,
|
|
IClientSimBlacklistManager blacklistManager,
|
|
IClientSimEventDispatcher eventDispatcher,
|
|
Transform parent)
|
|
{
|
|
_sceneManager = sceneManager;
|
|
_playerManager = playerManager;
|
|
_blacklistManager = blacklistManager;
|
|
_eventDispatcher = eventDispatcher;
|
|
_parent = parent;
|
|
}
|
|
|
|
public static Vector3 GetRandomPositionAroundSpawn(Vector3 spawnPosition, float radius)
|
|
{
|
|
Vector2 randomPosition = Random.insideUnitCircle * radius;
|
|
return new Vector3(randomPosition.x + spawnPosition.x, spawnPosition.y, randomPosition.y + spawnPosition.z);
|
|
}
|
|
|
|
public ClientSimPlayer SpawnPlayer(string playerName, bool isLocal)
|
|
{
|
|
if (!_sceneManager.HasSceneDescriptor())
|
|
{
|
|
throw new ClientSimException("Cannot spawn player if there is no world descriptor!");
|
|
}
|
|
|
|
GameObject playerPrefab = isLocal ? localPlayerPrefab : remotePlayerPrefab;
|
|
if (playerPrefab == null)
|
|
{
|
|
throw new ClientSimException("Failed to spawn player! Player prefab was not found.");
|
|
}
|
|
|
|
Transform spawn = _sceneManager.GetSpawnPoint(!isLocal);
|
|
float radius = _sceneManager.GetSpawnRadius();
|
|
Vector3 position = GetRandomPositionAroundSpawn(spawn.position, radius);
|
|
Quaternion rotation = Quaternion.Euler(0, spawn.rotation.eulerAngles.y, 0);
|
|
|
|
GameObject playerInstance = Instantiate(playerPrefab, position, rotation, _parent);
|
|
|
|
if (_parent == null)
|
|
{
|
|
DontDestroyOnLoad(playerInstance);
|
|
}
|
|
_blacklistManager.AddObjectAndChildrenToBlackList(playerInstance);
|
|
|
|
ClientSimPlayer player = playerInstance.GetComponent<ClientSimPlayer>();
|
|
if (player == null)
|
|
{
|
|
throw new ClientSimException("Failed to spawn player! ClientSimPlayer script was not found.");
|
|
}
|
|
|
|
// PlayerManager will automatically handle sending player join event
|
|
_playerManager.CreateNewPlayer(isLocal, player, playerName);
|
|
|
|
|
|
if (isLocal)
|
|
{
|
|
// Disable player controller until ClientSim is initialized, which is when the player should be able to gain control.
|
|
playerInstance.SetActive(false);
|
|
}
|
|
|
|
player.SetEventDispatcher(_eventDispatcher);
|
|
|
|
return player;
|
|
}
|
|
|
|
|
|
}
|
|
} |