Browse Source

Fixed a bug where applying a prefab on a non-root prefab instance SO would not properly save the prefab
Saving a prefab via Apply will now properly save the resource in Resources folder as well as the project library, so version control can pick it up

BearishSun 9 years ago
parent
commit
e791a68e45

+ 23 - 10
Source/MBansheeEditor/Utility/PrefabUtility.cs

@@ -41,6 +41,10 @@ namespace BansheeEditor
             if (obj == null)
                 return;
 
+            SceneObject prefabInstanceRoot = GetPrefabParent(obj);
+            if (prefabInstanceRoot == null)
+                return;
+
             if (refreshScene)
             {
                 SceneObject root = Scene.Root;
@@ -48,8 +52,17 @@ namespace BansheeEditor
                     Internal_RecordPrefabDiff(root.GetCachedPtr());
             }
 
-            IntPtr objPtr = obj.GetCachedPtr();
-            Internal_ApplyPrefab(objPtr);
+            string prefabUUID = GetPrefabUUID(prefabInstanceRoot);
+            string prefabPath = ProjectLibrary.GetPath(prefabUUID);
+            Prefab prefab = ProjectLibrary.Load<Prefab>(prefabPath);
+            if (prefab != null)
+            {
+                IntPtr soPtr = prefabInstanceRoot.GetCachedPtr();
+                IntPtr prefabPtr = prefab.GetCachedPtr();
+
+                Internal_ApplyPrefab(soPtr, prefabPtr);
+                ProjectLibrary.Save(prefab);
+            }
 
             if (refreshScene)
             {
@@ -131,28 +144,28 @@ namespace BansheeEditor
         }
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_BreakPrefab(IntPtr nativeInstance);
+        private static extern void Internal_BreakPrefab(IntPtr soPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_ApplyPrefab(IntPtr nativeInstance);
+        private static extern void Internal_ApplyPrefab(IntPtr soPtr, IntPtr prefabPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_RecordPrefabDiff(IntPtr nativeInstance);
+        private static extern void Internal_RecordPrefabDiff(IntPtr soPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_RevertPrefab(IntPtr nativeInstance);
+        private static extern void Internal_RevertPrefab(IntPtr soPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern bool Internal_HasPrefabLink(IntPtr nativeInstance);
+        private static extern bool Internal_HasPrefabLink(IntPtr soPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern void Internal_UpdateFromPrefab(IntPtr nativeInstance);
+        private static extern void Internal_UpdateFromPrefab(IntPtr soPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern SceneObject Internal_GetPrefabParent(IntPtr nativeInstance);
+        private static extern SceneObject Internal_GetPrefabParent(IntPtr soPtr);
 
         [MethodImpl(MethodImplOptions.InternalCall)]
-        private static extern string Internal_GetPrefabUUID(IntPtr nativeInstance);
+        private static extern string Internal_GetPrefabUUID(IntPtr soPtr);
     }
 
     /** @} */

+ 8 - 8
Source/SBansheeEditor/Include/BsScriptPrefabUtility.h

@@ -21,14 +21,14 @@ namespace BansheeEngine
 		/************************************************************************/
 		/* 								CLR HOOKS						   		*/
 		/************************************************************************/
-		static void internal_breakPrefab(ScriptSceneObject* nativeInstance);
-		static void internal_applyPrefab(ScriptSceneObject* nativeInstance);
-		static void internal_revertPrefab(ScriptSceneObject* nativeInstance);
-		static bool internal_hasPrefabLink(ScriptSceneObject* nativeInstance);
-		static MonoObject* internal_getPrefabParent(ScriptSceneObject* nativeInstance);
-		static MonoString* internal_GetPrefabUUID(ScriptSceneObject* nativeInstance);
-		static void internal_UpdateFromPrefab(ScriptSceneObject* nativeInstance);
-		static void internal_RecordPrefabDiff(ScriptSceneObject* nativeInstance);
+		static void internal_breakPrefab(ScriptSceneObject* soPtr);
+		static void internal_applyPrefab(ScriptSceneObject* soPtr, ScriptPrefab* prefabPtr);
+		static void internal_revertPrefab(ScriptSceneObject* soPtr);
+		static bool internal_hasPrefabLink(ScriptSceneObject* soPtr);
+		static MonoObject* internal_getPrefabParent(ScriptSceneObject* soPtr);
+		static MonoString* internal_GetPrefabUUID(ScriptSceneObject* soPtr);
+		static void internal_UpdateFromPrefab(ScriptSceneObject* soPtr);
+		static void internal_RecordPrefabDiff(ScriptSceneObject* soPtr);
 
 		ScriptPrefabUtility(MonoObject* instance);
 	};

+ 30 - 34
Source/SBansheeEditor/Source/BsScriptPrefabUtility.cpp

@@ -10,6 +10,7 @@
 #include "BsResources.h"
 #include "BsMonoUtil.h"
 #include "BsScriptGameObjectManager.h"
+#include "BsScriptPrefab.h"
 
 namespace BansheeEngine
 {
@@ -29,52 +30,44 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_RecordPrefabDiff", &ScriptPrefabUtility::internal_RecordPrefabDiff);
 	}
 
-	void ScriptPrefabUtility::internal_breakPrefab(ScriptSceneObject* nativeInstance)
+	void ScriptPrefabUtility::internal_breakPrefab(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return;
 
-		nativeInstance->getNativeSceneObject()->breakPrefabLink();
+		soPtr->getNativeSceneObject()->breakPrefabLink();
 	}
 
-	void ScriptPrefabUtility::internal_applyPrefab(ScriptSceneObject* nativeInstance)
+	void ScriptPrefabUtility::internal_applyPrefab(ScriptSceneObject* soPtr, ScriptPrefab* prefabPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return;
 
-		ResourceLoadFlags loadFlags = ResourceLoadFlag::KeepInternalRef | ResourceLoadFlag::KeepSourceData;
-
-		String prefabLinkUUID = nativeInstance->getNativeSceneObject()->getPrefabLink();
-		HPrefab prefab = static_resource_cast<Prefab>(gResources().loadFromUUID(prefabLinkUUID, false, loadFlags));
-
-		if (prefab != nullptr)
-			prefab->update(nativeInstance->getNativeSceneObject());
-
-		gResources().save(prefab);
+		prefabPtr->getHandle()->update(soPtr->getNativeSceneObject());
 	}
 
-	void ScriptPrefabUtility::internal_revertPrefab(ScriptSceneObject* nativeInstance)
+	void ScriptPrefabUtility::internal_revertPrefab(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return;
 
-		PrefabUtility::revertToPrefab(nativeInstance->getNativeSceneObject());
+		PrefabUtility::revertToPrefab(soPtr->getNativeSceneObject());
 	}
 
-	bool ScriptPrefabUtility::internal_hasPrefabLink(ScriptSceneObject* nativeInstance)
+	bool ScriptPrefabUtility::internal_hasPrefabLink(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return false;
 
-		return !nativeInstance->getNativeSceneObject()->getPrefabLink(true).empty();
+		return !soPtr->getNativeSceneObject()->getPrefabLink(true).empty();
 	}
 
-	MonoObject* ScriptPrefabUtility::internal_getPrefabParent(ScriptSceneObject* nativeInstance)
+	MonoObject* ScriptPrefabUtility::internal_getPrefabParent(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return nullptr;
 
-		HSceneObject so = nativeInstance->getNativeSceneObject();
+		HSceneObject so = soPtr->getNativeSceneObject();
 		HSceneObject parent = so->getPrefabParent();
 
 		if (parent != nullptr)
@@ -86,35 +79,38 @@ namespace BansheeEngine
 		return nullptr;
 	}
 
-	MonoString* ScriptPrefabUtility::internal_GetPrefabUUID(ScriptSceneObject* nativeInstance)
+	MonoString* ScriptPrefabUtility::internal_GetPrefabUUID(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return nullptr;
 
-		HSceneObject so = nativeInstance->getNativeSceneObject();
+		HSceneObject so = soPtr->getNativeSceneObject();
 
-		String prefabUUID = nativeInstance->getNativeSceneObject()->getPrefabLink(true);
+		String prefabUUID = soPtr->getNativeSceneObject()->getPrefabLink(true);
 		if (prefabUUID.empty())
 			return nullptr;
 
 		return MonoUtil::stringToMono(prefabUUID);
 	}
 
-	void ScriptPrefabUtility::internal_UpdateFromPrefab(ScriptSceneObject* nativeInstance)
+	void ScriptPrefabUtility::internal_UpdateFromPrefab(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return;
 
-		HSceneObject so = nativeInstance->getNativeSceneObject();
-		PrefabUtility::updateFromPrefab(so);
+		HSceneObject so = soPtr->getNativeSceneObject();
+		HSceneObject prefabParent = so->getPrefabParent();
+
+		if(prefabParent != nullptr)
+			PrefabUtility::updateFromPrefab(prefabParent);
 	}
 
-	void ScriptPrefabUtility::internal_RecordPrefabDiff(ScriptSceneObject* nativeInstance)
+	void ScriptPrefabUtility::internal_RecordPrefabDiff(ScriptSceneObject* soPtr)
 	{
-		if (ScriptSceneObject::checkIfDestroyed(nativeInstance))
+		if (ScriptSceneObject::checkIfDestroyed(soPtr))
 			return;
 
-		HSceneObject so = nativeInstance->getNativeSceneObject();
+		HSceneObject so = soPtr->getNativeSceneObject();
 		PrefabUtility::recordPrefabDiff(so);
 	}
 }