0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Scene View のレンダリングをGame View に合わせる

0
Posted at

editorss0.png

image.png

2D/3Dのシーンを行ったり来たりするような場合、SceneViewはデフォルトのレンダリングのままでGameのセッティングが反映されません。
そんな時はEditorフォルダに下記のスクリプトを用意し、メニューからTools>SetSceneViewRendererTools>を選択することで、SceneViewのレンダリングをGameViewに合わせることができます。

SceneViewRendererSwitcher.cs
using UnityEditor;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public static class SceneViewRendererSwitcher
{
    private const string PipelineAssetPath = "Assets/Settings/UniversalRP.asset";
    private const string UrpSceneViewLimitationMessage = "[SetSceneViewRenderer] URP limitation: SceneView always uses URP default renderer. Switching default renderer index to reflect change in SceneView.";

    [MenuItem("Tools/SetSceneViewRenderer/Match Main Camera Renderer", false, 10)]
    public static void MatchMainCameraRenderer()
    {
        if (!TryGetPipeline(out var pipeline))
        {
            return;
        }

        if (!TryGetMainCameraRendererIndex(pipeline, out var rendererIndex))
        {
            return;
        }

        ApplySceneViewRendererIndex(pipeline, rendererIndex);
    }

    [MenuItem("Tools/SetSceneViewRenderer/Choose Renderer From URP List...", false, 11)]
    public static void OpenRendererPicker()
    {
        if (!TryGetPipeline(out var pipeline))
        {
            return;
        }

        SceneViewRendererPickerWindow.Open(pipeline);
    }

    private static bool TryGetPipeline(out UniversalRenderPipelineAsset pipeline)
    {
        pipeline = AssetDatabase.LoadAssetAtPath<UniversalRenderPipelineAsset>(PipelineAssetPath);
        if (pipeline == null)
        {
            pipeline = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
        }

        if (pipeline != null)
        {
            return true;
        }

        Debug.LogError("[SetSceneViewRenderer] Universal RP asset was not found.");
        return false;
    }

    private static bool TryGetMainCameraRendererIndex(UniversalRenderPipelineAsset pipeline, out int rendererIndex)
    {
        rendererIndex = -1;
        var camera = Camera.main;
        if (camera == null)
        {
            Debug.LogError("[SetSceneViewRenderer] Main Camera was not found.");
            return false;
        }

        var cameraData = camera.GetComponent<UniversalAdditionalCameraData>();
        if (cameraData == null)
        {
            Debug.LogWarning("[SetSceneViewRenderer] Main Camera has no UniversalAdditionalCameraData. Using URP default renderer.");
            return TryGetDefaultRendererIndex(pipeline, out rendererIndex);
        }

        var cameraSo = new SerializedObject(cameraData);
        var cameraRendererIndex = cameraSo.FindProperty("m_RendererIndex");
        if (cameraRendererIndex == null)
        {
            Debug.LogWarning("[SetSceneViewRenderer] Main Camera renderer override property was not found. Using URP default renderer.");
            return TryGetDefaultRendererIndex(pipeline, out rendererIndex);
        }

        rendererIndex = cameraRendererIndex.intValue;
        if (rendererIndex < 0 || !IsRendererIndexValid(pipeline, rendererIndex))
        {
            if (TryGetRendererIndexFromCurrentRenderer(pipeline, cameraData, out var resolvedIndex))
            {
                rendererIndex = resolvedIndex;
                return true;
            }

            return TryGetDefaultRendererIndex(pipeline, out rendererIndex);
        }

        return true;
    }

    private static bool TryGetDefaultRendererIndex(UniversalRenderPipelineAsset pipeline, out int rendererIndex)
    {
        rendererIndex = 0;
        var pipelineSo = new SerializedObject(pipeline);
        var defaultIndex = pipelineSo.FindProperty("m_DefaultRendererIndex");
        if (defaultIndex == null)
        {
            Debug.LogError("[SetSceneViewRenderer] URP default renderer index was not found.");
            return false;
        }

        rendererIndex = defaultIndex.intValue;
        return IsRendererIndexValid(pipeline, rendererIndex);
    }

    internal static void ApplySceneViewRendererIndex(UniversalRenderPipelineAsset pipeline, int rendererIndex)
    {
        if (!IsRendererIndexValid(pipeline, rendererIndex))
        {
            Debug.LogError("[SetSceneViewRenderer] Invalid renderer index.");
            return;
        }

        var pipelineSo = new SerializedObject(pipeline);
        pipelineSo.Update();
        var defaultIndex = pipelineSo.FindProperty("m_DefaultRendererIndex");
        if (defaultIndex == null)
        {
            Debug.LogError("[SetSceneViewRenderer] URP default renderer index was not found.");
            return;
        }

        defaultIndex.intValue = rendererIndex;
        pipelineSo.ApplyModifiedPropertiesWithoutUndo();
        EditorUtility.SetDirty(pipeline);
        AssetDatabase.SaveAssets();

        var rendererData = GetRendererDataAtIndex(pipeline, rendererIndex);
        Debug.Log(UrpSceneViewLimitationMessage);
        Debug.Log($"[SetSceneViewRenderer] Default renderer set to index {rendererIndex}: {rendererData?.name}");

        RepaintSceneViews();
    }

    internal static bool IsRendererIndexValid(UniversalRenderPipelineAsset pipeline, int rendererIndex)
    {
        if (rendererIndex < 0)
        {
            return false;
        }

        var pipelineSo = new SerializedObject(pipeline);
        var rendererList = pipelineSo.FindProperty("m_RendererDataList");
        return rendererList != null && rendererIndex < rendererList.arraySize && rendererList.GetArrayElementAtIndex(rendererIndex).objectReferenceValue != null;
    }

    internal static string[] GetRendererNames(UniversalRenderPipelineAsset pipeline)
    {
        var pipelineSo = new SerializedObject(pipeline);
        var rendererList = pipelineSo.FindProperty("m_RendererDataList");
        if (rendererList == null || rendererList.arraySize == 0)
        {
            return new[] { "No renderers" };
        }

        var names = new string[rendererList.arraySize];
        for (var i = 0; i < rendererList.arraySize; i++)
        {
            var rendererData = rendererList.GetArrayElementAtIndex(i).objectReferenceValue as ScriptableRendererData;
            names[i] = rendererData == null ? $"{i}: Missing" : $"{i}: {rendererData.name} ({rendererData.GetType().Name})";
        }

        return names;
    }

    private static ScriptableRendererData GetRendererDataAtIndex(UniversalRenderPipelineAsset pipeline, int rendererIndex)
    {
        var pipelineSo = new SerializedObject(pipeline);
        var rendererList = pipelineSo.FindProperty("m_RendererDataList");
        if (rendererList == null || rendererIndex < 0 || rendererIndex >= rendererList.arraySize)
        {
            return null;
        }

        return rendererList.GetArrayElementAtIndex(rendererIndex).objectReferenceValue as ScriptableRendererData;
    }

    private static int GetCurrentSceneViewRendererIndex(UniversalRenderPipelineAsset pipeline)
    {
        return GetSafePipelineDefaultIndex(pipeline);
    }

    private static int GetSafePipelineDefaultIndex(UniversalRenderPipelineAsset pipeline)
    {
        return TryGetDefaultRendererIndex(pipeline, out var rendererIndex) ? rendererIndex : 0;
    }

    private static bool TryGetRendererIndexFromCurrentRenderer(UniversalRenderPipelineAsset pipeline, UniversalAdditionalCameraData cameraData, out int rendererIndex)
    {
        rendererIndex = -1;
        if (cameraData == null || cameraData.scriptableRenderer == null)
        {
            return false;
        }

        var targetRendererType = cameraData.scriptableRenderer.GetType();
        var pipelineSo = new SerializedObject(pipeline);
        var rendererList = pipelineSo.FindProperty("m_RendererDataList");
        if (rendererList == null)
        {
            return false;
        }

        for (var i = 0; i < rendererList.arraySize; i++)
        {
            var rendererData = rendererList.GetArrayElementAtIndex(i).objectReferenceValue as ScriptableRendererData;
            if (rendererData == null)
            {
                continue;
            }

            if (RendererDataMatchesRendererType(rendererData, targetRendererType))
            {
                rendererIndex = i;
                return true;
            }
        }

        return false;
    }

    private static bool RendererDataMatchesRendererType(ScriptableRendererData rendererData, System.Type rendererType)
    {
        if (rendererData == null || rendererType == null)
        {
            return false;
        }

        if (rendererData is Renderer2DData)
        {
            return rendererType.Name.Contains("Renderer2D");
        }

        if (rendererData is UniversalRendererData)
        {
            return rendererType.Name.Contains("UniversalRenderer");
        }

        return false;
    }

    private static bool TryGetSceneViews(out SceneView[] sceneViews)
    {
        sceneViews = Resources.FindObjectsOfTypeAll<SceneView>();
        if (sceneViews == null || sceneViews.Length == 0)
        {
            Debug.LogError("[SetSceneViewRenderer] No SceneView window was found.");
            return false;
        }

        return true;
    }

    private static void RepaintSceneViews()
    {
        if (!TryGetSceneViews(out var sceneViews))
        {
            return;
        }

        for (var i = 0; i < sceneViews.Length; i++)
        {
            sceneViews[i].sceneLighting = true;
            sceneViews[i].Repaint();
        }
    }

    private sealed class SceneViewRendererPickerWindow : EditorWindow
    {
        private UniversalRenderPipelineAsset pipeline;
        private string[] rendererNames;
        private int selectedIndex;

        internal static void Open(UniversalRenderPipelineAsset targetPipeline)
        {
            var window = GetWindow<SceneViewRendererPickerWindow>(true, "Set Scene View Renderer");
            window.minSize = new Vector2(520f, 90f);
            window.pipeline = targetPipeline;
            window.rendererNames = GetRendererNames(targetPipeline);
            window.selectedIndex = GetSafeSelectedIndex(targetPipeline, window.rendererNames.Length);
            window.Show();
        }

        private void OnGUI()
        {
            if (pipeline == null)
            {
                EditorGUILayout.HelpBox("Universal RP asset could not be loaded.", MessageType.Error);
                return;
            }

            EditorGUILayout.LabelField("Renderer From Assets/Settings/UniversalRP.asset", EditorStyles.boldLabel);
            selectedIndex = EditorGUILayout.Popup("Renderer", selectedIndex, rendererNames);

            using (new EditorGUILayout.HorizontalScope())
            {
                if (GUILayout.Button("Apply"))
                {
                    ApplySceneViewRendererIndex(pipeline, selectedIndex);
                    Close();
                }

                if (GUILayout.Button("Cancel"))
                {
                    Close();
                }
            }
        }

        private static int GetSafeSelectedIndex(UniversalRenderPipelineAsset targetPipeline, int maxLength)
        {
            var index = GetCurrentSceneViewRendererIndex(targetPipeline);
            if (index < 0 || index >= maxLength)
            {
                return 0;
            }

            return index;
        }
    }
}

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?