Guest User

Untitled

a guest
May 22nd, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.93 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEditor;
  5. using UnityEditorInternal;
  6. using System.Linq;
  7. using System.Reflection;
  8.  
  9. //オブジェクトのコンポーネントを別の奴にコピーする
  10. public class CopyTransformComponents : ScriptableWizard
  11. {
  12. public Transform fromTransform;
  13. public Transform toTransform;
  14.  
  15. [MenuItem("Utils/CopyTransformComponents")]
  16. static void Open()
  17. {
  18. DisplayWizard<CopyTransformComponents>("CopyTransformComponents");
  19. }
  20.  
  21. //実行
  22. void OnWizardCreate()
  23. {
  24. if (fromTransform != null && toTransform != null)
  25. {
  26. Execute();
  27. }
  28. else
  29. {
  30. if (fromTransform == null)
  31. {
  32. Debug.Log("fromTransform == null");
  33. }
  34. if (toTransform == null)
  35. {
  36. Debug.Log("toTransform == null");
  37. }
  38. }
  39. }
  40.  
  41. void Execute()
  42. {
  43. //to側に無いオブジェクトはfromからコピーしてくる。あればコンポーネントのコピー
  44. ProcessTransform(fromTransform, toTransform);
  45. }
  46.  
  47. static void CopyComponents(GameObject from, GameObject to)
  48. {
  49. //var currentGameObject = Selection.activeGameObject;
  50.  
  51. var components = from.GetComponents<Component>();
  52. var targetComponents = to.GetComponents<Component>();
  53. Dictionary<System.Type, int> currentComponentCount = new Dictionary<System.Type, int>();
  54.  
  55. foreach (var component in components)
  56. {
  57. if (component is SkinnedMeshRenderer)//skinnedMeshRendererはスキップ
  58. { continue;}
  59.  
  60. var componentCount = targetComponents.Count(c => c.GetType() == component.GetType());
  61. ComponentUtility.CopyComponent(component);
  62. if (componentCount == 0)
  63. {
  64. ComponentUtility.PasteComponentAsNew(to);
  65. }
  66. else if (componentCount == 1)
  67. {
  68. var targetComponent = targetComponents.First(c => c.GetType() == component.GetType());
  69. ComponentUtility.PasteComponentValues(targetComponent);
  70. }
  71. else
  72. {
  73. if (currentComponentCount.ContainsKey(component.GetType()) == false)
  74. {
  75. currentComponentCount.Add(component.GetType(), 0);
  76. }
  77. var count = currentComponentCount[component.GetType()];
  78. var targetComponentsWithType = targetComponents.Where(c => c.GetType() == component.GetType());
  79. if (count < targetComponentsWithType.Count())
  80. {
  81. var targetComponent = targetComponents.Where(c => c.GetType() == component.GetType()).ElementAt(count);
  82. currentComponentCount[component.GetType()] += 1;
  83. ComponentUtility.PasteComponentValues(targetComponent);
  84. }
  85. else
  86. {
  87. ComponentUtility.PasteComponentAsNew(to);
  88. }
  89. }
  90. }
  91. }
  92.  
  93. void ProcessTransform(Transform from, Transform to)
  94. {
  95. //コンポーネント全部コピー(上書き)
  96. CopyComponents(from.gameObject, to.gameObject);
  97.  
  98. //Transform、GameObjectの参照を差し替える
  99. ProcessReflection(from, to);
  100.  
  101. //子供に対して同様の処理
  102. for (int i = 0; i < from.childCount; i++)
  103. {
  104. var fromObject = from.GetChild(i);
  105. var fromName = fromObject.name;
  106.  
  107. //toの子供に同じ名前のtransformあるか?
  108. bool findFlag = false;
  109. for (int j = 0; j < to.childCount; j++)
  110. {
  111. var toObject = to.GetChild(j);
  112. if (toObject.name == fromName)
  113. {
  114. ProcessTransform(fromObject, toObject);
  115. findFlag = true;
  116. break;//次へ
  117. }
  118. }
  119.  
  120. if (!findFlag)//見つからなかったらオブジェクトごとコピー
  121. {
  122. var newObj = GameObject.Instantiate(fromObject.gameObject, to);
  123. newObj.name = fromObject.name;
  124. ProcessTransform(fromObject, newObj.transform);
  125. }
  126.  
  127. }
  128. }
  129.  
  130. //Breadth-first search
  131. public Transform FindDeepChild(Transform aParent, string aName)
  132. {
  133. var result = aParent.Find(aName);
  134. if (result != null)
  135. return result;
  136. foreach (Transform child in aParent)
  137. {
  138. result = FindDeepChild(child,aName);
  139. if (result != null)
  140. return result;
  141. }
  142. return null;
  143. }
  144.  
  145. void ProcessReflection(Transform from, Transform to)
  146. {
  147. var fromComponents = from.GetComponents<Component>();
  148. for (int i = 0; i < fromComponents.Length; i++) //全コンポーネントについて
  149. {
  150. var fromType = fromComponents[i].GetType();
  151. //Debug.Log(fromType);
  152.  
  153. var toComponent = to.GetComponent(fromType);
  154.  
  155. if (toComponent == null)
  156. {
  157. //Debug.Log(toComponent + "==null");
  158. continue;
  159. }
  160.  
  161. //フィールドを取得する
  162. MemberInfo[] members = fromType.GetMembers(
  163. BindingFlags.Public | BindingFlags.NonPublic |
  164. BindingFlags.Instance );
  165.  
  166. //Debug.Log(members);
  167.  
  168. foreach (var m in members)
  169. {
  170.  
  171. if (m.MemberType != MemberTypes.Field)
  172. {
  173. continue;
  174. }
  175.  
  176. System.Type fieldType = ((FieldInfo)m).FieldType;
  177.  
  178. //transformとgameobjectを差し替える
  179. if (fieldType == typeof(Transform) || fieldType == typeof(GameObject))
  180. {
  181. string targetName;//差し替えるtransformの名前
  182. FieldInfo field = fromType.GetField(m.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  183. if (fieldType == typeof(Transform))
  184. {
  185. Transform t = (Transform)field.GetValue(fromComponents[i]);
  186. if (t == null)
  187. {
  188. continue;
  189. }
  190. targetName = t.name;
  191. }
  192. else if (fieldType == typeof(GameObject))
  193. {
  194. GameObject obj = (GameObject)field.GetValue(fromComponents[i]);
  195. if (obj == null)
  196. {
  197. continue;
  198. }
  199. targetName = obj.name;
  200. }
  201. else
  202. {
  203. continue;
  204. }
  205.  
  206. //toObjectから同名オブジェクトサーチ
  207. var targetTransform = FindDeepChild(toTransform, targetName);
  208. if (targetTransform != null)
  209. {
  210.  
  211. FieldInfo setField = fromType.GetField(m.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  212. if (setField == null)
  213. {
  214. Debug.Log("setField == null:" + m.Name);
  215. }
  216. else
  217. {
  218. if (fieldType == typeof(Transform))
  219. {
  220. setField.SetValue(toComponent, targetTransform);//セット
  221. }
  222. else if (fieldType == typeof(GameObject))
  223. {
  224. setField.SetValue(toComponent, targetTransform.gameObject);//セット
  225. }
  226. }
  227. }
  228. }
  229. else if (fieldType == typeof(Transform[]))
  230. {
  231. string[] targetNames;//差し替えるtransformの名前
  232. FieldInfo field = fromType.GetField(m.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  233. Transform[] t = (Transform[])field.GetValue(fromComponents[i]);
  234. if (t == null)
  235. {
  236. continue;
  237. }
  238. targetNames = new string[t.Length];
  239. for (int j = 0; j < t.Length; j++)
  240. {
  241. if (t[j] == null)
  242. {
  243. targetNames[j] = null;
  244. }
  245. else
  246. {
  247. targetNames[j] = t[j].name;
  248. }
  249. }
  250.  
  251. Transform[] newTransformArray = new Transform[t.Length];
  252.  
  253. for (int j = 0; j < t.Length; j++)
  254. {
  255. if (targetNames[j] == null)
  256. {
  257. continue;
  258. }
  259.  
  260. //toObjectから同名オブジェクトサーチ
  261. var targetTransform = FindDeepChild(toTransform, targetNames[j]);
  262. if (targetTransform != null)
  263. {
  264. newTransformArray[j] = targetTransform;
  265. }
  266. }
  267.  
  268. FieldInfo setField = fromType.GetField(m.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  269. if (setField == null)
  270. {
  271. Debug.Log("setField == null:" + m.Name);
  272. }
  273. else
  274. {
  275. setField.SetValue(toComponent, newTransformArray);//セット
  276. }
  277. }
  278. else if (fieldType == typeof(GameObject[]))
  279. {
  280. string[] targetNames;//差し替えるtransformの名前
  281. FieldInfo field = fromType.GetField(m.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  282. GameObject[] t = (GameObject[])field.GetValue(fromComponents[i]);
  283. if (t == null)
  284. {
  285. continue;
  286. }
  287. targetNames = new string[t.Length];
  288. for (int j = 0; j < t.Length; j++)
  289. {
  290. if (t[j] == null)
  291. {
  292. targetNames[j] = null;
  293. }
  294. else
  295. {
  296. targetNames[j] = t[j].name;
  297. }
  298. }
  299.  
  300. GameObject[] newArray = new GameObject[t.Length];
  301.  
  302. for (int j = 0; j < t.Length; j++)
  303. {
  304. if (targetNames[j] == null)
  305. {
  306. continue;
  307. }
  308.  
  309. //toObjectから同名オブジェクトサーチ
  310. var targetTransform = FindDeepChild(toTransform, targetNames[j]);
  311. if (targetTransform != null)
  312. {
  313. newArray[j] = targetTransform.gameObject;
  314. }
  315. }
  316.  
  317. FieldInfo setField = fromType.GetField(m.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
  318. if (setField == null)
  319. {
  320. Debug.Log("setField == null:" + m.Name);
  321. }
  322. else
  323. {
  324. setField.SetValue(toComponent, newArray);//セット
  325. }
  326. }
  327. }
  328. }
  329.  
  330. }
  331.  
  332.  
  333. }
Add Comment
Please, Sign In to add comment