├── Preview.gif ├── ComponentHelper ├── ReadMe.jpg ├── MoreTips.txt.meta ├── Editor.meta ├── Editor │ ├── ComponentHelperCore.cs.meta │ ├── ComponentHelperView.cs.meta │ ├── ComponentEditorHierHelper.cs.meta │ ├── ComponentEditorHierHelper.cs │ ├── ComponentHelperCore.cs │ └── ComponentHelperView.cs ├── MoreTips.txt └── ReadMe.jpg.meta └── README.md /Preview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hont127/Unity-Component-Helper/HEAD/Preview.gif -------------------------------------------------------------------------------- /ComponentHelper/ReadMe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hont127/Unity-Component-Helper/HEAD/ComponentHelper/ReadMe.jpg -------------------------------------------------------------------------------- /ComponentHelper/MoreTips.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 591dc1f0b498c1d43b63bebf2c5835b8 3 | TextScriptImporter: 4 | userData: 5 | -------------------------------------------------------------------------------- /ComponentHelper/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 42eb48e839310c7419008458d2f9cc31 3 | folderAsset: yes 4 | DefaultImporter: 5 | userData: 6 | -------------------------------------------------------------------------------- /ComponentHelper/Editor/ComponentHelperCore.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: db2fdd711b89ec54d83df97ef3cfff12 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /ComponentHelper/Editor/ComponentHelperView.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 86a3c4e33de43424789f1d5e69b4e3a2 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /ComponentHelper/Editor/ComponentEditorHierHelper.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9c9298aac34c18c4e8626000a8fc2aa8 3 | MonoImporter: 4 | serializedVersion: 2 5 | defaultReferences: [] 6 | executionOrder: 0 7 | icon: {instanceID: 0} 8 | userData: 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity-Component-Helper 2 | Unity3D Component Cut/Copy/Paste helper window tool Unity3D组件拷贝助手,支持批量剪切复制粘贴修改引用链接等. 3 | 4 | ![](https://github.com/hont127/Unity-Component-Helper/blob/master/Preview.gif) 5 | 6 | ![](https://github.com/hont127/Unity-Component-Helper/blob/master/ComponentHelper/RedeMe.jpg) 7 | -------------------------------------------------------------------------------- /ComponentHelper/MoreTips.txt: -------------------------------------------------------------------------------- 1 | -What is Cursor Mode? 2 | 3 | Cursor Mode will use the current object in the hierarchy panel 4 | . 5 | 6 | -How do use the IsIntelligentFindParent? 7 | 8 | When you copy multiple components you will find that the parent object has not changed, 9 | so..open this toggle, parent object will change accordingly 10 | . 11 | 12 | -How to copy multiple target 13 | ? 14 | 15 | This is very simple, first set component to copy list, and then open the cursor mode 16 | select multiple objects. and click "paste" button 17 | complete! 18 | -------------------------------------------------------------------------------- /ComponentHelper/ReadMe.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 22bb2d10d9a81004ebe9532f3a8834aa 3 | TextureImporter: 4 | fileIDToRecycleName: {} 5 | externalObjects: {} 6 | serializedVersion: 7 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | vertices: [] 80 | indices: 81 | edges: [] 82 | weights: [] 83 | spritePackingTag: 84 | pSDRemoveMatte: 0 85 | pSDShowRemoveMatteOption: 0 86 | userData: 87 | assetBundleName: 88 | assetBundleVariant: 89 | -------------------------------------------------------------------------------- /ComponentHelper/Editor/ComponentEditorHierHelper.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | 6 | using System; 7 | 8 | namespace Hont 9 | { 10 | public static class ComponentEditorHierHelper 11 | { 12 | public static void ChangeUnityObjectHierLink(Component targetComp, bool justCompareType = false) 13 | { 14 | HashSet saerchCompList = new HashSet(); 15 | ParentForEach(targetComp.transform 16 | , m => 17 | { 18 | foreach (var item in m.GetComponents()) 19 | saerchCompList.Add(item); 20 | 21 | saerchCompList.Add(m.gameObject); 22 | } 23 | , true); 24 | 25 | ChildForEach(targetComp.transform 26 | , m => 27 | { 28 | foreach (var item in m.GetComponents()) 29 | saerchCompList.Add(item); 30 | 31 | saerchCompList.Add(m.gameObject); 32 | }, true); 33 | 34 | var fields = targetComp.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance); 35 | 36 | foreach (var item in fields) 37 | { 38 | var value = item.GetValue(targetComp) as UnityEngine.Object; 39 | if (value == null) continue; 40 | var target = saerchCompList.FirstOrDefault(m => 41 | { 42 | bool result = false; 43 | result = justCompareType && m.GetType() == value.GetType(); 44 | result |= m.name == value.name && m.GetType() == value.GetType(); 45 | return result; 46 | }); 47 | 48 | item.SetValue(targetComp, target); 49 | } 50 | } 51 | 52 | public static void ChildForEach(Transform tfm, Action action, bool hasSelf = false) 53 | { 54 | if (hasSelf) action(tfm); 55 | RecursiveChildTfm(tfm, action); 56 | } 57 | 58 | static void RecursiveChildTfm(Transform tfm, Action action) 59 | { 60 | foreach (Transform item in tfm) 61 | { 62 | if (action != null) action(item); 63 | 64 | if (item.childCount > 0) 65 | { 66 | RecursiveChildTfm(item, action); 67 | } 68 | } 69 | } 70 | 71 | static void ParentForEach(Transform tfm, Action action, bool hasSelf = false) 72 | { 73 | if (hasSelf) action(tfm); 74 | Transform tmpTfm = tfm; 75 | while (tmpTfm != null) 76 | { 77 | action(tmpTfm); 78 | tmpTfm = tmpTfm.parent; 79 | } 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ComponentHelper/Editor/ComponentHelperCore.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System.Linq; 4 | using System.Collections.Generic; 5 | 6 | namespace Hont 7 | { 8 | public class ComponentHelperCore 9 | { 10 | Component mLastOpComp; 11 | GameObject mSrcObj; 12 | GameObject mDstObj; 13 | GameObject[] mDstObjArr; 14 | HashSet mWillRemoveList = new HashSet(); 15 | HashSet mWaitCopyList = new HashSet(); 16 | HashSet mCopySelList = new HashSet(); 17 | bool mIsOrderMode; 18 | bool mIsAttachMode; 19 | bool mIsIntelligentFindParent; 20 | bool mIsIntelligentFindParentOnlyType; 21 | bool? mSrcOrDstSelection = true; 22 | 23 | public Component LastOpComponent { get { return mLastOpComp; } } 24 | 25 | public HashSet CopyList { get { return mWaitCopyList; } } 26 | public HashSet CopySelList { get { return mCopySelList; } } 27 | public HashSet WillRemoveList { get { return mWillRemoveList; } } 28 | 29 | public bool CanPaste 30 | { 31 | get 32 | { 33 | bool flag = false; 34 | flag = mDstObj != null || mDstObjArr != null; 35 | flag &= mSrcObj != null; 36 | 37 | return flag; 38 | } 39 | } 40 | 41 | public bool IsOrderMode { get { return mIsOrderMode; } set { mIsOrderMode = value; } } 42 | public bool IsAttachMode { get { return mIsAttachMode; } set { mIsAttachMode = value; } } 43 | 44 | public string SrcObjInfo { get { return string.Format("-Source(Name:{0} ID:{1})", mSrcObj.name, mSrcObj.GetInstanceID()); } } 45 | public string DstObjInfo { get { return string.Format("-Dst(Name:{0} ID:{1})", mDstObj.name, mDstObj.GetInstanceID()); } } 46 | 47 | public bool IsIntelligentFindParent 48 | { 49 | get 50 | { return mIsIntelligentFindParent; } 51 | set 52 | { 53 | mIsIntelligentFindParent = value; 54 | if (mIsIntelligentFindParent) mIsIntelligentFindParentOnlyType = false; 55 | } 56 | } 57 | public bool IsIntelligentFindParentOnlyType 58 | { 59 | get { return mIsIntelligentFindParentOnlyType; } 60 | set 61 | { 62 | mIsIntelligentFindParentOnlyType = value; 63 | if (mIsIntelligentFindParentOnlyType) mIsIntelligentFindParent = false; 64 | } 65 | } 66 | 67 | public GameObject SrcObj { get { return mSrcObj; } set { mSrcObj = value; } } 68 | public GameObject DstObj { get { return mDstObj; } set { mDstObj = value; } } 69 | public GameObject[] DstObjArr { get { return mDstObjArr; } set { mDstObjArr = value; } } 70 | 71 | public Component[] SrcObjComps { get { return mSrcObj.GetComponents(); } } 72 | public Component[] DstObjComps { get { return mDstObj.GetComponents(); } } 73 | 74 | public bool? SrcOrDstSelection { get { return mSrcOrDstSelection; } set { mSrcOrDstSelection = value; } } 75 | public bool IsMultiDst { get { return mDstObjArr != null && mDstObjArr.Length > 0; } } 76 | 77 | 78 | public void RefreshSelectList() 79 | { 80 | if (mSrcOrDstSelection.HasValue == false) 81 | { 82 | mDstObjArr = null; 83 | } 84 | else if (mSrcOrDstSelection.Value) 85 | { 86 | mSrcObj = Selection.activeGameObject; 87 | } 88 | else 89 | { 90 | mDstObj = Selection.activeGameObject; 91 | mDstObjArr = Selection.gameObjects; 92 | if (mDstObjArr.Length == 1) mDstObjArr = null; 93 | } 94 | } 95 | 96 | public void AddToWillRemoveList(Component comp) 97 | { 98 | mWillRemoveList.Add(comp); 99 | mLastOpComp = comp; 100 | } 101 | 102 | public void RemoveFromCopyList(Component comp) 103 | { 104 | mWaitCopyList.Remove(comp); 105 | 106 | if (mWillRemoveList.Contains(comp)) 107 | mWillRemoveList.Remove(comp); 108 | 109 | if (mCopySelList.Contains(comp)) 110 | mCopySelList.Remove(comp); 111 | } 112 | 113 | public void SelectItemFromCopyList(Component comp, bool isSelect) 114 | { 115 | if (mCopySelList.Contains(comp)) mCopySelList.Remove(comp); 116 | else mCopySelList.Add(comp); 117 | } 118 | 119 | public void ClearCopyList() 120 | { 121 | mWillRemoveList.Clear(); 122 | mWaitCopyList.Clear(); 123 | mCopySelList.Clear(); 124 | } 125 | 126 | public void ReverseCopyList() 127 | { 128 | var temp = mCopySelList.Reverse().ToArray(); 129 | mCopySelList.Clear(); 130 | foreach (var item in temp) 131 | mCopySelList.Add(item); 132 | 133 | temp = mWillRemoveList.Reverse().ToArray(); 134 | mWillRemoveList.Clear(); 135 | foreach (var item in temp) 136 | mWillRemoveList.Add(item); 137 | 138 | temp = mWaitCopyList.Reverse().ToArray(); 139 | mWaitCopyList.Clear(); 140 | foreach (var item in temp) 141 | mWaitCopyList.Add(item); 142 | } 143 | 144 | #region Component Operation Methods. 145 | 146 | public void ComponentToTop(Component comp) 147 | { 148 | var go = comp.gameObject; 149 | 150 | #if !(UNITY_2018_3_OR_NEWER) 151 | if (!AssetDatabase.IsMainAsset(go)) 152 | PrefabUtility.DisconnectPrefabInstance(go); 153 | #endif 154 | 155 | for (int j = 0; j < go.GetComponents().Length; j++) 156 | { 157 | UnityEditorInternal.ComponentUtility.MoveComponentUp(comp); 158 | } 159 | mLastOpComp = comp; 160 | } 161 | 162 | public void ComponentToBottom(Component comp) 163 | { 164 | var go = comp.gameObject; 165 | 166 | #if !(UNITY_2018_3_OR_NEWER) 167 | if (!AssetDatabase.IsMainAsset(go)) 168 | PrefabUtility.DisconnectPrefabInstance(go); 169 | #endif 170 | 171 | for (int j = 0; j < go.GetComponents().Length; j++) 172 | { 173 | UnityEditorInternal.ComponentUtility.MoveComponentDown(comp); 174 | } 175 | mLastOpComp = comp; 176 | } 177 | 178 | public void ComponentToUp(Component comp) 179 | { 180 | var go = comp.gameObject; 181 | 182 | #if !(UNITY_2018_3_OR_NEWER) 183 | if (!AssetDatabase.IsMainAsset(go)) 184 | PrefabUtility.DisconnectPrefabInstance(go); 185 | #endif 186 | 187 | UnityEditorInternal.ComponentUtility.MoveComponentUp(comp); 188 | mLastOpComp = comp; 189 | } 190 | 191 | public void ComponentToDown(Component comp) 192 | { 193 | var go = comp.gameObject; 194 | 195 | #if !(UNITY_2018_3_OR_NEWER) 196 | if (!AssetDatabase.IsMainAsset(go)) 197 | PrefabUtility.DisconnectPrefabInstance(go); 198 | #endif 199 | 200 | UnityEditorInternal.ComponentUtility.MoveComponentDown(comp); 201 | mLastOpComp = comp; 202 | } 203 | 204 | public void DeleteComponent(Component comp) 205 | { 206 | if (mWillRemoveList.Contains(comp)) 207 | mWillRemoveList.Remove(comp); 208 | 209 | if (mWaitCopyList.Contains(comp)) 210 | mWaitCopyList.Remove(comp); 211 | 212 | if (mCopySelList.Contains(comp)) 213 | mCopySelList.Remove(comp); 214 | 215 | Undo.DestroyObjectImmediate(comp); 216 | } 217 | 218 | public void AddCutComponentToCopyList(Component comp) 219 | { 220 | mWillRemoveList.Add(comp); 221 | mWaitCopyList.Add(comp); 222 | mCopySelList.Add(comp); 223 | mLastOpComp = comp; 224 | } 225 | 226 | public void AddComponentToCopyList(Component comp) 227 | { 228 | mWaitCopyList.Add(comp); 229 | mCopySelList.Add(comp); 230 | mLastOpComp = comp; 231 | } 232 | 233 | public void ComponentDuplicate(Component comp) 234 | { 235 | mWaitCopyList.Add(comp); 236 | mCopySelList.Add(comp); 237 | Paste(); 238 | mWaitCopyList.Remove(comp); 239 | mCopySelList.Remove(comp); 240 | mLastOpComp = comp; 241 | } 242 | #endregion 243 | 244 | public void Paste() 245 | { 246 | foreach (var item in mCopySelList) 247 | { 248 | if (!IsMultiDst) 249 | { 250 | Paste(item, mDstObj); 251 | } 252 | else//multiple copy target state. 253 | { 254 | foreach (var dstObj in mDstObjArr) 255 | { 256 | Paste(item, dstObj); 257 | } 258 | } 259 | } 260 | 261 | if (mSrcObj != null) 262 | { 263 | foreach (var item in mWillRemoveList) 264 | { 265 | if (mCopySelList.Contains(item)) 266 | mCopySelList.Remove(item); 267 | 268 | if (mWaitCopyList.Contains(item)) 269 | mWaitCopyList.Remove(item); 270 | 271 | Undo.DestroyObjectImmediate(item); 272 | } 273 | mWillRemoveList.Clear(); 274 | } 275 | } 276 | 277 | public void PasteValue(Component comp) 278 | { 279 | if (mCopySelList.Count == 1) 280 | { 281 | EditorUtility.CopySerialized(mCopySelList.FirstOrDefault(), comp); 282 | 283 | if (mSrcObj != null) 284 | { 285 | foreach (var item in mWillRemoveList) 286 | { 287 | Undo.DestroyObjectImmediate(item); 288 | } 289 | mWillRemoveList.Clear(); 290 | } 291 | } 292 | } 293 | 294 | public void Paste(Component comp, GameObject dstObj) 295 | { 296 | var newComp = Undo.AddComponent(dstObj, comp.GetType()); 297 | if (newComp == null) return; 298 | 299 | EditorUtility.CopySerialized(comp, newComp); 300 | 301 | if (mIsIntelligentFindParent || mIsIntelligentFindParentOnlyType) 302 | ComponentEditorHierHelper.ChangeUnityObjectHierLink(newComp, mIsIntelligentFindParentOnlyType); 303 | } 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /ComponentHelper/Editor/ComponentHelperView.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | using UnityEditor; 3 | using System; 4 | using System.Linq; 5 | 6 | namespace Hont 7 | { 8 | public class ComponentHelperView : EditorWindow 9 | { 10 | static EditorWindow mWindowHandle; 11 | ComponentHelperCore mComponentTool = new ComponentHelperCore(); 12 | Vector2 mScrollSign; 13 | 14 | 15 | [MenuItem("Tools/Hont/Utility/Component Helper %#o")] 16 | public static void ComponentEditorToolInit() 17 | { 18 | if (mWindowHandle != null) 19 | { 20 | mWindowHandle.Close(); 21 | return; 22 | } 23 | mWindowHandle = EditorWindow.GetWindow(typeof(ComponentHelperView)); 24 | mWindowHandle.minSize = new Vector2(480, 540); 25 | } 26 | 27 | void OnGUI() 28 | { 29 | ModeSelectDetection(); 30 | 31 | if (Event.current.type == EventType.KeyDown || Event.current.type == EventType.KeyUp) return; 32 | 33 | EditorGUILayout.HelpBox("-Hold 'ctrl' you can change to Mode1'\t\n-Hold 'ctrl+alt' you can change to 'Mode2'", MessageType.Info); 34 | 35 | RefreshSelectList(); 36 | FindParentModeOption(); 37 | RefreshCopyList(); 38 | RefreshOpComponentList(); 39 | } 40 | 41 | void Update() 42 | { 43 | Repaint(); 44 | } 45 | 46 | void ModeSelectDetection() 47 | { 48 | var curEvt = Event.current; 49 | if (curEvt.keyCode == KeyCode.LeftControl && curEvt.type == EventType.KeyDown) 50 | { 51 | mComponentTool.IsOrderMode = true; 52 | Repaint(); 53 | } 54 | 55 | else if (curEvt.keyCode == KeyCode.LeftControl && curEvt.type == EventType.KeyUp) 56 | { 57 | mComponentTool.IsOrderMode = false; 58 | Repaint(); 59 | } 60 | 61 | else if (curEvt.keyCode == KeyCode.LeftAlt && curEvt.type == EventType.KeyDown) 62 | { 63 | mComponentTool.IsAttachMode = true; 64 | Repaint(); 65 | } 66 | 67 | else if (curEvt.keyCode == KeyCode.LeftAlt && curEvt.type == EventType.KeyUp) 68 | { 69 | mComponentTool.IsAttachMode = false; 70 | Repaint(); 71 | } 72 | } 73 | 74 | void FindParentModeOption() 75 | { 76 | EditorGUILayout.BeginHorizontal(); 77 | mComponentTool.IsIntelligentFindParent 78 | = GUILayout.Toggle(mComponentTool.IsIntelligentFindParent, "IntelligentFindParent"); 79 | mComponentTool.IsIntelligentFindParentOnlyType 80 | = GUILayout.Toggle(mComponentTool.IsIntelligentFindParentOnlyType, "IntelligentFindParent(Only Type)"); 81 | EditorGUILayout.EndHorizontal(); 82 | } 83 | 84 | void RefreshOpComponentList() 85 | { 86 | var defaultGUIColor = GUI.color; 87 | mScrollSign = EditorGUILayout.BeginScrollView(mScrollSign);/*BeginScrollView*/ 88 | 89 | #region ---SRC Object Components--- 90 | if (mComponentTool.SrcObj != null) 91 | { 92 | GUILayout.Label(mComponentTool.SrcObjInfo, EditorStyles.boldLabel); 93 | 94 | var comps = mComponentTool.SrcObjComps; 95 | for (int i = 0; i < comps.Length; i++) 96 | { 97 | var item = comps[i]; 98 | GUI.color = defaultGUIColor; 99 | 100 | if (item == null) 101 | { 102 | ColorBlock(col: Color.red, blockContent: () => GUILayout.Box("Null(Script) Component")); 103 | continue; 104 | } 105 | 106 | EditorGUILayout.BeginHorizontal();/*BeginHorizontal*/ 107 | 108 | if (item == mComponentTool.LastOpComponent) GUI.color = Color.Lerp(GUI.color, Color.red, 0.2f); 109 | 110 | var isWillRemove = mComponentTool.WillRemoveList.Contains(item); 111 | 112 | ColorBlock( 113 | col: isWillRemove ? Color.red : GUI.color 114 | , blockContent: () => ComponentNameBoxRender(item, isWillRemove ? "(WillRemove)" : "")); 115 | 116 | HightLightRectRender(defaultGUIColor); 117 | 118 | if (mComponentTool.IsOrderMode) 119 | { 120 | var delResult = OrderModeBtnGroupRender(item); 121 | if (delResult) break; 122 | } 123 | else 124 | { 125 | if (GUILayout.Button("Cut", GUILayout.MaxWidth(100))) 126 | { 127 | if (item is Transform) 128 | { 129 | EditorUtility.DisplayDialog("Tip", "You Don't Destroy Transform!", "OK"); 130 | return; 131 | } 132 | 133 | mComponentTool.AddCutComponentToCopyList(item); 134 | } 135 | 136 | if (GUILayout.Button("To Copy List", GUILayout.MaxWidth(100))) 137 | { 138 | mComponentTool.AddComponentToCopyList(item); 139 | } 140 | 141 | if (GUILayout.Button("Duplicate", GUILayout.MaxWidth(100))) 142 | { 143 | if (item is Transform) 144 | { 145 | EditorUtility.DisplayDialog("Tip", "You Don't Destroy Transform!", "OK"); 146 | return; 147 | } 148 | 149 | if (mComponentTool.DstObj == null) 150 | { 151 | EditorUtility.DisplayDialog("Tip", "Please Select A Target!", "OK"); 152 | return; 153 | } 154 | 155 | mComponentTool.ComponentDuplicate(item); 156 | } 157 | } 158 | EditorGUILayout.EndHorizontal();/*EndHorizontal*/ 159 | } 160 | GUI.color = defaultGUIColor; 161 | } 162 | #endregion 163 | 164 | #region ---DST Object Components--- 165 | if (mComponentTool.IsMultiDst) 166 | { 167 | GUILayout.Label("Dst(ID:--)", EditorStyles.boldLabel); 168 | GUILayout.Box("Multi Dst Mode"); 169 | } 170 | else if (mComponentTool.DstObj != null) 171 | { 172 | GUILayout.Label(mComponentTool.DstObjInfo, EditorStyles.boldLabel); 173 | var comps = mComponentTool.DstObjComps; 174 | for (int i = 0; i < comps.Length; i++) 175 | { 176 | var item = comps[i]; 177 | 178 | if (item == null) 179 | { 180 | ColorBlock(col: Color.red, blockContent: () => GUILayout.Box("Null(Script) Component")); 181 | continue; 182 | } 183 | 184 | GUILayout.BeginHorizontal();/*BeginHorizontal*/ 185 | 186 | GUI.color = defaultGUIColor; 187 | if (item == mComponentTool.LastOpComponent) GUI.color = Color.Lerp(GUI.color, Color.red, 0.2f); 188 | 189 | ComponentNameBoxRender(item); 190 | 191 | HightLightRectRender(defaultGUIColor); 192 | 193 | if (mComponentTool.IsOrderMode) 194 | { 195 | var delResult = OrderModeBtnGroupRender(item); 196 | if (delResult) return; 197 | } 198 | else 199 | { 200 | if (GUILayout.Button("Paste Value", GUILayout.MaxWidth(200))) 201 | { 202 | if (mComponentTool.CopySelList.Count > 1) 203 | { 204 | EditorUtility.DisplayDialog("Tip", "Please Change To Single Target!", "OK"); 205 | return; 206 | } 207 | else if (mComponentTool.CopySelList.Count < 1) 208 | { 209 | EditorUtility.DisplayDialog("Tip", "Please Select A Target!", "OK"); 210 | return; 211 | } 212 | else 213 | { 214 | mComponentTool.PasteValue(item); 215 | } 216 | } 217 | } 218 | GUILayout.EndHorizontal();/*EndHorizontal*/ 219 | } 220 | GUI.color = defaultGUIColor; 221 | } 222 | #endregion 223 | 224 | if (mComponentTool.CanPaste) 225 | { 226 | if (GUILayout.Button("\nPaste\n")) 227 | ExecutePaste(); 228 | } 229 | 230 | EditorGUILayout.EndScrollView();/*EndScrollView*/ 231 | } 232 | 233 | void RefreshSelectList() 234 | { 235 | mComponentTool.RefreshSelectList(); 236 | 237 | #region ---SRC--- 238 | EditorGUILayout.BeginHorizontal();/*BeginHorizontal*/ 239 | EditorGUILayout.LabelField("Source GameObject"); 240 | 241 | CursorModeRender(targetModeDetectionValue: true); 242 | 243 | mComponentTool.SrcObj = EditorGUILayout.ObjectField(mComponentTool.SrcObj, typeof(GameObject), true) as GameObject; 244 | EditorGUILayout.EndHorizontal();/*EndHorizontal*/ 245 | #endregion 246 | 247 | #region ---DST--- 248 | EditorGUILayout.BeginHorizontal();/*BeginHorizontal*/ 249 | if (mComponentTool.IsMultiDst) 250 | EditorGUILayout.LabelField(string.Format("Dst Multi({0})", mComponentTool.DstObjArr.Length)); 251 | else 252 | EditorGUILayout.LabelField("Destination GameObject"); 253 | 254 | CursorModeRender(targetModeDetectionValue: false); 255 | 256 | if (!mComponentTool.IsMultiDst) 257 | mComponentTool.DstObj = EditorGUILayout.ObjectField(mComponentTool.DstObj, typeof(GameObject), true) as GameObject; 258 | else 259 | GUILayout.Label("Multi Dst Mode"); 260 | 261 | EditorGUILayout.EndHorizontal();/*EndHorizontal*/ 262 | #endregion 263 | } 264 | 265 | void RefreshCopyList() 266 | { 267 | GUILayout.Label(string.Format("-Copy List({0}):", mComponentTool.CopyList.Count)); 268 | 269 | foreach (var item in mComponentTool.CopyList) 270 | { 271 | EditorGUILayout.BeginHorizontal();/*BeginHorizontal*/ 272 | var isContainItem = mComponentTool.CopySelList.Contains(item); 273 | 274 | bool isBreakFlag = false; 275 | ColorBlock(col: isContainItem ? Color.Lerp(GUI.color, Color.green, 0.5f) : GUI.color, 276 | blockContent: () => 277 | { 278 | var guiContent = EditorGUIUtility.ObjectContent(item, item.GetType()); 279 | guiContent.text = item.GetType().Name; 280 | GUILayout.Box(guiContent 281 | , EditorStyles.wordWrappedLabel 282 | , GUILayout.MaxWidth(300) 283 | , GUILayout.Height(EditorGUIUtility.singleLineHeight * 1.2f)); 284 | 285 | if (GUILayout.Button(isContainItem ? "Unselect" : "Select")) 286 | { 287 | mComponentTool.SelectItemFromCopyList(comp: item, isSelect: isContainItem); 288 | isBreakFlag = true; 289 | return; 290 | } 291 | 292 | if (GUILayout.Button("Remove")) 293 | { 294 | mComponentTool.RemoveFromCopyList(item); 295 | isBreakFlag = true; 296 | return; 297 | } 298 | }); 299 | EditorGUILayout.EndHorizontal();/*EndHorizontal*/ 300 | 301 | if (isBreakFlag) break; 302 | } 303 | 304 | if (GUILayout.Button("Reverse Copy List")) mComponentTool.ReverseCopyList(); 305 | if (GUILayout.Button("Clear Copy List")) mComponentTool.ClearCopyList(); 306 | } 307 | 308 | void ExecutePaste() 309 | { 310 | if (mComponentTool.CopySelList.Count <= 0) 311 | { 312 | EditorUtility.DisplayDialog("Tip", "Please Select From Copy List!", "OK"); 313 | return; 314 | } 315 | 316 | if (mComponentTool.CopySelList.FirstOrDefault(m => m is Transform) != null) 317 | { 318 | EditorUtility.DisplayDialog("Tip", "Don't Paste Transform Type!", "OK"); 319 | return; 320 | } 321 | 322 | try { mComponentTool.Paste(); } 323 | catch (Exception e) { EditorUtility.DisplayDialog("Error!", e.ToString(), "OK"); } 324 | } 325 | 326 | void ColorBlock(Color col, Action blockContent) 327 | { 328 | var tmp = GUI.color; 329 | GUI.color = col; 330 | blockContent(); 331 | GUI.color = tmp; 332 | } 333 | 334 | #region ----Common Button Redener Methods---- 335 | void CursorModeRender(bool targetModeDetectionValue) 336 | { 337 | ColorBlock( 338 | col: mComponentTool.SrcOrDstSelection.GetValueOrDefault(!targetModeDetectionValue) == targetModeDetectionValue ? Color.red : GUI.color 339 | , blockContent: () => 340 | { 341 | if (GUILayout.Button("Cursor Mode")) 342 | { 343 | if (mComponentTool.SrcOrDstSelection.GetValueOrDefault(!targetModeDetectionValue) == targetModeDetectionValue) 344 | mComponentTool.SrcOrDstSelection = null; 345 | else 346 | mComponentTool.SrcOrDstSelection = targetModeDetectionValue; 347 | } 348 | }); 349 | } 350 | 351 | void HightLightRectRender(Color defaultGUIColor) 352 | { 353 | var lightRect = GUILayoutUtility.GetLastRect(); 354 | lightRect.width = EditorGUIUtility.currentViewWidth; 355 | if (lightRect.Contains(Event.current.mousePosition)) 356 | { 357 | GUI.color = Color.Lerp(defaultGUIColor, Color.red, 0.4f); 358 | Repaint(); 359 | } 360 | } 361 | 362 | void ComponentNameBoxRender(Component comp, string nameAttachStr = "") 363 | { 364 | var compType = comp.GetType(); 365 | var guiContent = EditorGUIUtility.ObjectContent(comp, compType); 366 | guiContent.text = compType.Name + nameAttachStr; 367 | GUILayout.Box(guiContent 368 | , EditorStyles.wordWrappedLabel 369 | , GUILayout.MaxWidth(300) 370 | , GUILayout.Height(EditorGUIUtility.singleLineHeight * 1.2f)); 371 | } 372 | 373 | /// 374 | /// return is delete success. 375 | /// 376 | bool OrderModeBtnGroupRender(Component comp) 377 | { 378 | if (mComponentTool.IsAttachMode) 379 | { 380 | ToTopBtnRender(comp); 381 | ToBottomBtnRender(comp); 382 | } 383 | else 384 | { 385 | UpBtnRender(comp); 386 | DownBtnRender(comp); 387 | } 388 | 389 | var delResult = DelBtnRender(comp); 390 | 391 | return delResult; 392 | } 393 | 394 | bool DelBtnRender(Component comp) 395 | { 396 | if (GUILayout.Button("Del", GUILayout.MaxWidth(100))) 397 | { 398 | mComponentTool.DeleteComponent(comp); 399 | return true; 400 | } 401 | 402 | return false; 403 | } 404 | 405 | void UpBtnRender(Component comp) { if (GUILayout.Button("Up", GUILayout.MaxWidth(100))) mComponentTool.ComponentToUp(comp); } 406 | 407 | void DownBtnRender(Component comp) { if (GUILayout.Button("Down", GUILayout.MaxWidth(100))) mComponentTool.ComponentToDown(comp); } 408 | 409 | void ToTopBtnRender(Component comp) { if (GUILayout.Button("To Top", GUILayout.MaxWidth(100))) mComponentTool.ComponentToTop(comp); } 410 | 411 | void ToBottomBtnRender(Component comp) { if (GUILayout.Button("To Bottom", GUILayout.MaxWidth(100))) mComponentTool.ComponentToBottom(comp); } 412 | #endregion 413 | } 414 | } 415 | --------------------------------------------------------------------------------