Unity 编辑器开发实战【Editor Window】- Duplicator复制机
【摘要】
1.Name Duplicator:名称复制机(根据层级结构复制名称)
2.Material Duplicator:材质复制机(根据层级结构复制材质)
代码如下:
namespace SK.Framework{ public interface IDuplicator { stri...
1.Name Duplicator:名称复制机(根据层级结构复制名称)
2.Material Duplicator:材质复制机(根据层级结构复制材质)
代码如下:
-
namespace SK.Framework
-
{
-
public interface IDuplicator
-
{
-
string InvalidatedInfo { get; }
-
-
bool IsValidated();
-
-
void Duplicate();
-
}
-
}
-
namespace SK.Framework
-
{
-
public abstract class AbstractDuplicator<T> : IDuplicator
-
{
-
public virtual string InvalidatedInfo
-
{
-
get
-
{
-
return "Is invalidated.";
-
}
-
}
-
-
protected T from;
-
protected T to;
-
-
public abstract bool IsValidated();
-
-
public abstract void Duplicate();
-
}
-
}
-
using UnityEngine;
-
using System.Text;
-
using System.Collections.Generic;
-
-
namespace SK.Framework
-
{
-
public class NameDuplicator : AbstractDuplicator<Transform>
-
{
-
private readonly Dictionary<string, Transform> fromHierarchy;
-
private readonly Dictionary<string, Transform> toHierarchy;
-
-
public override string InvalidatedInfo
-
{
-
get
-
{
-
return "Is invalidated:请先验证层级结构是否一致";
-
}
-
}
-
-
public NameDuplicator(Transform from, Transform to)
-
{
-
this.from = from;
-
this.to = to;
-
fromHierarchy = new Dictionary<string, Transform>();
-
toHierarchy = new Dictionary<string, Transform>();
-
}
-
-
//递归遍历From层级
-
private void ForEachFromHierarchy(Transform t)
-
{
-
foreach (Transform child in t)
-
{
-
string fullName = GetFullName(child);
-
fromHierarchy.Add(fullName, child);
-
ForEachFromHierarchy(child);
-
}
-
}
-
//递归遍历To层级
-
private void ForEachToHierarchy(Transform t)
-
{
-
foreach (Transform child in t)
-
{
-
string fullName = GetFullName(child);
-
toHierarchy.Add(fullName, child);
-
ForEachToHierarchy(child);
-
}
-
}
-
//获取层级结构
-
private string GetFullName(Transform t)
-
{
-
const string flag = "hierarchy";
-
List<Transform> tfs = new List<Transform>();
-
Transform tf = t.transform;
-
tfs.Add(tf);
-
while (tf.parent)
-
{
-
tf = tf.parent;
-
tfs.Add(tf);
-
}
-
StringBuilder sb = new StringBuilder();
-
sb.Append($"{flag}{tfs[tfs.Count - 2].GetSiblingIndex()}");
-
for (int i = tfs.Count - 3; i >= 0; i--)
-
{
-
sb.Append($"/{flag}{tfs[i].GetSiblingIndex()}");
-
}
-
return sb.ToString();
-
}
-
-
public override bool IsValidated()
-
{
-
ForEachFromHierarchy(from);
-
ForEachToHierarchy(to);
-
bool retV = true;
-
retV &= fromHierarchy.Count == toHierarchy.Count;
-
foreach (var kv in toHierarchy)
-
{
-
if (!fromHierarchy.ContainsKey(kv.Key))
-
{
-
retV = false;
-
break;
-
}
-
}
-
return retV;
-
}
-
-
public override void Duplicate()
-
{
-
foreach (var kv in toHierarchy)
-
{
-
kv.Value.name = fromHierarchy[kv.Key].name;
-
}
-
}
-
}
-
}
-
using UnityEngine;
-
using System.Text;
-
using System.Collections.Generic;
-
-
namespace SK.Framework
-
{
-
public class MaterialDuplicator : AbstractDuplicator<Transform>
-
{
-
private readonly Dictionary<string, Renderer> fromDic;
-
private readonly Dictionary<string, Renderer> toDic;
-
-
public MaterialDuplicator(Transform from, Transform to)
-
{
-
this.from = from;
-
this.to = to;
-
fromDic = new Dictionary<string, Renderer>();
-
toDic = new Dictionary<string, Renderer>();
-
}
-
-
private void GetFromMeshRenderer()
-
{
-
Renderer[] renderers = from.GetComponentsInChildren<Renderer>(true);
-
for(int i = 0; i < renderers.Length; i++)
-
{
-
Renderer renderer = renderers[i];
-
fromDic.Add(GetFullName(renderer.transform), renderer);
-
}
-
}
-
private void GetToMeshRenderer()
-
{
-
Renderer[] renderers = to.GetComponentsInChildren<Renderer>(true);
-
for (int i = 0; i < renderers.Length; i++)
-
{
-
Renderer renderer = renderers[i];
-
toDic.Add(GetFullName(renderer.transform), renderer);
-
}
-
}
-
private string GetFullName(Transform t)
-
{
-
List<Transform> tfs = new List<Transform>();
-
Transform tf = t.transform;
-
tfs.Add(tf);
-
while (tf.parent)
-
{
-
tf = tf.parent;
-
tfs.Add(tf);
-
}
-
StringBuilder sb = new StringBuilder();
-
sb.Append(tfs[tfs.Count - 2].name);
-
for (int i = tfs.Count - 3; i >= 0; i--)
-
{
-
sb.Append("/" + tfs[i].name);
-
}
-
return sb.ToString();
-
}
-
public override bool IsValidated()
-
{
-
GetFromMeshRenderer();
-
GetToMeshRenderer();
-
bool retV = true;
-
retV &= fromDic.Count == toDic.Count;
-
foreach (var kv in toDic)
-
{
-
if (!fromDic.ContainsKey(kv.Key))
-
{
-
retV = false;
-
break;
-
}
-
}
-
return retV;
-
}
-
public override void Duplicate()
-
{
-
foreach (var kv in toDic)
-
{
-
kv.Value.sharedMaterials = fromDic[kv.Key].sharedMaterials;
-
}
-
}
-
}
-
}
-
using UnityEngine;
-
using UnityEditor;
-
-
namespace SK.Framework
-
{
-
public class DuplicatorWindow : EditorWindow
-
{
-
[MenuItem("SKFramework/Duplicator")]
-
private static void Open()
-
{
-
GetWindow<DuplicatorWindow>("Duplicator").Show();
-
}
-
-
private Transform from;
-
private Transform to;
-
private bool isValidated;
-
private const float labelWidth = 80f;
-
-
private enum Mode
-
{
-
Name,
-
Material,
-
}
-
private Mode mode = Mode.Name;
-
private IDuplicator duplicator;
-
-
private void OnGUI()
-
{
-
OnModeGUI();
-
-
OnFromToGUI();
-
-
OnValidateGUI();
-
-
OnDuplicateGUI();
-
}
-
private void OnModeGUI()
-
{
-
GUILayout.BeginHorizontal();
-
GUILayout.Label("Mode", GUILayout.Width(labelWidth));
-
mode = (Mode)EditorGUILayout.EnumPopup(mode);
-
GUILayout.EndHorizontal();
-
}
-
private void OnFromToGUI()
-
{
-
//From
-
GUILayout.BeginHorizontal();
-
GUILayout.Label("From", GUILayout.Width(labelWidth));
-
Transform newFrom = EditorGUILayout.ObjectField(from, typeof(Transform), true) as Transform;
-
if (newFrom != from)
-
{
-
from = newFrom;
-
isValidated = false;
-
}
-
GUILayout.EndHorizontal();
-
-
//To
-
GUILayout.BeginHorizontal();
-
GUILayout.Label("To", GUILayout.Width(labelWidth));
-
Transform newTo = EditorGUILayout.ObjectField(to, typeof(Transform), true) as Transform;
-
if (newTo != to)
-
{
-
to = newTo;
-
isValidated = false;
-
}
-
GUILayout.EndHorizontal();
-
}
-
private void OnValidateGUI()
-
{
-
GUI.enabled = from != null && to != null;
-
if (GUILayout.Button("Validate"))
-
{
-
switch (mode)
-
{
-
case Mode.Name: duplicator = new NameDuplicator(from, to); break;
-
case Mode.Material: duplicator = new MaterialDuplicator(from, to); break;
-
default: break;
-
}
-
isValidated = duplicator.IsValidated();
-
}
-
GUI.enabled = true;
-
if (duplicator != null && !isValidated)
-
{
-
EditorGUILayout.HelpBox(duplicator.InvalidatedInfo, MessageType.Warning);
-
}
-
}
-
private void OnDuplicateGUI()
-
{
-
GUI.enabled = isValidated;
-
if (GUILayout.Button("Duplicate"))
-
{
-
duplicator.Duplicate();
-
EditorUtility.SetDirty(to);
-
}
-
}
-
}
-
}
文章来源: coderz.blog.csdn.net,作者:CoderZ1010,版权归原作者所有,如需转载,请联系作者。
原文链接:coderz.blog.csdn.net/article/details/123775027
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)