Skip to content

Fix undo redo on layered lit editor #3059

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions com.unity.render-pipelines.high-definition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed side effect on styles during compositor rendering.
- Fixed size and spacing of compositor info boxes (case 1305652).
- Fixed spacing of UI widgets in the Graphics Compositor (case 1305638).
- Fixed undo-redo on layered lit editor.

### Changed
- Change the source value for the ray tracing frame index iterator from m_FrameCount to the camera frame count (case 1301356).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace UnityEditor.Rendering.HighDefinition
internal struct SerializeableGUIDs
{
public string[] GUIDArray;
public bool[] withUV;
}

/// <summary>
Expand Down Expand Up @@ -254,37 +255,27 @@ public static void SynchronizeAllLayers(Material material)
AssetImporter materialImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material.GetInstanceID()));

Material[] layers = null;
bool[] withUV = null;

// Material importer can be null when the selected material doesn't exists as asset (Material saved inside the scene)
if (materialImporter != null)
InitializeMaterialLayers(material, ref layers);
InitializeMaterialLayers(material, ref layers, ref withUV);

// We could have no userData in the assets, so test if we have load something
if (layers != null)
if (layers != null && withUV != null)
{
for (int i = 0; i < layerCount; ++i)
{
SynchronizeLayerProperties(material, layers, i, true);
SynchronizeLayerProperties(material, i, layers[i], withUV[i]);
}
}
}

public static void SynchronizeAllLayersProperties(Material material, Material[] materialLayers, bool excludeUVMappingProperties)
{
int numLayer = material.GetLayerCount();

for (int i = 0; i < numLayer; ++i)
{
SynchronizeLayerProperties(material, materialLayers, i, excludeUVMappingProperties);
}
}

// This function will look for all referenced lit material, and assign value from Lit to layered lit layers.
// This is based on the naming of the variables, i.E BaseColor will match BaseColor0, if a properties shouldn't be override
// put the name in the exclusionList below
public static void SynchronizeLayerProperties(Material material, Material[] layers, int layerIndex, bool excludeUVMappingProperties)
public static void SynchronizeLayerProperties(Material material, int layerIndex, Material layerMaterial, bool includeUVMappingProperties)
{
Material layerMaterial = layers[layerIndex];
string[] exclusionList = { kTexWorldScale, kUVBase, kUVMappingMask, kUVDetail, kUVDetailsMappingMask };

if (layerMaterial != null)
Expand All @@ -296,7 +287,7 @@ public static void SynchronizeLayerProperties(Material material, Material[] laye
string propertyName = ShaderUtil.GetPropertyName(layerShader, i);
string layerPropertyName = propertyName + layerIndex;

if (!exclusionList.Contains(propertyName) || !excludeUVMappingProperties)
if (includeUVMappingProperties || !exclusionList.Contains(propertyName))
{
if (material.HasProperty(layerPropertyName))
{
Expand All @@ -322,7 +313,7 @@ public static void SynchronizeLayerProperties(Material material, Material[] laye
case ShaderUtil.ShaderPropertyType.TexEnv:
{
material.SetTexture(layerPropertyName, layerMaterial.GetTexture(propertyName));
if (!excludeUVMappingProperties)
if (includeUVMappingProperties)
{
material.SetTextureOffset(layerPropertyName, layerMaterial.GetTextureOffset(propertyName));
material.SetTextureScale(layerPropertyName, layerMaterial.GetTextureScale(propertyName));
Expand All @@ -338,10 +329,14 @@ public static void SynchronizeLayerProperties(Material material, Material[] laye

// We use the user data to save a string that represent the referenced lit material
// so we can keep reference during serialization
public static void InitializeMaterialLayers(Material material, ref Material[] layers)
public static void InitializeMaterialLayers(Material material, ref Material[] layers, ref bool[] withUV)
{
AssetImporter materialImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material.GetInstanceID()));
InitializeMaterialLayers(materialImporter, ref layers, ref withUV);
}

public static void InitializeMaterialLayers(AssetImporter materialImporter, ref Material[] layers, ref bool[] withUV)
{
if (materialImporter.userData != string.Empty)
{
SerializeableGUIDs layersGUID = JsonUtility.FromJson<SerializeableGUIDs>(materialImporter.userData);
Expand All @@ -353,19 +348,40 @@ public static void InitializeMaterialLayers(Material material, ref Material[] la
layers[i] = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(layersGUID.GUIDArray[i]), typeof(Material)) as Material;
}
}
if (layersGUID.withUV.Length > 0)
{
withUV = new bool[layersGUID.withUV.Length];
for (int i = 0; i < layersGUID.withUV.Length; ++i)
withUV[i] = layersGUID.withUV[i];
}
}
else
{
if (layers != null)
{
for (int i = 0; i < layers.Length; ++i)
layers[i] = null;
}
if (withUV != null)
{
for (int i = 0; i < withUV.Length; ++i)
withUV[i] = true;
}
}
}

public static void SaveMaterialLayers(Material material, Material[] materialLayers)
public static void SaveMaterialLayers(Material material, Material[] materialLayers, bool[] withUV)
{
AssetImporter materialImporter = AssetImporter.GetAtPath(AssetDatabase.GetAssetPath(material.GetInstanceID()));

SerializeableGUIDs layersGUID;
layersGUID.GUIDArray = new string[materialLayers.Length];
layersGUID.withUV = new bool[withUV.Length];
for (int i = 0; i < materialLayers.Length; ++i)
{
if (materialLayers[i] != null)
layersGUID.GUIDArray[i] = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(materialLayers[i].GetInstanceID()));
layersGUID.withUV[i] = withUV[i];
}

materialImporter.userData = JsonUtility.ToJson(layersGUID);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ internal class Styles
MaterialProperty layerCount = null;

ExpandableBit m_ExpandableBit;
bool[] m_WithUV;
bool[] m_WithUV = new bool[kMaxLayerCount];
Material[] m_MaterialLayers = new Material[kMaxLayerCount];
AssetImporter m_MaterialImporter;

Expand Down Expand Up @@ -69,7 +69,6 @@ void UpdateEditorExpended(int layerNumber)
public LayerListUIBlock(ExpandableBit expandableBit)
{
m_ExpandableBit = expandableBit;
m_WithUV = new bool[] { true, true, true, true };
}

/// <summary>
Expand All @@ -86,25 +85,7 @@ public override void LoadMaterialProperties()

// Material importer can be null when the selected material doesn't exists as asset (Material saved inside the scene)
if (m_MaterialImporter != null)
InitializeMaterialLayers(m_MaterialImporter, ref m_MaterialLayers);
}

// We use the user data to save a string that represent the referenced lit material
// so we can keep reference during serialization
static void InitializeMaterialLayers(AssetImporter materialImporter, ref Material[] layers)
{
if (materialImporter.userData != string.Empty)
{
SerializeableGUIDs layersGUID = JsonUtility.FromJson<SerializeableGUIDs>(materialImporter.userData);
if (layersGUID.GUIDArray.Length > 0)
{
layers = new Material[layersGUID.GUIDArray.Length];
for (int i = 0; i < layersGUID.GUIDArray.Length; ++i)
{
layers[i] = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(layersGUID.GUIDArray[i]), typeof(Material)) as Material;
}
}
}
LayeredLitGUI.InitializeMaterialLayers(m_MaterialImporter, ref m_MaterialLayers, ref m_WithUV);
}

/// <summary>
Expand Down Expand Up @@ -153,19 +134,18 @@ void DrawLayerListGUI()
{
using (new EditorGUILayout.HorizontalScope())
{
EditorGUI.BeginChangeCheck();

Rect lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight);
Rect colorRect = new Rect(lineRect.x + 17f, lineRect.y + 7f, colorWidth, colorWidth);
Rect materialRect = new Rect(lineRect.x + padding + colorRect.width, lineRect.y, lineRect.width - UVWidth - padding - 3 - resetButtonWidth + endOffset, lineRect.height);
Rect uvRect = new Rect(lineRect.x + lineRect.width - resetButtonWidth - padding - UVWidth - endOffset, lineRect.y, UVWidth, lineRect.height);
Rect resetRect = new Rect(lineRect.x + lineRect.width - resetButtonWidth - endOffset, lineRect.y, resetButtonWidth, lineRect.height);

EditorGUI.BeginChangeCheck();
m_MaterialLayers[layerIndex] = EditorGUI.ObjectField(materialRect, Styles.layerLabels[layerIndex], m_MaterialLayers[layerIndex], typeof(Material), allowSceneObjects: true) as Material;
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObjects(new UnityEngine.Object[] { material, m_MaterialImporter }, "Change layer material");
LayeredLitGUI.SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex, true);
LayeredLitGUI.SynchronizeLayerProperties(material, layerIndex, m_MaterialLayers[layerIndex], m_WithUV[layerIndex]);
layersChanged = true;

// Update external reference.
Expand All @@ -178,12 +158,18 @@ void DrawLayerListGUI()

EditorGUI.DrawRect(colorRect, kLayerColors[layerIndex]);

EditorGUI.BeginChangeCheck();
m_WithUV[layerIndex] = EditorGUI.Toggle(uvRect, m_WithUV[layerIndex]);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObjects(new UnityEngine.Object[] { material, m_MaterialImporter }, "Change layer material");
layersChanged = true;
}

if (GUI.Button(resetRect, GUIContent.none))
{
Undo.RecordObjects(new UnityEngine.Object[] { material, m_MaterialImporter }, "Reset layer material");
LayeredLitGUI.SynchronizeLayerProperties(material, m_MaterialLayers, layerIndex, !m_WithUV[layerIndex]);
LayeredLitGUI.SynchronizeLayerProperties(material, layerIndex, m_MaterialLayers[layerIndex], m_WithUV[layerIndex]);
layersChanged = true;
}

Expand Down Expand Up @@ -212,7 +198,7 @@ void DrawLayerListGUI()

// SaveAssetsProcessor the referenced material in the users data
if (m_MaterialImporter != null)
LayeredLitGUI.SaveMaterialLayers(material, m_MaterialLayers);
LayeredLitGUI.SaveMaterialLayers(material, m_MaterialLayers, m_WithUV);

// We should always do this call at the end
materialEditor.serializedObject.ApplyModifiedProperties();
Expand Down