181 lines
7.6 KiB
C#
181 lines
7.6 KiB
C#
|
|
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
#if UNITY_POST_PROCESSING_STACK_V2
|
|
using UnityEngine.Rendering.PostProcessing;
|
|
#endif
|
|
#if VRC_SDK_VRCSDK3
|
|
using VRC.SDKBase;
|
|
#endif
|
|
|
|
namespace VRWorldToolkit.Editor
|
|
{
|
|
public class PostProcessingTools : MonoBehaviour
|
|
{
|
|
#if VRC_SDK_VRCSDK3
|
|
[MenuItem("VRWorld Toolkit/Post Processing/Setup Post Processing", false, 1)]
|
|
private static void PostProcessingSetup()
|
|
{
|
|
#if UNITY_POST_PROCESSING_STACK_V2
|
|
var sceneDescriptors = FindObjectsOfType(typeof(VRC_SceneDescriptor)) as VRC_SceneDescriptor[];
|
|
var avatarDescriptors = FindObjectsOfType(typeof(VRC_AvatarDescriptor)) as VRC_AvatarDescriptor[];
|
|
|
|
if (UpdateLayers.AreLayersSetup() || EditorUtility.DisplayDialog("Layers Missing!", "You haven't setup the project layers from the VRCSDK Builder tab.\r\n\r\nSelect Continue to set them up now.", "Continue", "Cancel"))
|
|
{
|
|
UpdateLayers.SetupEditorLayers();
|
|
|
|
if (sceneDescriptors.Length == 0)
|
|
{
|
|
if (avatarDescriptors.Length > 0)
|
|
{
|
|
SetupBasicPostProcessing();
|
|
}
|
|
else if (EditorUtility.DisplayDialog("Scene descriptor missing!",
|
|
"No scene descriptor or avatar descriptors was found. A scene descriptor must exist and contain a reference camera for post-processing to appear in-game.\r\n\r\nYou can add a scene descriptor by adding a VRCWorld prefab included with the SDK.\r\n\r\nSelect Cancel to return and add a scene descriptor so the setup can set the reference camera for you, or select Continue to ignore this warning.",
|
|
"Continue",
|
|
"Cancel"))
|
|
{
|
|
SetupBasicPostProcessing();
|
|
}
|
|
}
|
|
else if (sceneDescriptors.Length > 1)
|
|
{
|
|
EditorUtility.DisplayDialog("Multiple scene descriptors!", "Multiple scene descriptors found, remove any you aren't using and run the setup again.", "OK");
|
|
}
|
|
else
|
|
{
|
|
SetupWorldPostProcessing(sceneDescriptors);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
[MenuItem("VRWorld Toolkit/Post Processing/Setup Post Processing", true)]
|
|
private static bool PostProcessingSetupValidation()
|
|
{
|
|
return !(Helper.BuildPlatform() is RuntimePlatform.Android);
|
|
}
|
|
#endif
|
|
|
|
[MenuItem("VRWorld Toolkit/Post Processing/Post Processing Guide", false, 2)]
|
|
private static void PostProcessingGuide()
|
|
{
|
|
Application.OpenURL("https://gitlab.com/s-ilent/SCSS/-/wikis/Other/Post-Processing");
|
|
}
|
|
|
|
private static void SetupBasicPostProcessing()
|
|
{
|
|
GameObject camera = null;
|
|
|
|
if (Camera.main != null)
|
|
{
|
|
camera = Camera.main.gameObject;
|
|
}
|
|
else
|
|
{
|
|
if (EditorUtility.DisplayDialog("No main camera!", "No main camera found in the current scene. The main camera is needed to create the Post Processing Volume.\r\n\r\nSelect Continue to create a new one.", "Continue", "Cancel"))
|
|
{
|
|
camera = Helper.CreateMainCamera();
|
|
}
|
|
}
|
|
|
|
if (camera != null)
|
|
{
|
|
SetupPostProcessingGenerics(camera);
|
|
}
|
|
}
|
|
|
|
#if VRC_SDK_VRCSDK3
|
|
private static void SetupWorldPostProcessing(VRC_SceneDescriptor[] descriptors)
|
|
{
|
|
if (EditorUtility.DisplayDialog("Setup Post Processing?", "This will setup your scenes Reference Camera and make a new global volume using the included example Post Processing Profile.", "OK", "Cancel"))
|
|
{
|
|
var referenceCamera = descriptors.Length > 0 && descriptors[0].ReferenceCamera;
|
|
|
|
GameObject camera = null;
|
|
|
|
if (!referenceCamera && Camera.main is null)
|
|
{
|
|
if (EditorUtility.DisplayDialog("No main camera!", "No main camera found in the current scene. The main camera is needed to create the Post Processing Volume.\r\n\r\nSelect Continue to create a new one.", "Continue", "Cancel"))
|
|
{
|
|
camera = Helper.CreateMainCamera();
|
|
|
|
descriptors[0].ReferenceCamera = camera;
|
|
}
|
|
}
|
|
else if (referenceCamera)
|
|
{
|
|
camera = descriptors[0].ReferenceCamera;
|
|
}
|
|
else if (Camera.main != null)
|
|
{
|
|
camera = Camera.main.gameObject;
|
|
}
|
|
|
|
if (camera != null)
|
|
{
|
|
descriptors[0].ReferenceCamera = camera;
|
|
PrefabUtility.RecordPrefabInstancePropertyModifications(descriptors[0]);
|
|
|
|
SetupPostProcessingGenerics(camera);
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
public static void SetupPostProcessingGenerics(GameObject camera)
|
|
{
|
|
#if UNITY_POST_PROCESSING_STACK_V2
|
|
//Use PostProcessing layer if it exists otherwise use Water
|
|
var layer = LayerMask.NameToLayer("PostProcessing") > -1 ? "PostProcessing" : "Water";
|
|
|
|
//Make sure the Post Process Layer exists and set it up
|
|
if (!camera.GetComponent<PostProcessLayer>())
|
|
camera.AddComponent(typeof(PostProcessLayer));
|
|
var postprocessLayer = camera.GetComponent(typeof(PostProcessLayer)) as PostProcessLayer;
|
|
postprocessLayer.volumeLayer = LayerMask.GetMask(layer);
|
|
|
|
//Copy the example profile to the Post Processing folder
|
|
if (!Directory.Exists("Assets/Post Processing"))
|
|
AssetDatabase.CreateFolder("Assets", "Post Processing");
|
|
if (AssetDatabase.LoadAssetAtPath("Assets/Post Processing/SilentProfile.asset", typeof(PostProcessProfile)) == null)
|
|
{
|
|
var path = AssetDatabase.GetAssetPath(Resources.Load("VRWorldToolkit/PostProcessing/SilentProfile"));
|
|
|
|
if (path != null)
|
|
{
|
|
AssetDatabase.CopyAsset(path, "Assets/Post Processing/SilentProfile.asset");
|
|
}
|
|
}
|
|
|
|
var profileFound = false;
|
|
|
|
//Set up the post process volume
|
|
var volume = Instantiate(PostProcessManager.instance.QuickVolume(16, 100f));
|
|
if (File.Exists("Assets/Post Processing/SilentProfile.asset"))
|
|
{
|
|
volume.sharedProfile = (PostProcessProfile) AssetDatabase.LoadAssetAtPath("Assets/Post Processing/SilentProfile.asset", typeof(PostProcessProfile));
|
|
profileFound = true;
|
|
}
|
|
|
|
// Set volume name and layer
|
|
volume.gameObject.name = "Post Processing Volume";
|
|
volume.gameObject.layer = LayerMask.NameToLayer(layer);
|
|
|
|
// Mark the scene as dirty for saving
|
|
EditorSceneManager.MarkSceneDirty(SceneManager.GetActiveScene());
|
|
|
|
// Set the created volume as active selection in hierarchy
|
|
Selection.activeGameObject = volume.gameObject;
|
|
|
|
// Notify the user if the default profile was not found during setup
|
|
if (!profileFound)
|
|
EditorUtility.DisplayDialog("Default profile not found!", "Default Post Processing Profile was not found during setup, so it was automatically not set in the Post Processing Volume.\n\nCreate your profile to finish the setup.", "Ok");
|
|
#endif
|
|
}
|
|
}
|
|
}
|