diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/SubWindowTests.cs b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/SubWindowTests.cs new file mode 100644 index 00000000000..d93f30bf6dd --- /dev/null +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/SubWindowTests.cs @@ -0,0 +1,222 @@ +using System.Collections; +using NUnit.Framework; +using UnityEditor.Experimental.GraphView; +using UnityEditor.ShaderGraph.Drawing; +using UnityEditor.ShaderGraph.Drawing.Inspector; +using System.Reflection; +using UnityEngine; +using UnityEngine.TestTools; +using UnityEngine.UIElements; + +/* Changes: + * Made ShaderGraphImporterEditor.ShowGraphEditWindow public + * Made MaterialGraphEditWindow.graphEditorView public + * Altered MasterPreviewView.OnMouseDragPreviewMesh slightly + */ + +namespace UnityEditor.ShaderGraph.UnitTests +{ + [TestFixture] + internal class SubWindowTests + { + static string kGraphName = "Assets/CommonAssets/Graphs/SubWindow.shadergraph"; + + GraphEditorView m_GraphEditorView; + MaterialGraphEditWindow m_Window; + + [SetUp] + public void OpenGraphWindow() + { + // Open up the window + if (!ShaderGraphImporterEditor.ShowGraphEditWindow(kGraphName)) + { + Assert.Fail("ShaderGraphImporterEditor.ShowGraphEditWindow could not open " + kGraphName); + } + + m_Window = EditorWindow.GetWindow(); + + if (m_Window == null) + { + Assert.Fail("Could not open window"); + } + + // EditorWindow.GetWindow will return a new window if one is not found. A new window will have graphObject == null. + if (m_Window.graphObject == null) + { + Assert.Fail("Existing Shader Graph window of " + kGraphName + " not found."); + } + + m_GraphEditorView = m_Window.graphEditorView; + } + + [TearDown] + public void CloseGraphWindow() + { + m_Window.graphObject = null; // Don't spawn ask-to-save dialog + m_Window.Close(); + } + + private void ToggleSubWindows(bool showBlackboard, bool showPreview) + { + m_GraphEditorView.viewSettings.isBlackboardVisible = showBlackboard; + m_GraphEditorView.viewSettings.isPreviewVisible = showPreview; + + m_GraphEditorView.UserViewSettingsChangeCheck(0); + } + + // Tests that we the user can toggle the SubWindows + // The repeating Q<...>ing is done deliberately: to confirm that it's still in the graph view. + [UnityTest] + public IEnumerator CanToggleSubWindows() + { + // Both + ToggleSubWindows(true, true); + + yield return null; + + Assert.That(m_GraphEditorView.Q().enabledInHierarchy, Is.True, "Blackboard is not visible when it should be. (1st pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.True, "MasterPreviewView is not visible when it should be. (1st pass)"); + + yield return null; + + // Neither + ToggleSubWindows(false, false); + + yield return null; + + Assert.That(m_GraphEditorView.Q(), Is.Null, "Blackboard remained visible when it should not be. (2nd pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.False, "MasterPreviewView remained visible when it should not be. (2nd pass)"); + + yield return null; + + // Blackboard Only + ToggleSubWindows(true, false); + + yield return null; + + Assert.That(m_GraphEditorView.Q().enabledInHierarchy, Is.True, "Blackboard is not visible when it should be. (3rd pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.False, "MasterPreviewView remained visible when it should not be. (3rd pass)"); + + // Preview Only + ToggleSubWindows(false, true); + + yield return null; + + Assert.That(m_GraphEditorView.Q(), Is.Null, "Blackboard remained visible when it should not be. (4th pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.True, "MasterPreviewView is not visible when it should be. (4th pass)"); + + yield return null; + } + + private IEnumerator ToggleSubWindowsThenCloseThenReopen(bool showBlackboard, bool showPreview) + { + ToggleSubWindows(showBlackboard, showPreview); + yield return null; + + CloseGraphWindow(); + yield return null; + + OpenGraphWindow(); + yield return null; + } + + // Tests that the Sub Window status is remembered when closing and reopening Shader Graphs. + // The repeating Q<...>ing is done deliberately: to confirm that it's still in the graph view. + [UnityTest] + public IEnumerator SubWindowStatusRememberedAfterCloseAndReopen() + { + yield return ToggleSubWindowsThenCloseThenReopen(true, true); + + Assert.That(m_GraphEditorView.Q().enabledInHierarchy, Is.True, "Blackboard is NOT visible when it should be. (1st pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.True, "MasterPreviewView is NOT visible when it should be. (1st pass)"); + + yield return ToggleSubWindowsThenCloseThenReopen(true, true); + + Assert.That(m_GraphEditorView.Q().enabledInHierarchy, Is.True, "Blackboard is NOT visible when it should be. (2nd pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.True, "MasterPreviewView is NOT visible when it should be. (2nd pass)"); + + yield return ToggleSubWindowsThenCloseThenReopen(true, false); + + Assert.That(m_GraphEditorView.Q().enabledInHierarchy, Is.True, "Blackboard is NOT visible when it should be. (3rd pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.False, "MasterPreviewView IS visible when it should not be. (3rd pass)"); + + yield return ToggleSubWindowsThenCloseThenReopen(true, false); + + Assert.That(m_GraphEditorView.Q().enabledInHierarchy, Is.True, "Blackboard is NOT visible when it should be. (4th pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.False, "MasterPreviewView IS visible when it should not be. (4th pass)"); + + yield return ToggleSubWindowsThenCloseThenReopen(false, true); + + Assert.That(m_GraphEditorView.Q(), Is.Null, "Blackboard IS visible when it should not be. (5th pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.True, "MasterPreviewView is NOT visible when it should not (5th pass)be."); + + yield return ToggleSubWindowsThenCloseThenReopen(false, true); + + Assert.That(m_GraphEditorView.Q(), Is.Null, "Blackboard IS visible when it should not be. (6th pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.True, "MasterPreviewView is NOT visible when it should not (6th pass)be."); + + yield return ToggleSubWindowsThenCloseThenReopen(false, false); + + Assert.That(m_GraphEditorView.Q(), Is.Null, "Blackboard IS visible when it should not be. (7th pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.False, "MasterPreviewView IS visible when it should not be. (7th pass)"); + + yield return ToggleSubWindowsThenCloseThenReopen(false, false); + + Assert.That(m_GraphEditorView.Q(), Is.Null, "Blackboard IS visible when it should not be. (8th pass)"); + Assert.That(m_GraphEditorView.Q().visible, Is.False, "MasterPreviewView IS visible when it should not be. (8th pass)"); + } + + // [UnityTest] + // public IEnumerator SubWindowLocationRememberedAfterCloseAndReopen() + // { + // yield return TestBlackboardLocation(new Rect(50.0f, 50.0f, 160.0f, 160.0f)); + // yield return TestBlackboardLocation(new Rect(80050.0f, 50.0f, 220.0f, 240.0f)); + // yield return TestBlackboardLocation(new Rect(50.0f, 90050.0f, 220.0f, 240.0f)); + // yield return TestBlackboardLocation(new Rect(80050.0f, 90050.0f, 220.0f, 240.0f)); + // yield return TestBlackboardLocation(new Rect(50.0f, -50.0f, 230.0f, 230.0f)); + // } + // Test does not pass when run in batchmode on yamato, needs more investigation to re-enable + + // Only works for Blackboard... for now. (Plan is to make Internal Inspector, Blackboard 2.0, and MasterPreview use the same SubWindow class someday) + private IEnumerator TestBlackboardLocation(Rect blackboardRect) + { + ToggleSubWindows(true, true); + + Blackboard blackboard = m_GraphEditorView.blackboardProvider.blackboard; + MasterPreviewView masterPreviewView = m_GraphEditorView.Q(); + + blackboard.SetPosition(blackboardRect); + yield return null; + + CloseGraphWindow(); + yield return null; + OpenGraphWindow(); + yield return null; + + blackboard = m_GraphEditorView.blackboardProvider.blackboard; + + // Keep inside the GraphEditor in the same way as expected + Rect editorViewContainer = m_GraphEditorView.graphView.contentContainer.layout; + Rect blackboardRectBefore = blackboardRect; + if (blackboardRect.x + blackboardRect.width > editorViewContainer.width) + blackboardRect.x = editorViewContainer.width - blackboardRect.width; + if (blackboardRect.y + blackboardRect.height > editorViewContainer.height) + blackboardRect.y = editorViewContainer.height - blackboardRect.height; + if (blackboardRect.x < 0) + blackboardRect.x = 0; + if (blackboardRect.y < 0) + blackboardRect.y = 0; + + // Using approximately instead of exact comparisons, which is why we don't use (blackboard.layout == blackboardRect) + Assert.That(Mathf.Approximately(blackboard.layout.x, blackboardRect.x), "Blackboard did not remember location, x differs: " + + "m_GraphEditorView.layout=" + m_GraphEditorView.layout + " blackboard.layout=" + blackboard.layout + " blackboardRect=" + blackboardRect + " blackboardRectPreModification=" + blackboardRectBefore); + Assert.That(Mathf.Approximately(blackboard.layout.y, blackboardRect.y), "Blackboard did not remember location, y differs: " + + "m_GraphEditorView.layout=" + m_GraphEditorView.layout + " blackboard.layout=" + blackboard.layout + " blackboardRect=" + blackboardRect + " blackboardRectPreModification=" + blackboardRectBefore); + Assert.That(Mathf.Approximately(blackboard.layout.width, blackboardRect.width), "Blackboard did not remember width: " + + "m_GraphEditorView.layout=" + m_GraphEditorView.layout + " blackboard.layout=" + blackboard.layout + " blackboardRect=" + blackboardRect + " blackboardRectPreModification=" + blackboardRectBefore); + Assert.That(Mathf.Approximately(blackboard.layout.height, blackboardRect.height), "Blackboard did not remember height: " + + "m_GraphEditorView.layout=" + m_GraphEditorView.layout + " blackboard.layout=" + blackboard.layout + " blackboardRect=" + blackboardRect + " blackboardRectPreModification=" + blackboardRectBefore); + } + + } +} diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/SubWindowTests.cs.meta b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/SubWindowTests.cs.meta new file mode 100644 index 00000000000..6daa1b5c509 --- /dev/null +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/SubWindowTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f3279de49ed10ec448630911004c39ec +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/TestAssemblyExtensions.cs b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/TestAssemblyExtensions.cs new file mode 100644 index 00000000000..5fb81a586c9 --- /dev/null +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/TestAssemblyExtensions.cs @@ -0,0 +1,76 @@ +using System; +using System.Reflection; + +namespace UnityEditor.ShaderGraph.UnitTests +{ + public static class TestAssemblyExtensions + { + private const BindingFlags privateBindingFlags = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy; + public static void InvokePrivateAction(this object obj, string methodName, object[] parameters = null) => GetMethod(obj, methodName).Invoke(obj, parameters); + private static MethodInfo GetMethod(object obj, string methodName) + { + MethodInfo method = GetMethodRecursive(obj.GetType(), methodName); + if (method == null) + throw new System.Exception($"Unnable to find private method {methodName} in class {obj.GetType().ToString()}"); + return method; + } + private static MethodInfo GetMethodRecursive(Type type, string methodName) + { + MethodInfo method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance); + if (method == null && type.BaseType != null) + return GetMethodRecursive(type.BaseType, methodName); + return method; + } + + public static void InvokePrivateFunc(this object obj, string methodName, object[] parameters = null) + { + GetMethod(obj, methodName).Invoke(obj, parameters); + } + + public static T InvokePrivateFunc(this object obj, string methodName, object[] parameters = null) + { + object value = GetMethod(obj, methodName).Invoke(obj, parameters); + return TryConvertValueToType(value, methodName); + } + private static T TryConvertValueToType(object input, string name) + { + T output = default; + try { output = (T)input; } + catch { throw new System.ArgumentException($"Unnable to convert {name} to type of {output.GetType().ToString()}"); } + return output; + } + + public static void SetPrivateField(this object obj, string fieldName, object value) + { + FieldInfo fieldInfo = GetField(obj, fieldName, privateBindingFlags); + fieldInfo.SetValue(obj, value); + } + public static T GetPrivateField(this object obj, string fieldName) + { + object value = GetField(obj, fieldName, privateBindingFlags).GetValue(obj); + return TryConvertValueToType(value, fieldName); + } + private static FieldInfo GetField(object obj, string fieldName, BindingFlags bindingFlags) + { + FieldInfo field = obj.GetType().GetField(fieldName, bindingFlags); + if (field == null) + throw new System.Exception($"Unnable to find field {fieldName} in class {obj.GetType().ToString()} with binding flags {bindingFlags}"); + return field; + } + + public static T GetPrivateProperty(this object obj, string propertyName) + { + object value = GetProperty(obj, propertyName, privateBindingFlags).GetValue(obj); + return TryConvertValueToType(value, propertyName); + } + + private static PropertyInfo GetProperty(object obj, string propertyName, BindingFlags bindingFlags) + { + PropertyInfo property = obj.GetType().GetProperty(propertyName, bindingFlags); + if(property == null) + throw new System.Exception($"Unnable to find private property {propertyName} in class {obj.GetType().ToString()} with binding flags {bindingFlags}"); + return property; + } + + } +} diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/TestAssemblyExtensions.cs.meta b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/TestAssemblyExtensions.cs.meta new file mode 100644 index 00000000000..eeeb99a5dbd --- /dev/null +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Editor/TestAssemblyExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a29bccf868ef4484db11a1f4025c60d2 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Graphs/SubWindow.shadergraph b/TestProjects/ShaderGraph/Assets/CommonAssets/Graphs/SubWindow.shadergraph new file mode 100644 index 00000000000..a639e051cfc --- /dev/null +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Graphs/SubWindow.shadergraph @@ -0,0 +1,65 @@ +{ + "m_SerializedProperties": [ + { + "typeInfo": { + "fullName": "UnityEditor.ShaderGraph.Internal.Texture2DShaderProperty" + }, + "JSONnodeData": "{\n \"m_Guid\": {\n \"m_GuidSerialized\": \"de3b706d-3716-41fc-bb69-5fe762e2af37\"\n },\n \"m_Name\": \"Texture2D\",\n \"m_DefaultReferenceName\": \"Texture2D_1AF14AE5\",\n \"m_OverrideReferenceName\": \"\",\n \"m_GeneratePropertyBlock\": true,\n \"m_Precision\": 0,\n \"m_GPUInstanced\": false,\n \"m_Hidden\": false,\n \"m_Value\": {\n \"m_SerializedTexture\": \"{\\\"texture\\\":{\\\"fileID\\\":2800000,\\\"guid\\\":\\\"17c8e6ca2c91eba44aa7c73b1ee3002e\\\",\\\"type\\\":3}}\",\n \"m_Guid\": \"\"\n },\n \"m_Modifiable\": true,\n \"m_DefaultType\": 0\n}" + } + ], + "m_SerializedKeywords": [], + "m_SerializableNodes": [ + { + "typeInfo": { + "fullName": "UnityEditor.ShaderGraph.PropertyNode" + }, + "JSONnodeData": "{\n \"m_GuidSerialized\": \"06ac1f44-47d5-45c1-8de3-b1d3d7b796fa\",\n \"m_GroupGuidSerialized\": \"00000000-0000-0000-0000-000000000000\",\n \"m_Name\": \"Property\",\n \"m_NodeVersion\": 0,\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": -278.0,\n \"y\": 125.33334350585938,\n \"width\": 139.99998474121095,\n \"height\": 34.0\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Texture2DMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Texture2D\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Out\\\",\\n \\\"m_StageCapability\\\": 3\\n}\"\n }\n ],\n \"m_Precision\": 0,\n \"m_PreviewExpanded\": true,\n \"m_CustomColors\": {\n \"m_SerializableColors\": []\n },\n \"m_PropertyGuidSerialized\": \"de3b706d-3716-41fc-bb69-5fe762e2af37\"\n}" + }, + { + "typeInfo": { + "fullName": "UnityEditor.ShaderGraph.PBRMasterNode" + }, + "JSONnodeData": "{\n \"m_GuidSerialized\": \"48954da0-91a0-4bd6-8bf2-d7cb3dd8c87b\",\n \"m_GroupGuidSerialized\": \"d3d13f39-4721-493d-924c-fc049ec19fa9\",\n \"m_Name\": \"PBR Master\",\n \"m_NodeVersion\": 0,\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": 223.3333740234375,\n \"y\": 42.0,\n \"width\": 199.99998474121095,\n \"height\": 317.3333435058594\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.PositionMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 9,\\n \\\"m_DisplayName\\\": \\\"Vertex Position\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Vertex Position\\\",\\n \\\"m_StageCapability\\\": 1,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\"\\n ],\\n \\\"m_Space\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.NormalMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 10,\\n \\\"m_DisplayName\\\": \\\"Vertex Normal\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Vertex Normal\\\",\\n \\\"m_StageCapability\\\": 1,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\"\\n ],\\n \\\"m_Space\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.TangentMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 11,\\n \\\"m_DisplayName\\\": \\\"Vertex Tangent\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Vertex Tangent\\\",\\n \\\"m_StageCapability\\\": 1,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\"\\n ],\\n \\\"m_Space\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.ColorRGBMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"Albedo\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Albedo\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.7353569269180298,\\n \\\"y\\\": 0.7353569269180298,\\n \\\"z\\\": 0.7353569269180298\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\"\\n ],\\n \\\"m_ColorMode\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.NormalMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"Normal\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Normal\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\"\\n ],\\n \\\"m_Space\\\": 3\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.ColorRGBMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 4,\\n \\\"m_DisplayName\\\": \\\"Emission\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Emission\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\",\\n \\\"Z\\\"\\n ],\\n \\\"m_ColorMode\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"Metallic\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Metallic\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.0,\\n \\\"m_DefaultValue\\\": 0.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 5,\\n \\\"m_DisplayName\\\": \\\"Smoothness\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Smoothness\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.5,\\n \\\"m_DefaultValue\\\": 0.5,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 6,\\n \\\"m_DisplayName\\\": \\\"Occlusion\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Occlusion\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 1.0,\\n \\\"m_DefaultValue\\\": 1.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 7,\\n \\\"m_DisplayName\\\": \\\"Alpha\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Alpha\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 1.0,\\n \\\"m_DefaultValue\\\": 1.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 8,\\n \\\"m_DisplayName\\\": \\\"AlphaClipThreshold\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"AlphaClipThreshold\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.5,\\n \\\"m_DefaultValue\\\": 0.5,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n }\n ],\n \"m_Precision\": 0,\n \"m_PreviewExpanded\": true,\n \"m_CustomColors\": {\n \"m_SerializableColors\": []\n },\n \"m_DOTSInstancing\": false,\n \"m_SerializableSubShaders\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.Rendering.Universal.UniversalPBRSubShader\"\n },\n \"JSONnodeData\": \"{}\"\n }\n ],\n \"m_Model\": 1,\n \"m_SurfaceType\": 0,\n \"m_AlphaMode\": 0,\n \"m_TwoSided\": false,\n \"m_NormalDropOffSpace\": 0\n}" + }, + { + "typeInfo": { + "fullName": "UnityEditor.ShaderGraph.SampleTexture2DNode" + }, + "JSONnodeData": "{\n \"m_GuidSerialized\": \"d60324ee-94d8-43a4-8ec1-619aef7e84fd\",\n \"m_GroupGuidSerialized\": \"00000000-0000-0000-0000-000000000000\",\n \"m_Name\": \"Sample Texture 2D\",\n \"m_NodeVersion\": 0,\n \"m_DrawState\": {\n \"m_Expanded\": true,\n \"m_Position\": {\n \"serializedVersion\": \"2\",\n \"x\": -122.0,\n \"y\": 113.33334350585938,\n \"width\": 208.0,\n \"height\": 435.3333740234375\n }\n },\n \"m_SerializableSlots\": [\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector4MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 0,\\n \\\"m_DisplayName\\\": \\\"RGBA\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"RGBA\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0,\\n \\\"z\\\": 0.0,\\n \\\"w\\\": 0.0\\n }\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 4,\\n \\\"m_DisplayName\\\": \\\"R\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"R\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.0,\\n \\\"m_DefaultValue\\\": 0.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 5,\\n \\\"m_DisplayName\\\": \\\"G\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"G\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.0,\\n \\\"m_DefaultValue\\\": 0.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 6,\\n \\\"m_DisplayName\\\": \\\"B\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"B\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.0,\\n \\\"m_DefaultValue\\\": 0.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Vector1MaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 7,\\n \\\"m_DisplayName\\\": \\\"A\\\",\\n \\\"m_SlotType\\\": 1,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"A\\\",\\n \\\"m_StageCapability\\\": 2,\\n \\\"m_Value\\\": 0.0,\\n \\\"m_DefaultValue\\\": 0.0,\\n \\\"m_Labels\\\": [\\n \\\"X\\\"\\n ]\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.Texture2DInputMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 1,\\n \\\"m_DisplayName\\\": \\\"Texture\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Texture\\\",\\n \\\"m_StageCapability\\\": 3,\\n \\\"m_Texture\\\": {\\n \\\"m_SerializedTexture\\\": \\\"{\\\\\\\"texture\\\\\\\":{\\\\\\\"instanceID\\\\\\\":0}}\\\",\\n \\\"m_Guid\\\": \\\"\\\"\\n },\\n \\\"m_DefaultType\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.UVMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 2,\\n \\\"m_DisplayName\\\": \\\"UV\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"UV\\\",\\n \\\"m_StageCapability\\\": 3,\\n \\\"m_Value\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0\\n },\\n \\\"m_DefaultValue\\\": {\\n \\\"x\\\": 0.0,\\n \\\"y\\\": 0.0\\n },\\n \\\"m_Labels\\\": [\\n \\\"X\\\",\\n \\\"Y\\\"\\n ],\\n \\\"m_Channel\\\": 0\\n}\"\n },\n {\n \"typeInfo\": {\n \"fullName\": \"UnityEditor.ShaderGraph.SamplerStateMaterialSlot\"\n },\n \"JSONnodeData\": \"{\\n \\\"m_Id\\\": 3,\\n \\\"m_DisplayName\\\": \\\"Sampler\\\",\\n \\\"m_SlotType\\\": 0,\\n \\\"m_Priority\\\": 2147483647,\\n \\\"m_Hidden\\\": false,\\n \\\"m_ShaderOutputName\\\": \\\"Sampler\\\",\\n \\\"m_StageCapability\\\": 3\\n}\"\n }\n ],\n \"m_Precision\": 0,\n \"m_PreviewExpanded\": true,\n \"m_CustomColors\": {\n \"m_SerializableColors\": []\n },\n \"m_TextureType\": 0,\n \"m_NormalMapSpace\": 0\n}" + } + ], + "m_Groups": [ + { + "m_GuidSerialized": "d3d13f39-4721-493d-924c-fc049ec19fa9", + "m_Title": "Simple Graph", + "m_Position": { + "x": 49.3333740234375, + "y": -6.0 + } + } + ], + "m_StickyNotes": [], + "m_SerializableEdges": [ + { + "typeInfo": { + "fullName": "UnityEditor.Graphing.Edge" + }, + "JSONnodeData": "{\n \"m_OutputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"06ac1f44-47d5-45c1-8de3-b1d3d7b796fa\"\n },\n \"m_InputSlot\": {\n \"m_SlotId\": 1,\n \"m_NodeGUIDSerialized\": \"d60324ee-94d8-43a4-8ec1-619aef7e84fd\"\n }\n}" + }, + { + "typeInfo": { + "fullName": "UnityEditor.Graphing.Edge" + }, + "JSONnodeData": "{\n \"m_OutputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"d60324ee-94d8-43a4-8ec1-619aef7e84fd\"\n },\n \"m_InputSlot\": {\n \"m_SlotId\": 0,\n \"m_NodeGUIDSerialized\": \"48954da0-91a0-4bd6-8bf2-d7cb3dd8c87b\"\n }\n}" + } + ], + "m_PreviewData": { + "serializedMesh": { + "m_SerializedMesh": "{\"mesh\":{\"fileID\":10200,\"guid\":\"0000000000000000e000000000000000\",\"type\":0}}", + "m_Guid": "" + } + }, + "m_Path": "Shader Graphs", + "m_ConcretePrecision": 0, + "m_ActiveOutputNodeGuidSerialized": "48954da0-91a0-4bd6-8bf2-d7cb3dd8c87b" +} \ No newline at end of file diff --git a/TestProjects/ShaderGraph/Assets/CommonAssets/Graphs/SubWindow.shadergraph.meta b/TestProjects/ShaderGraph/Assets/CommonAssets/Graphs/SubWindow.shadergraph.meta new file mode 100644 index 00000000000..1432fda1f61 --- /dev/null +++ b/TestProjects/ShaderGraph/Assets/CommonAssets/Graphs/SubWindow.shadergraph.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 82d602e040685b94289eda9596b97ce0 +ScriptedImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 2 + userData: + assetBundleName: + assetBundleVariant: + script: {fileID: 11500000, guid: 625f186215c104763be7675aa2d941aa, type: 3} diff --git a/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs b/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs index d870246adc0..a39ff510097 100644 --- a/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs +++ b/com.unity.shadergraph/Editor/Drawing/Blackboard/BlackboardProvider.cs @@ -255,7 +255,9 @@ void EditTextRequested(Blackboard blackboard, VisualElement visualElement, strin public void HandleGraphChanges(bool wasUndoRedoPerformed) { - var selection = new List(blackboard.selection); + var selection = new List(); + if(blackboard.selection != null) + selection.Concat(blackboard.selection); foreach (var inputGuid in m_Graph.removedInputs) { @@ -275,7 +277,7 @@ public void HandleGraphChanges(bool wasUndoRedoPerformed) foreach (var item in selection) { if (item is BlackboardFieldView blackboardFieldView) - { + { var guid = blackboardFieldView.shaderInput.referenceName; oldSelectionPersistenceData.Add(guid, blackboardFieldView.viewDataKey); } diff --git a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs index 5066b690e11..109e7abd146 100644 --- a/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs +++ b/com.unity.shadergraph/Editor/Drawing/MaterialGraphEditWindow.cs @@ -56,10 +56,10 @@ MessageManager messageManager } GraphEditorView m_GraphEditorView; - GraphEditorView graphEditorView + internal GraphEditorView graphEditorView { get { return m_GraphEditorView; } - set + private set { if (m_GraphEditorView != null) { @@ -84,7 +84,7 @@ GraphEditorView graphEditorView } } - GraphObject graphObject + internal GraphObject graphObject { get { return m_GraphObject; } set diff --git a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs index 36974390f13..324546bf7b1 100644 --- a/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs +++ b/com.unity.shadergraph/Editor/Drawing/Views/GraphEditorView.cs @@ -60,6 +60,8 @@ public BlackboardProvider blackboardProvider const string k_UserViewSettings = "UnityEditor.ShaderGraph.ToggleSettings"; UserViewSettings m_UserViewSettings; + internal UserViewSettings viewSettings { get => m_UserViewSettings; } + const string k_FloatingWindowsLayoutKey = "UnityEditor.ShaderGraph.FloatingWindowsLayout2"; FloatingWindowsLayout m_FloatingWindowsLayout; @@ -207,7 +209,7 @@ public GraphEditorView(EditorWindow editorWindow, GraphData graph, MessageManage EditorGUI.BeginChangeCheck(); GUILayout.Label("Color Mode"); - var newColorIdx = EditorGUILayout.Popup(m_ColorManager.activeIndex, colorProviders, GUILayout.Width(100f)); + var newColorIndex = EditorGUILayout.Popup(m_ColorManager.activeIndex, colorProviders, GUILayout.Width(100f)); GUILayout.Space(4); m_UserViewSettings.isBlackboardVisible = GUILayout.Toggle(m_UserViewSettings.isBlackboardVisible, "Blackboard", EditorStyles.toolbarButton); @@ -220,16 +222,7 @@ public GraphEditorView(EditorWindow editorWindow, GraphData graph, MessageManage m_UserViewSettings.isPreviewVisible = GUILayout.Toggle(m_UserViewSettings.isPreviewVisible, "Main Preview", EditorStyles.toolbarButton); if (EditorGUI.EndChangeCheck()) { - if(newColorIdx != m_ColorManager.activeIndex) - { - m_ColorManager.SetActiveProvider(newColorIdx, m_GraphView.Query().ToList()); - m_UserViewSettings.colorProvider = m_ColorManager.activeProviderName; - } - - UpdateSubWindowsVisibility(); - - var serializedViewSettings = JsonUtility.ToJson(m_UserViewSettings); - EditorUserSettings.SetConfigValue(k_UserViewSettings, serializedViewSettings); + UserViewSettingsChangeCheck(newColorIndex); } GUILayout.EndHorizontal(); }); @@ -290,12 +283,27 @@ public GraphEditorView(EditorWindow editorWindow, GraphData graph, MessageManage Add(content); } + internal void UserViewSettingsChangeCheck(int newColorIndex) + { + if (newColorIndex != m_ColorManager.activeIndex) + { + m_ColorManager.SetActiveProvider(newColorIndex, m_GraphView.Query().ToList()); + m_UserViewSettings.colorProvider = m_ColorManager.activeProviderName; + } + + var serializedViewSettings = JsonUtility.ToJson(m_UserViewSettings); + EditorUserSettings.SetConfigValue(k_UserViewSettings, serializedViewSettings); + + UpdateSubWindowsVisibility(); + } + void NodeCreationRequest(NodeCreationContext c) { m_SearchWindowProvider.connectedPort = null; SearcherWindow.Show(m_EditorWindow, (m_SearchWindowProvider as SearcherProvider).LoadSearchWindow(), item => (m_SearchWindowProvider as SearcherProvider).OnSearcherSelectEntry(item, c.screenMousePosition - m_EditorWindow.position.position), c.screenMousePosition - m_EditorWindow.position.position, null); + }