Added Unity project files
This commit is contained in:
@ -0,0 +1,190 @@
|
||||
using UnityEngine;
|
||||
using VRC.SDKBase;
|
||||
using System.Reflection;
|
||||
using UnityEngine.Rendering.PostProcessing;
|
||||
|
||||
namespace VRC.SDK3.ClientSim
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper for the VRC_SceneDescriptor.
|
||||
/// </summary>
|
||||
public class ClientSimSceneManager : IClientSimSceneManager
|
||||
{
|
||||
// Using a variable here to allow for testability when not on android platform.
|
||||
private bool _isAndroid =
|
||||
#if UNITY_ANDROID
|
||||
true;
|
||||
#else
|
||||
false;
|
||||
#endif
|
||||
|
||||
// Only used for tests to verify android path in copy camera.
|
||||
internal static ClientSimSceneManager CreateTestInstance(bool isAndroid)
|
||||
{
|
||||
return new ClientSimSceneManager { _isAndroid = isAndroid };
|
||||
}
|
||||
|
||||
|
||||
private int _spawnOrder = 0;
|
||||
private VRC_SceneDescriptor _descriptor => VRC_SceneDescriptor.Instance;
|
||||
|
||||
|
||||
public bool HasSceneDescriptor()
|
||||
{
|
||||
return _descriptor != null;
|
||||
}
|
||||
|
||||
public void SetupCamera(Camera camera)
|
||||
{
|
||||
if (!HasSceneDescriptor())
|
||||
{
|
||||
throw new ClientSimException("Cannot get reference camera when there is no scene descriptor.");
|
||||
}
|
||||
|
||||
Camera refCamera = null;
|
||||
if (_descriptor.ReferenceCamera != null)
|
||||
{
|
||||
refCamera = _descriptor.ReferenceCamera.GetComponent<Camera>();
|
||||
}
|
||||
|
||||
if (refCamera != null)
|
||||
{
|
||||
CopyCameraValues(refCamera, camera);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LogWarning("Reference camera is not set in the SceneDescriptor!");
|
||||
|
||||
// Force camera near settings
|
||||
camera.nearClipPlane = Mathf.Clamp(camera.nearClipPlane, 0.01f, 0.05f);
|
||||
}
|
||||
}
|
||||
|
||||
public float GetRespawnHeight()
|
||||
{
|
||||
if (!HasSceneDescriptor())
|
||||
{
|
||||
throw new ClientSimException("Cannot get respawn height when there is no scene descriptor.");
|
||||
}
|
||||
|
||||
return _descriptor.RespawnHeightY;
|
||||
}
|
||||
|
||||
public bool ShouldObjectsDestroyAtRespawnHeight()
|
||||
{
|
||||
if (!HasSceneDescriptor())
|
||||
{
|
||||
throw new ClientSimException("Cannot get respawn height setting when there is no scene descriptor.");
|
||||
}
|
||||
|
||||
return _descriptor.ObjectBehaviourAtRespawnHeight == VRC_SceneDescriptor.RespawnHeightBehaviour.Destroy;
|
||||
}
|
||||
|
||||
public void ResetSpawnOrder()
|
||||
{
|
||||
_spawnOrder = 0;
|
||||
}
|
||||
|
||||
public Transform GetSpawnPoint(bool remote = false)
|
||||
{
|
||||
if (!HasSceneDescriptor())
|
||||
{
|
||||
throw new ClientSimException("Trying to get a Spawn Point but there is no Scene Descriptor. Add a SceneDescriptor or the VRCWorldPrefab to your scene.");
|
||||
}
|
||||
|
||||
if (_descriptor.spawns.Length == 0 || _descriptor.spawns[0] == null)
|
||||
{
|
||||
throw new ClientSimException("Trying to get a Spawn Point but the Scene Descriptor doesn't have one. Add a Transform to the 'Spawns' array in the VRC Scene Descriptor component.");
|
||||
}
|
||||
|
||||
// Remote players always restart the list, so for now, only first spawn
|
||||
if (_descriptor.spawnOrder == VRC_SceneDescriptor.SpawnOrder.First ||
|
||||
_descriptor.spawnOrder == VRC_SceneDescriptor.SpawnOrder.Demo ||
|
||||
remote)
|
||||
{
|
||||
return _descriptor.spawns[0];
|
||||
}
|
||||
if (_descriptor.spawnOrder == VRC_SceneDescriptor.SpawnOrder.Random)
|
||||
{
|
||||
int spawn = Random.Range(0, _descriptor.spawns.Length);
|
||||
return _descriptor.spawns[spawn];
|
||||
}
|
||||
if (_descriptor.spawnOrder == VRC_SceneDescriptor.SpawnOrder.Sequential)
|
||||
{
|
||||
Transform spawn = _descriptor.spawns[_spawnOrder];
|
||||
_spawnOrder = (_spawnOrder + 1) % _descriptor.spawns.Length;
|
||||
return spawn;
|
||||
}
|
||||
|
||||
// Fallback to first spawn point
|
||||
return _descriptor.spawns[0];
|
||||
}
|
||||
|
||||
public Transform GetSpawnPoint(int index)
|
||||
{
|
||||
if (!HasSceneDescriptor())
|
||||
{
|
||||
throw new ClientSimException("Cannot get spawn point when there is no scene descriptor.");
|
||||
}
|
||||
|
||||
if (index < 0 || index >= _descriptor.spawns.Length || _descriptor.spawns[index] == null)
|
||||
{
|
||||
this.LogWarning($"Using spawn point 0 instead of {index}, which is invalid.");
|
||||
index = 0;
|
||||
}
|
||||
|
||||
// Fallback to first spawn point
|
||||
return _descriptor.spawns[index];
|
||||
}
|
||||
|
||||
public float GetSpawnRadius()
|
||||
{
|
||||
if (!HasSceneDescriptor())
|
||||
{
|
||||
throw new ClientSimException("Cannot get spawn radius when there is no scene descriptor.");
|
||||
}
|
||||
|
||||
return _descriptor.spawnRadius;
|
||||
}
|
||||
|
||||
private void CopyCameraValues(Camera refCamera, Camera camera)
|
||||
{
|
||||
if (refCamera == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
camera.farClipPlane = refCamera.farClipPlane;
|
||||
camera.nearClipPlane = Mathf.Clamp(refCamera.nearClipPlane, 0.01f, 0.05f);
|
||||
camera.clearFlags = refCamera.clearFlags;
|
||||
camera.backgroundColor = refCamera.backgroundColor;
|
||||
camera.allowHDR = refCamera.allowHDR;
|
||||
|
||||
PostProcessLayer refPostProcessLayer = refCamera.GetComponent<PostProcessLayer>();
|
||||
if (refPostProcessLayer != null)
|
||||
{
|
||||
if (_isAndroid)
|
||||
{
|
||||
Debug.LogWarning("Post processing is not supported on Android");
|
||||
}
|
||||
else
|
||||
{
|
||||
// VRChatBug: VRChat ignores if the PostProcessingLayer is disabled on the reference camera and always
|
||||
// enables it for the player's camera.
|
||||
PostProcessLayer postProcessLayer = camera.gameObject.AddComponent<PostProcessLayer>();
|
||||
postProcessLayer.volumeLayer = refPostProcessLayer.volumeLayer;
|
||||
|
||||
postProcessLayer.volumeTrigger = refPostProcessLayer.volumeTrigger != refPostProcessLayer.transform
|
||||
? refPostProcessLayer.volumeTrigger
|
||||
: camera.transform;
|
||||
|
||||
// Use reflection to copy over resources : https://github.com/Unity-Technologies/PostProcessing/issues/467
|
||||
FieldInfo resourcesInfo = typeof(PostProcessLayer).GetField("m_Resources", BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
PostProcessResources postProcessResources = resourcesInfo.GetValue(refPostProcessLayer) as PostProcessResources;
|
||||
postProcessLayer.Init(postProcessResources);
|
||||
}
|
||||
}
|
||||
refCamera.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user