PrefabUtility.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. using System;
  4. using System.Runtime.CompilerServices;
  5. using bs;
  6. namespace bs.Editor
  7. {
  8. /** @addtogroup Utility-Editor
  9. * @{
  10. */
  11. /// <summary>
  12. /// Performs various prefab specific operations.
  13. /// </summary>
  14. public static class PrefabUtility
  15. {
  16. /// <summary>
  17. /// Breaks the link between a prefab instance and its prefab. Object will retain all current values but will
  18. /// no longer be influenced by modifications to its parent prefab.
  19. /// </summary>
  20. /// <param name="obj">Prefab instance whose link to break.</param>
  21. public static void BreakPrefab(SceneObject obj)
  22. {
  23. if (obj == null)
  24. return;
  25. IntPtr objPtr = obj.GetCachedPtr();
  26. Internal_BreakPrefab(objPtr);
  27. }
  28. /// <summary>
  29. /// Updates the contents of the prefab with the contents of the provided prefab instance. If the provided object
  30. /// is not a prefab instance nothing happens.
  31. /// </summary>
  32. /// <param name="obj">Prefab instance whose prefab to update.</param>
  33. /// <param name="refreshScene">If true, all prefab instances in the current scene will be updated so they consistent
  34. /// with the newly saved data.</param>
  35. public static void ApplyPrefab(SceneObject obj, bool refreshScene = true)
  36. {
  37. if (obj == null)
  38. return;
  39. SceneObject prefabInstanceRoot = GetPrefabParent(obj);
  40. if (prefabInstanceRoot == null)
  41. return;
  42. if (refreshScene)
  43. {
  44. SceneObject root = Scene.Root;
  45. if (root != null)
  46. Internal_RecordPrefabDiff(root.GetCachedPtr());
  47. }
  48. UUID prefabUUID = GetPrefabUUID(prefabInstanceRoot);
  49. string prefabPath = ProjectLibrary.GetPath(prefabUUID);
  50. Prefab prefab = ProjectLibrary.Load<Prefab>(prefabPath);
  51. if (prefab != null)
  52. {
  53. IntPtr soPtr = prefabInstanceRoot.GetCachedPtr();
  54. IntPtr prefabPtr = prefab.GetCachedPtr();
  55. Internal_ApplyPrefab(soPtr, prefabPtr);
  56. ProjectLibrary.Save(prefab);
  57. }
  58. if (refreshScene)
  59. {
  60. SceneObject root = Scene.Root;
  61. if (root != null)
  62. Internal_UpdateFromPrefab(root.GetCachedPtr());
  63. }
  64. }
  65. /// <summary>
  66. /// Remove any instance specific changes to the object or its hierarchy from the provided prefab instance and
  67. /// restore it to the exact copy of the linked prefab.
  68. /// </summary>
  69. /// <param name="obj">Prefab instance to revert to original state.</param>
  70. public static void RevertPrefab(SceneObject obj)
  71. {
  72. if (obj == null)
  73. return;
  74. IntPtr objPtr = obj.GetCachedPtr();
  75. Internal_RevertPrefab(objPtr);
  76. }
  77. /// <summary>
  78. /// Updates all of the objects belonging to the same prefab instance as the provided object (if any). The update
  79. /// will apply any changes from the linked prefab to the hierarchy(if any).
  80. /// </summary>
  81. /// <param name="obj"></param>
  82. public static void UpdateFromPrefab(SceneObject obj)
  83. {
  84. if (obj == null)
  85. return;
  86. IntPtr objPtr = obj.GetCachedPtr();
  87. Internal_UpdateFromPrefab(objPtr);
  88. }
  89. /// <summary>
  90. /// Checks if a scene object has a prefab link. Scene objects with a prefab link will be automatically updated
  91. /// when their prefab changes in order to reflect its changes.
  92. /// </summary>
  93. /// <param name="obj">Scene object to check if it has a prefab link.</param>
  94. /// <returns>True if the object is a prefab instance (has a prefab link), false otherwise.</returns>
  95. public static bool IsPrefabInstance(SceneObject obj)
  96. {
  97. if (obj == null)
  98. return false;
  99. IntPtr objPtr = obj.GetCachedPtr();
  100. return Internal_HasPrefabLink(objPtr);
  101. }
  102. /// <summary>
  103. /// Returns the root object of the prefab instance that this object belongs to, if any.
  104. /// </summary>
  105. /// <param name="obj">Scene object to retrieve the prefab parent for.</param>
  106. /// <returns>Prefab parent of the provided object, or null if the object is not part of a prefab instance.</returns>
  107. public static SceneObject GetPrefabParent(SceneObject obj)
  108. {
  109. if (obj == null)
  110. return null;
  111. IntPtr objPtr = obj.GetCachedPtr();
  112. return Internal_GetPrefabParent(objPtr);
  113. }
  114. /// <summary>
  115. /// Returns the UUID of the prefab attached to the provided scene object. Only works on root prefab objects.
  116. /// </summary>
  117. /// <param name="obj">Scene object to retrieve the prefab UUID for.</param>
  118. /// <returns>Prefab UUID if the object is part of a prefab, null otherwise. </returns>
  119. public static UUID GetPrefabUUID(SceneObject obj)
  120. {
  121. if (obj == null)
  122. return UUID.Empty;
  123. IntPtr objPtr = obj.GetCachedPtr();
  124. UUID uuid;
  125. Internal_GetPrefabUUID(objPtr, out uuid);
  126. return uuid;
  127. }
  128. [MethodImpl(MethodImplOptions.InternalCall)]
  129. private static extern void Internal_BreakPrefab(IntPtr soPtr);
  130. [MethodImpl(MethodImplOptions.InternalCall)]
  131. private static extern void Internal_ApplyPrefab(IntPtr soPtr, IntPtr prefabPtr);
  132. [MethodImpl(MethodImplOptions.InternalCall)]
  133. private static extern void Internal_RecordPrefabDiff(IntPtr soPtr);
  134. [MethodImpl(MethodImplOptions.InternalCall)]
  135. private static extern void Internal_RevertPrefab(IntPtr soPtr);
  136. [MethodImpl(MethodImplOptions.InternalCall)]
  137. private static extern bool Internal_HasPrefabLink(IntPtr soPtr);
  138. [MethodImpl(MethodImplOptions.InternalCall)]
  139. private static extern void Internal_UpdateFromPrefab(IntPtr soPtr);
  140. [MethodImpl(MethodImplOptions.InternalCall)]
  141. private static extern SceneObject Internal_GetPrefabParent(IntPtr soPtr);
  142. [MethodImpl(MethodImplOptions.InternalCall)]
  143. private static extern void Internal_GetPrefabUUID(IntPtr soPtr, out UUID uuid);
  144. }
  145. /** @} */
  146. }