BuildCommon.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // Magica Cloth.
  2. // Copyright (c) MagicaSoft, 2020-2022.
  3. // https://magicasoft.jp
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using UnityEditor;
  8. using UnityEngine;
  9. namespace MagicaCloth
  10. {
  11. public static partial class BuildManager
  12. {
  13. /// <summary>
  14. /// 共有データの作成
  15. /// </summary>
  16. /// <typeparam name="T"></typeparam>
  17. /// <param name="dataName"></param>
  18. /// <param name="savePrefabPath">共有データ保存先プレハブパス.null=保存しない</param>
  19. /// <returns></returns>
  20. static T CreateShareData<T>(string dataName, string savePrefabPath) where T : ShareDataObject
  21. {
  22. // 共有データ作成
  23. var sdata = ShareDataObject.CreateShareData<T>(dataName);
  24. // 同時にプレハブにデータを保存するか判定
  25. // (データをアセットデータベースで直接作成する場合)
  26. if (string.IsNullOrEmpty(savePrefabPath) == false)
  27. {
  28. SaveShareDataSubAsset(sdata, savePrefabPath);
  29. }
  30. return sdata;
  31. }
  32. /// <summary>
  33. /// 共有データを指定プレハブのサブアセットとして保存する
  34. /// </summary>
  35. /// <param name="sdata"></param>
  36. /// <param name="savePrefabPath"></param>
  37. /// <returns></returns>
  38. static bool SaveShareDataSubAsset(ShareDataObject sdata, string savePrefabPath)
  39. {
  40. // 保存先プレハブアセット
  41. var savePrefab = AssetDatabase.LoadAssetAtPath<GameObject>(savePrefabPath);
  42. if (savePrefab == null)
  43. return false;
  44. // 編集不可のプレハブならば保存できないため処理を行わない
  45. if (PrefabUtility.IsPartOfImmutablePrefab(savePrefab))
  46. {
  47. return false;
  48. }
  49. // サブアセットとしてプレハブに保存する
  50. AssetDatabase.AddObjectToAsset(sdata, savePrefab);
  51. return true;
  52. }
  53. /// <summary>
  54. /// 指定コンポーネントの共有データが外部にアセットとして保存されているか判定する
  55. /// </summary>
  56. /// <param name="core"></param>
  57. /// <returns></returns>
  58. static bool IsExternalShareDataObject(CoreComponent core)
  59. {
  60. Debug.Assert(core);
  61. bool ret = false;
  62. try
  63. {
  64. if (core is BaseCloth)
  65. {
  66. var cloth = core as BaseCloth;
  67. if (cloth.ClothData != null)
  68. ret = AssetDatabase.IsForeignAsset(cloth.ClothData) ? true : ret;
  69. if (cloth is MagicaMeshSpring)
  70. ret = AssetDatabase.IsForeignAsset((cloth as MagicaMeshSpring).SpringData) ? true : ret;
  71. }
  72. else if (core is MagicaRenderDeformer)
  73. {
  74. ret = AssetDatabase.IsForeignAsset((core as MagicaRenderDeformer).Deformer.MeshData) ? true : ret;
  75. }
  76. else if (core is MagicaVirtualDeformer)
  77. {
  78. ret = AssetDatabase.IsForeignAsset((core as MagicaVirtualDeformer).Deformer.MeshData) ? true : ret;
  79. }
  80. }
  81. catch (Exception)
  82. {
  83. // Reference is missing!
  84. ret = false;
  85. }
  86. return ret;
  87. }
  88. /// <summary>
  89. /// データが未作成か判定する
  90. /// </summary>
  91. /// <param name="core"></param>
  92. /// <returns></returns>
  93. static bool IsNotCreated(CoreComponent core)
  94. {
  95. Debug.Assert(core);
  96. return Define.IsError(core.VerifyData());
  97. }
  98. /// <summary>
  99. /// データが古いフォーマットか判定する
  100. /// </summary>
  101. /// <param name="core"></param>
  102. /// <returns></returns>
  103. static bool IsOldFormat(CoreComponent core)
  104. {
  105. Debug.Assert(core);
  106. return core.IsOldDataVertion();
  107. }
  108. /// <summary>
  109. /// 古いアルゴリズムを使用しているか判定する
  110. /// </summary>
  111. /// <param name="core"></param>
  112. /// <returns></returns>
  113. static bool IsOldAlgorithm(CoreComponent core)
  114. {
  115. Debug.Assert(core);
  116. if (core is BaseCloth)
  117. {
  118. var cloth = core as BaseCloth;
  119. // パラメータの設定が古いアルゴリズムを指している
  120. if (cloth.Params.AlgorithmType != ClothParams.Algorithm.Algorithm_2)
  121. return true;
  122. // すでに作成されたデータのアルゴリズムが古い
  123. if (cloth.ClothData != null && Define.IsError(cloth.VerifyAlgorithmVersion()))
  124. return true;
  125. }
  126. return false;
  127. }
  128. /// <summary>
  129. /// 指定ゲームオブジェクトからビルドに必要なコンポーネントを検索しリストに追加する
  130. /// </summary>
  131. /// <param name="gobj"></param>
  132. /// <param name="options"></param>
  133. /// <param name="coreComponents"></param>
  134. /// <returns></returns>
  135. static void GetBuildComponents(GameObject gobj, BuildOptions options, List<CoreComponent> coreComponents)
  136. {
  137. if (gobj == null)
  138. return;
  139. // シーンに配置されているか
  140. bool isScene = gobj.scene.IsValid();
  141. // 全コンポーネント取得
  142. var components = new List<CoreComponent>(
  143. gobj.GetComponentsInChildren<CoreComponent>(options.includeInactive)
  144. // コンバートコンポーネントの選別
  145. .Where(x =>
  146. x is MagicaBoneCloth && options.buildBoneCloth
  147. || x is MagicaBoneSpring && options.buildBoneSpring
  148. || x is MagicaMeshCloth && options.buildMeshCloth
  149. || x is MagicaMeshSpring && options.buildMeshSpring
  150. || x is MagicaRenderDeformer && options.buildRenderDeformer
  151. || x is MagicaVirtualDeformer && options.buildVirtualDeformer
  152. )
  153. // シーン配置の場合は共有データが外部に保存されているなら無効とする
  154. .Where(x => isScene == false || IsExternalShareDataObject(x) == false)
  155. // ビルド条件
  156. .Where(x =>
  157. options.forceBuild
  158. || options.verificationOnly
  159. || options.notCreated && IsNotCreated(x)
  160. || options.upgradeFormatAndAlgorithm && (IsOldFormat(x) || IsOldAlgorithm(x))
  161. )
  162. );
  163. coreComponents.AddRange(components);
  164. }
  165. /// <summary>
  166. /// コンポーネントリストをビルド順番にソートする
  167. /// </summary>
  168. /// <param name="coreComponents"></param>
  169. static void SortCoreComponents(List<CoreComponent> coreComponents)
  170. {
  171. // RenderDeformer > VirtualDeformer > ClothComponent の順でソートする
  172. // この順でデータを作成しないと駄目!
  173. coreComponents.Sort((a, b) => a.GetComponentType() < b.GetComponentType() ? -1 : 1);
  174. }
  175. /// <summary>
  176. /// データを保存するアセットパスを取得する
  177. /// プレハブかつシーンに配置されていない場合のみ有効なパスが帰る
  178. /// </summary>
  179. /// <param name="core"></param>
  180. /// <returns></returns>
  181. static string GetAssetSavePath(CoreComponent core)
  182. {
  183. if (core == null)
  184. return null;
  185. return EditorUtility.IsPersistent(core) ? PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(core) : null;
  186. }
  187. /// <summary>
  188. /// 指定オブジェクト(プレハブ)にMissingスクリプトが含まれているかチェックする
  189. /// </summary>
  190. /// <param name="go"></param>
  191. /// <returns></returns>
  192. static bool CheckMissingScripts(GameObject go)
  193. {
  194. return go.GetComponentsInChildren<Component>().Contains(null);
  195. }
  196. }
  197. }