static private void Setup_SceneDescriptor()
        {
            var comps = Object.FindObjectsOfType(typeof(VRCSDK2.VRC_SceneDescriptor));

            VRCSDK2.VRC_SceneDescriptor descriptor;
            switch (comps.Length)
            {
            case 0:
                Iwlog.Warn("VRC_SceneDescriptor not found. Create temporary");
                var go = new GameObject("VRC_SceneDescriptor holder");
                descriptor = go.AddComponent <VRCSDK2.VRC_SceneDescriptor>();
                var scene = EditorSceneManager.GetActiveScene();
                EditorSceneManager.MoveGameObjectToScene(go, scene);
                break;

            case 1:
                descriptor = (VRCSDK2.VRC_SceneDescriptor)comps[0];
                break;

            default:
                Iwlog.Warn("Too many VRC_SceneDescriptor found.");
                descriptor = (VRCSDK2.VRC_SceneDescriptor)comps[0];
                break;
            }

            LocalPlayerContext.SceneDescriptor = descriptor;
        }
        private void CopyPostProcessingV2(Camera srcCamera, Camera dstCamera)
        {
            var ppLayerType = Type.GetType("UnityEngine.Rendering.PostProcessing.PostProcessLayer, Unity.Postprocessing.Runtime");

            if (ppLayerType == null)
            {
                Iwlog.Trace("PostProcessing v2 not exists");
            }
            else
            {
                var srcPpLayerComp = srcCamera.GetComponent(ppLayerType);
                if (srcPpLayerComp != null)
                {
                    var dstPpLayerComp = dstCamera.GetComponent(ppLayerType);
                    if (dstPpLayerComp != null)
                    {
                        Iwlog.Warn(dstCamera.gameObject, "Unexpected PostProcessLayer exists.");
                    }
                    else
                    {
                        dstPpLayerComp = dstCamera.gameObject.AddComponent(ppLayerType);
                    }

                    #if UNITY_EDITOR
                    UnityEditor.EditorUtility.CopySerialized(srcPpLayerComp, dstPpLayerComp);
                    #else
                    Iwlog.Error("not implemented for runtime");
                    #endif

                    // replace volumeTrigger if camera itself. (That is usual case)
                    FieldInfo fldInfo = ppLayerType.GetField("volumeTrigger");
                    Assert.IsNotNull(fldInfo);
                    if ((Transform)fldInfo.GetValue(srcPpLayerComp) == srcCamera.transform)
                    {
                        fldInfo.SetValue(dstPpLayerComp, dstCamera.transform);
                    }
                }
            }
        }
        private void CopyCameraSettings(GameObject refCameraObj)
        {
            Camera refCamera = refCameraObj.GetComponent <Camera>();

            if (refCamera == null)
            {
                // VRC_SceneDescriptor.ReferenceCamera is just a GameObject.
                // It could be possible without a Camera component.
                var mes = "Camera not found in VRC_SceneDescriptor.ReferenceCamera.";
                Iwlog.Warn(refCameraObj, mes);
                EditorEnvUtil.ShowNotificationOnGameView(mes);
                return;
            }

            Assert.IsNotNull(playerCamera);

            playerCamera.nearClipPlane   = refCamera.nearClipPlane;
            playerCamera.farClipPlane    = refCamera.farClipPlane;
            playerCamera.clearFlags      = refCamera.clearFlags;
            playerCamera.backgroundColor = refCamera.backgroundColor;
            playerCamera.allowHDR        = refCamera.allowHDR;

            CopyPostProcessingV2(refCamera, playerCamera);
        }