1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
|
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
#if VRC_SDK_VRCSDK2
using VRCSDK2;
#endif
#if VRC_SDK_VRCSDK2 || VRC_SDK_VRCSDK3
namespace VRWorldToolkit
{
public class PostProcessingTools : MonoBehaviour
{
[MenuItem("VRWorld Toolkit/Post Processing/Import Post Processing", false, 1)]
private static void PostProcessingInstall()
{
Helper.ImportPackage("com.unity.postprocessing@3.0.3");
}
[MenuItem("VRWorld Toolkit/Post Processing/Import Post Processing", true)]
private static bool PostProcessingInstallValidation()
{
#if UNITY_POST_PROCESSING_STACK_V2
return false;
#else
return true;
#endif
}
[MenuItem("VRWorld Toolkit/Post Processing/Setup Post Processing", false, 12)]
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()
{
#if UNITY_POST_PROCESSING_STACK_V2
return !(Helper.BuildPlatform() is RuntimePlatform.Android);
#else
return false;
#endif
}
[MenuItem("VRWorld Toolkit/Post Processing/Post Processing Guide", false, 13)]
private static void PostProcessingGuide()
{
Application.OpenURL("https://gitlab.com/s-ilent/SCSS/-/wikis/Other/Post-Processing");
}
#if UNITY_POST_PROCESSING_STACK_V2
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);
}
}
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);
}
}
}
public static void SetupPostProcessingGenerics(GameObject camera)
{
//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("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
}
}
#endif
|