using UnityEditor; using UnityEngine; using System; using System.Reflection; namespace Project.Editor { internal static class Urp3DWebGlMigration { private const string MigrationVersionKey = "Project.URP3DWebGLMigration.v1"; private const string SettingsFolder = "Assets/Settings"; private const string PipelineAssetPath = SettingsFolder + "/UniversalRP.asset"; private const string RendererAssetPath = SettingsFolder + "/UniversalRenderer.asset"; private const string OldRendererAssetPath = SettingsFolder + "/Renderer2D.asset"; private const string UniversalRuntimeAssembly = "Unity.RenderPipelines.Universal.Runtime"; private const string PipelineAssetTypeName = "UnityEngine.Rendering.Universal.UniversalRenderPipelineAsset"; private const string RendererDataTypeName = "UnityEngine.Rendering.Universal.UniversalRendererData"; [InitializeOnLoadMethod] private static void RunOnLoad() { EditorApplication.delayCall += TryMigrate; } [MenuItem("Tools/Rendering/Run URP 3D WebGL Migration")] private static void RunFromMenu() { SessionState.EraseString(MigrationVersionKey); TryMigrate(); } private static void TryMigrate() { if (SessionState.GetString(MigrationVersionKey, string.Empty) == "done") { return; } SessionState.SetString(MigrationVersionKey, "done"); Type pipelineAssetType = Type.GetType($"{PipelineAssetTypeName}, {UniversalRuntimeAssembly}"); Type rendererDataType = Type.GetType($"{RendererDataTypeName}, {UniversalRuntimeAssembly}"); if (pipelineAssetType == null || rendererDataType == null) { return; } UnityEngine.Object pipelineAsset = AssetDatabase.LoadAssetAtPath(PipelineAssetPath, pipelineAssetType); if (pipelineAsset == null) { return; } UnityEngine.Object rendererData = AssetDatabase.LoadAssetAtPath(RendererAssetPath, rendererDataType); if (rendererData == null) { rendererData = ScriptableObject.CreateInstance(rendererDataType); AssetDatabase.CreateAsset(rendererData, RendererAssetPath); InvokeNonPublicMethod(rendererData, "OnValidate"); } SerializedObject pipelineObject = new SerializedObject(pipelineAsset); pipelineObject.FindProperty("m_RendererType").intValue = 0; pipelineObject.FindProperty("m_RendererData").objectReferenceValue = rendererData; SerializedProperty rendererList = pipelineObject.FindProperty("m_RendererDataList"); rendererList.arraySize = 1; rendererList.GetArrayElementAtIndex(0).objectReferenceValue = rendererData; pipelineObject.FindProperty("m_DefaultRendererIndex").intValue = 0; pipelineObject.ApplyModifiedPropertiesWithoutUndo(); EditorUtility.SetDirty(rendererData); EditorUtility.SetDirty(pipelineAsset); AssetDatabase.SaveAssets(); if (AssetDatabase.LoadAssetAtPath(OldRendererAssetPath) != null) { AssetDatabase.DeleteAsset(OldRendererAssetPath); } } private static void InvokeNonPublicMethod(object target, string methodName) { target.GetType() .GetMethod(methodName, BindingFlags.Instance | BindingFlags.NonPublic) ?.Invoke(target, null); } } }