1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using UnityEngine;
- namespace UnityEditor.Rendering
- {
- static class ContextualMenuDispatcher
- {
- [MenuItem("CONTEXT/Camera/Remove Component")]
- static void RemoveCameraComponent(MenuCommand command)
- {
- Camera camera = command.context as Camera;
- string error;
- if (!DispatchRemoveComponent(camera))
- {
- //preserve built-in behavior
- if (CanRemoveComponent(camera, out error))
- Undo.DestroyObjectImmediate(command.context);
- else
- EditorUtility.DisplayDialog("Can't remove component", error, "Ok");
- }
- }
- static bool DispatchRemoveComponent<T>(T component)
- where T : Component
- {
- Type type = RenderPipelineEditorUtility.FetchFirstCompatibleTypeUsingScriptableRenderPipelineExtension<IRemoveAdditionalDataContextualMenu<T>>();
- if (type != null)
- {
- IRemoveAdditionalDataContextualMenu<T> instance = (IRemoveAdditionalDataContextualMenu<T>)Activator.CreateInstance(type);
- instance.RemoveComponent(component, ComponentDependencies(component));
- return true;
- }
- return false;
- }
- static IEnumerable<Component> ComponentDependencies(Component component)
- => component.gameObject
- .GetComponents<Component>()
- .Where(c => c != component
- && c.GetType()
- .GetCustomAttributes(typeof(RequireComponent), true)
- .Count(att => att is RequireComponent rc
- && (rc.m_Type0 == component.GetType()
- || rc.m_Type1 == component.GetType()
- || rc.m_Type2 == component.GetType())) > 0);
- static bool CanRemoveComponent(Component component, out string error)
- {
- var dependencies = ComponentDependencies(component);
- if (dependencies.Count() == 0)
- {
- error = null;
- return true;
- }
- Component firstDependency = dependencies.First();
- error = $"Can't remove {component.GetType().Name} because {firstDependency.GetType().Name} depends on it.";
- return false;
- }
- }
- /// <summary>
- /// Interface that should be used with [ScriptableRenderPipelineExtension(type))] attribute to dispatch ContextualMenu calls on the different SRPs
- /// </summary>
- /// <typeparam name="T">This must be a component that require AdditionalData in your SRP</typeparam>
- public interface IRemoveAdditionalDataContextualMenu<T>
- where T : Component
- {
- /// <summary>
- /// Remove the given component
- /// </summary>
- /// <param name="component">The component to remove</param>
- /// <param name="dependencies">Dependencies.</param>
- void RemoveComponent(T component, IEnumerable<Component> dependencies);
- }
- }
|