void DrawProfileInspectorGUI()
        {
            EditorGUILayout.Space();

            bool assetHasChanged = false;
            bool showCopy        = m_Profile.objectReferenceValue != null;

            // The layout system sort of break alignement when mixing inspector fields with custom
            // layouted fields, do the layout manually instead
            int   buttonWidth    = showCopy ? 45 : 60;
            float indentOffset   = EditorGUI.indentLevel * 15f;
            var   lineRect       = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
            var   labelRect      = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height);
            var   fieldRect      = new Rect(labelRect.xMax, lineRect.y, lineRect.width - labelRect.width - buttonWidth * (showCopy ? 2 : 1), lineRect.height);
            var   buttonNewRect  = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height);
            var   buttonCopyRect = new Rect(buttonNewRect.xMax, lineRect.y, buttonWidth, lineRect.height);

            EditorGUI.PrefixLabel(labelRect, m_ProfileLabel);

            using (var scope = new EditorGUI.ChangeCheckScope())
            {
                m_Profile.objectReferenceValue
                    = (PostProcessProfile)EditorGUI.ObjectField(
                          fieldRect, m_Profile.objectReferenceValue, typeof(PostProcessProfile), false);
                assetHasChanged = scope.changed;
            }

            if (GUI.Button(
                    buttonNewRect,
                    EditorUtilities.GetContent("New|Create a new profile."),
                    showCopy ? EditorStyles.miniButtonLeft : EditorStyles.miniButton))
            {
                // By default, try to put assets in a folder next to the currently active
                // scene file. If the user isn't a scene, put them in root instead.
                var targetName = Target.name;
                var scene      = Target.gameObject.scene;
                var asset      = ProfileFactory.CreatePostProcessProfile(scene, targetName);
                m_Profile.objectReferenceValue = asset;
                assetHasChanged = true;
            }

            if (showCopy && GUI.Button(
                    buttonCopyRect,
                    EditorUtilities.GetContent("Clone|Create a new profile and copy the content of the currently assigned profile."),
                    EditorStyles.miniButtonRight))
            {
                // Duplicate the currently assigned profile and save it as a new profile
                var origin = (PostProcessProfile)m_Profile.objectReferenceValue;
                var path   = AssetDatabase.GetAssetPath(origin);
                path = AssetDatabase.GenerateUniqueAssetPath(path);

                var asset = Instantiate(origin);
                asset.settings.Clear();
                AssetDatabase.CreateAsset(asset, path);

                foreach (var item in origin.settings)
                {
                    var itemCopy = Instantiate(item);
                    itemCopy.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy;
                    itemCopy.name      = item.name;
                    asset.settings.Add(itemCopy);
                    AssetDatabase.AddObjectToAsset(itemCopy, asset);
                }

                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();

                m_Profile.objectReferenceValue = asset;
                assetHasChanged = true;
            }

            if (m_Profile.objectReferenceValue == null)
            {
                if (assetHasChanged && m_EffectList != null)
                {
                    m_EffectList.Clear(); // Asset wasn't null before, do some cleanup
                }
                EditorGUILayout.HelpBox(
                    "Assign an existing Post-process Profile by choosing an asset, or create a new one by clicking the \"New\" button.\nNew assets are automatically put in a folder next to your scene file. If your scene hasn't been saved yet they will be created at the root of the Assets folder.",
                    MessageType.Info);
            }
            else
            {
                if (assetHasChanged)
                {
                    RefreshEffectListEditor((PostProcessProfile)m_Profile.objectReferenceValue);
                }
                if (m_EffectList != null)
                {
                    m_EffectList.OnGUI();
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Manages the adding of components to generated scene objects. Supports generating sub-assets for those components that need them
        /// </summary>
        private static void AddNewComponent(GameObject go, COMPONENT_TYPE type)
        {
            switch (type)
            {
            case COMPONENT_TYPE.CAMERA:
            {
                var cam = go.GetOrAddComponent <Camera>();
                break;
            }

            case COMPONENT_TYPE.AUDIO_LISTENER:
            {
                go.GetOrAddComponent <AudioListener>();
                break;
            }

            case COMPONENT_TYPE.CINEMACHINE_BRAIN:
            {
                go.GetOrAddComponent <CinemachineBrain>();
                break;
            }

            case COMPONENT_TYPE.PLAYABLE_DIRECTOR:
            {
                var pd = go.GetOrAddComponent <PlayableDirector>();
                if (!AssetDatabase.IsValidFolder("Assets/Timeline"))
                {
                    AssetDatabase.CreateFolder("Assets", "Timeline");
                }
                var ta = ScriptableObjectUtility.CreateAssetType <TimelineAsset>("Assets/Timeline", "MasterTimeline.asset");
                pd.playableAsset = ta;
                break;
            }

            case COMPONENT_TYPE.POST_LAYER:
            {
                var post      = go.GetOrAddComponent <PostProcessLayer>();
                var postLayer = 1 << 8;               // post layer is 8 by default
                post.volumeLayer      = postLayer;    // LayerMask.NameToLayer("PostProcessing"); <= this doesn't work for some reason
                post.antialiasingMode = PostProcessLayer.Antialiasing.TemporalAntialiasing;
                break;
            }

            case COMPONENT_TYPE.POST_VOLUME:
            {
                var post = go.GetOrAddComponent <PostProcessVolume>();
                post.isGlobal = true;
                var targetName = go.name;
                var scene      = go.scene;

                // create a new profile
                var asset = ProfileFactory.CreatePostProcessProfile(scene, scene.name);

                // find & load the template
                // FIXME: should allow for user templates as well
                var templatePath = Settings.TEMPLATECONFIGPATH + "Default_Profiles/Default_PostProfile.asset";
                var template     = AssetDatabase.LoadAssetAtPath(templatePath, typeof(PostProcessProfile)) as PostProcessProfile;

                if (template != null)
                {
                    // add all of the settings to the template
                    foreach (var effect in template.settings)
                    {
                        asset.AddSettings(effect);
                    }
                }
                else
                {
                    Debug.Log("Could not find template post profile?");
                }

                post.profile          = asset;
                post.isGlobal         = true;
                post.gameObject.layer = LayerMask.NameToLayer("PostProcessing");
                break;
            }

            case COMPONENT_TYPE.SCENE_VOLUME:
            {
#if USING_HDRP
                var vol = go.GetOrAddComponent <Volume>();
                vol.isGlobal = true;
                var targetName = go.name;
                var scene      = go.scene;

                // FIXME: should load a volume profile from a template &
                // copy the components from one in the package as a base / starting point
                var asset = VolumeProfileFactory.CreateVolumeProfile(scene, targetName);

                vol.profile  = asset;
                vol.isGlobal = true;
#endif
                break;
            }

            case COMPONENT_TYPE.RENDER_SETTINGS:
            {
                var settings = go.GetOrAddComponent <RenderSettings>();
                // add our basic low / high detail levels to start
                var levels = new List <DetailLevel>()
                {
                    new DetailLevel()
                    {
                        name                   = "Low",
                        reflectionProbes       = false,
                        planarReflectionProbes = false,
                    },
                    new DetailLevel()
                    {
                        name                   = "High",
                        reflectionProbes       = true,
                        planarReflectionProbes = true,
                    }
                };

                settings.detailLevels.AddRange(levels);
                break;
            }

            default:
            {
                Debug.Log("unrecognized component type");
                break;
            }
            }
        }