首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

Unity 编辑器开发实战【Editor Window】- Duplicator复制机

  • 25-03-03 17:01
  • 3554
  • 9548
blog.csdn.net

1.Name Duplicator:名称复制机(根据层级结构复制名称)

 

2.Material Duplicator:材质复制机(根据层级结构复制材质)

代码如下:

  1. namespace SK.Framework
  2. {
  3. public interface IDuplicator
  4. {
  5. string InvalidatedInfo { get; }
  6. bool IsValidated();
  7. void Duplicate();
  8. }
  9. }
  1. namespace SK.Framework
  2. {
  3. public abstract class AbstractDuplicator<T> : IDuplicator
  4. {
  5. public virtual string InvalidatedInfo
  6. {
  7. get
  8. {
  9. return "Is invalidated.";
  10. }
  11. }
  12. protected T from;
  13. protected T to;
  14. public abstract bool IsValidated();
  15. public abstract void Duplicate();
  16. }
  17. }
  1. using UnityEngine;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. namespace SK.Framework
  5. {
  6. public class NameDuplicator : AbstractDuplicator<Transform>
  7. {
  8. private readonly Dictionary<string, Transform> fromHierarchy;
  9. private readonly Dictionary<string, Transform> toHierarchy;
  10. public override string InvalidatedInfo
  11. {
  12. get
  13. {
  14. return "Is invalidated:请先验证层级结构是否一致";
  15. }
  16. }
  17. public NameDuplicator(Transform from, Transform to)
  18. {
  19. this.from = from;
  20. this.to = to;
  21. fromHierarchy = new Dictionary<string, Transform>();
  22. toHierarchy = new Dictionary<string, Transform>();
  23. }
  24. //递归遍历From层级
  25. private void ForEachFromHierarchy(Transform t)
  26. {
  27. foreach (Transform child in t)
  28. {
  29. string fullName = GetFullName(child);
  30. fromHierarchy.Add(fullName, child);
  31. ForEachFromHierarchy(child);
  32. }
  33. }
  34. //递归遍历To层级
  35. private void ForEachToHierarchy(Transform t)
  36. {
  37. foreach (Transform child in t)
  38. {
  39. string fullName = GetFullName(child);
  40. toHierarchy.Add(fullName, child);
  41. ForEachToHierarchy(child);
  42. }
  43. }
  44. //获取层级结构
  45. private string GetFullName(Transform t)
  46. {
  47. const string flag = "hierarchy";
  48. List tfs = new List();
  49. Transform tf = t.transform;
  50. tfs.Add(tf);
  51. while (tf.parent)
  52. {
  53. tf = tf.parent;
  54. tfs.Add(tf);
  55. }
  56. StringBuilder sb = new StringBuilder();
  57. sb.Append($"{flag}{tfs[tfs.Count - 2].GetSiblingIndex()}");
  58. for (int i = tfs.Count - 3; i >= 0; i--)
  59. {
  60. sb.Append($"/{flag}{tfs[i].GetSiblingIndex()}");
  61. }
  62. return sb.ToString();
  63. }
  64. public override bool IsValidated()
  65. {
  66. ForEachFromHierarchy(from);
  67. ForEachToHierarchy(to);
  68. bool retV = true;
  69. retV &= fromHierarchy.Count == toHierarchy.Count;
  70. foreach (var kv in toHierarchy)
  71. {
  72. if (!fromHierarchy.ContainsKey(kv.Key))
  73. {
  74. retV = false;
  75. break;
  76. }
  77. }
  78. return retV;
  79. }
  80. public override void Duplicate()
  81. {
  82. foreach (var kv in toHierarchy)
  83. {
  84. kv.Value.name = fromHierarchy[kv.Key].name;
  85. }
  86. }
  87. }
  88. }
  1. using UnityEngine;
  2. using System.Text;
  3. using System.Collections.Generic;
  4. namespace SK.Framework
  5. {
  6. public class MaterialDuplicator : AbstractDuplicator<Transform>
  7. {
  8. private readonly Dictionary<string, Renderer> fromDic;
  9. private readonly Dictionary<string, Renderer> toDic;
  10. public MaterialDuplicator(Transform from, Transform to)
  11. {
  12. this.from = from;
  13. this.to = to;
  14. fromDic = new Dictionary<string, Renderer>();
  15. toDic = new Dictionary<string, Renderer>();
  16. }
  17. private void GetFromMeshRenderer()
  18. {
  19. Renderer[] renderers = from.GetComponentsInChildren(true);
  20. for(int i = 0; i < renderers.Length; i++)
  21. {
  22. Renderer renderer = renderers[i];
  23. fromDic.Add(GetFullName(renderer.transform), renderer);
  24. }
  25. }
  26. private void GetToMeshRenderer()
  27. {
  28. Renderer[] renderers = to.GetComponentsInChildren(true);
  29. for (int i = 0; i < renderers.Length; i++)
  30. {
  31. Renderer renderer = renderers[i];
  32. toDic.Add(GetFullName(renderer.transform), renderer);
  33. }
  34. }
  35. private string GetFullName(Transform t)
  36. {
  37. List tfs = new List();
  38. Transform tf = t.transform;
  39. tfs.Add(tf);
  40. while (tf.parent)
  41. {
  42. tf = tf.parent;
  43. tfs.Add(tf);
  44. }
  45. StringBuilder sb = new StringBuilder();
  46. sb.Append(tfs[tfs.Count - 2].name);
  47. for (int i = tfs.Count - 3; i >= 0; i--)
  48. {
  49. sb.Append("/" + tfs[i].name);
  50. }
  51. return sb.ToString();
  52. }
  53. public override bool IsValidated()
  54. {
  55. GetFromMeshRenderer();
  56. GetToMeshRenderer();
  57. bool retV = true;
  58. retV &= fromDic.Count == toDic.Count;
  59. foreach (var kv in toDic)
  60. {
  61. if (!fromDic.ContainsKey(kv.Key))
  62. {
  63. retV = false;
  64. break;
  65. }
  66. }
  67. return retV;
  68. }
  69. public override void Duplicate()
  70. {
  71. foreach (var kv in toDic)
  72. {
  73. kv.Value.sharedMaterials = fromDic[kv.Key].sharedMaterials;
  74. }
  75. }
  76. }
  77. }
  1. using UnityEngine;
  2. using UnityEditor;
  3. namespace SK.Framework
  4. {
  5. public class DuplicatorWindow : EditorWindow
  6. {
  7. [MenuItem("SKFramework/Duplicator")]
  8. private static void Open()
  9. {
  10. GetWindow("Duplicator").Show();
  11. }
  12. private Transform from;
  13. private Transform to;
  14. private bool isValidated;
  15. private const float labelWidth = 80f;
  16. private enum Mode
  17. {
  18. Name,
  19. Material,
  20. }
  21. private Mode mode = Mode.Name;
  22. private IDuplicator duplicator;
  23. private void OnGUI()
  24. {
  25. OnModeGUI();
  26. OnFromToGUI();
  27. OnValidateGUI();
  28. OnDuplicateGUI();
  29. }
  30. private void OnModeGUI()
  31. {
  32. GUILayout.BeginHorizontal();
  33. GUILayout.Label("Mode", GUILayout.Width(labelWidth));
  34. mode = (Mode)EditorGUILayout.EnumPopup(mode);
  35. GUILayout.EndHorizontal();
  36. }
  37. private void OnFromToGUI()
  38. {
  39. //From
  40. GUILayout.BeginHorizontal();
  41. GUILayout.Label("From", GUILayout.Width(labelWidth));
  42. Transform newFrom = EditorGUILayout.ObjectField(from, typeof(Transform), true) as Transform;
  43. if (newFrom != from)
  44. {
  45. from = newFrom;
  46. isValidated = false;
  47. }
  48. GUILayout.EndHorizontal();
  49. //To
  50. GUILayout.BeginHorizontal();
  51. GUILayout.Label("To", GUILayout.Width(labelWidth));
  52. Transform newTo = EditorGUILayout.ObjectField(to, typeof(Transform), true) as Transform;
  53. if (newTo != to)
  54. {
  55. to = newTo;
  56. isValidated = false;
  57. }
  58. GUILayout.EndHorizontal();
  59. }
  60. private void OnValidateGUI()
  61. {
  62. GUI.enabled = from != null && to != null;
  63. if (GUILayout.Button("Validate"))
  64. {
  65. switch (mode)
  66. {
  67. case Mode.Name: duplicator = new NameDuplicator(from, to); break;
  68. case Mode.Material: duplicator = new MaterialDuplicator(from, to); break;
  69. default: break;
  70. }
  71. isValidated = duplicator.IsValidated();
  72. }
  73. GUI.enabled = true;
  74. if (duplicator != null && !isValidated)
  75. {
  76. EditorGUILayout.HelpBox(duplicator.InvalidatedInfo, MessageType.Warning);
  77. }
  78. }
  79. private void OnDuplicateGUI()
  80. {
  81. GUI.enabled = isValidated;
  82. if (GUILayout.Button("Duplicate"))
  83. {
  84. duplicator.Duplicate();
  85. EditorUtility.SetDirty(to);
  86. }
  87. }
  88. }
  89. }
当代野生程序猿
微信公众号
Unity开发日志分享,欢迎关注/留言/私信。
注:本文转载自blog.csdn.net的CoderZ1010的文章"https://blog.csdn.net/qq_42139931/article/details/123775027"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top