Ver Fonte

Added remaining features to C# SceneObject
You will now be warned if you try to access component or scene object that has been destroyed, instead of getting an exception

Marko Pintera há 11 anos atrás
pai
commit
4164a1af25

+ 8 - 8
MBansheeEditor/DbgGizmo.cs

@@ -20,15 +20,15 @@ namespace BansheeEditor
                 iconTexture = new SpriteTexture(iconTex);
             }
 
-            Gizmos.DrawCube(target.sceneObject.position, new Vector3(1, 1, 1));
-            Gizmos.DrawSphere(target.sceneObject.position + 2 * Vector3.xAxis, 1.0f);
-            Gizmos.DrawWireCube(target.sceneObject.position + 4 * Vector3.xAxis, new Vector3(1, 1, 1));
-            Gizmos.DrawWireSphere(target.sceneObject.position + 6 * Vector3.xAxis, 1.0f);
-            Gizmos.DrawLine(target.sceneObject.position + 7.5f * Vector3.xAxis,
-                target.sceneObject.position + 8.5f * Vector3.xAxis);
-            Gizmos.DrawFrustum(target.sceneObject.position + 10 * Vector3.xAxis, 1920.0f / 1080.0f, 90, 1.0f, 1000.0f);
+            Gizmos.DrawCube(target.sceneObject.Position, new Vector3(1, 1, 1));
+            Gizmos.DrawSphere(target.sceneObject.Position + 2 * Vector3.xAxis, 1.0f);
+            Gizmos.DrawWireCube(target.sceneObject.Position + 4 * Vector3.xAxis, new Vector3(1, 1, 1));
+            Gizmos.DrawWireSphere(target.sceneObject.Position + 6 * Vector3.xAxis, 1.0f);
+            Gizmos.DrawLine(target.sceneObject.Position + 7.5f * Vector3.xAxis,
+                target.sceneObject.Position + 8.5f * Vector3.xAxis);
+            Gizmos.DrawFrustum(target.sceneObject.Position + 10 * Vector3.xAxis, 1920.0f / 1080.0f, 90, 1.0f, 1000.0f);
 
-            Gizmos.DrawIcon(target.sceneObject.position + new Vector3(0, 10, 0), iconTexture, false);
+            Gizmos.DrawIcon(target.sceneObject.Position + new Vector3(0, 10, 0), iconTexture, false);
         }
     }
 }

+ 4 - 4
MBansheeEditor/DebugCameraHandle.cs

@@ -18,24 +18,24 @@ namespace BansheeEditor
 
         protected override void PreInput()
         {
-            xAxis.Position = target.sceneObject.position;
+            xAxis.Position = target.sceneObject.Position;
         }
 
         protected override void PostInput()
         {
-            target.sceneObject.position = xAxis.NewPosition;
+            target.sceneObject.Position = xAxis.NewPosition;
         }
 
         protected override void Draw()
         {
-            Vector3 end = target.sceneObject.position + Vector3.xAxis * 5;
+            Vector3 end = target.sceneObject.Position + Vector3.xAxis * 5;
 
             if (xAxis.State == HandleSlider.StateType.Active)
                 HandleDrawing.SetColor(Color.white);
             else
                 HandleDrawing.SetColor(Color.green);
 
-            HandleDrawing.DrawLine(target.sceneObject.position, end);
+            HandleDrawing.DrawLine(target.sceneObject.Position, end);
         }
     }
 }

+ 3 - 3
MBansheeEditor/Scene/DefaultHandleManager.cs

@@ -53,11 +53,11 @@ namespace BansheeEditor
                 if (EditorApplication.HandleCoordinateMode == HandleCoordinateMode.World)
                     rotation = Quaternion.identity;
                 else
-                    rotation = selectedSceneObjects[0].rotation; // We don't average rotation in case of multi-selection
+                    rotation = selectedSceneObjects[0].Rotation; // We don't average rotation in case of multi-selection
 
                 Vector3 position;
                 if (EditorApplication.HandlePositionMode == HandlePositionMode.Pivot)
-                    position = selectedSceneObjects[0].position; // Just take pivot from the first one, no averaging
+                    position = selectedSceneObjects[0].Position; // Just take pivot from the first one, no averaging
                 else
                 {
                     List<SceneObject> flatenedHierarchy = new List<SceneObject>();
@@ -91,7 +91,7 @@ namespace BansheeEditor
                             MoveHandle moveHandle = (MoveHandle)activeHandle;
 
                             foreach (var so in selectedSceneObjects)
-                                so.position += moveHandle.Delta;
+                                so.Position += moveHandle.Delta;
                         }
 
                         break;

+ 143 - 8
MBansheeEngine/SceneObject.cs

@@ -3,16 +3,15 @@ using System.Runtime.CompilerServices;
 
 namespace BansheeEngine
 {
-    // TODO - Unfinished
     public sealed class SceneObject : GameObject
     {
-        public SceneObject parent
+        public SceneObject Parent
         {
             set { Internal_SetParent(mCachedPtr, value); }
             get { return Internal_GetParent(mCachedPtr); }
         }
 
-        public Vector3 position
+        public Vector3 Position
         {
             get
             {
@@ -27,7 +26,7 @@ namespace BansheeEngine
             }
         }
 
-        public Vector3 localPosition
+        public Vector3 LocalPosition
         {
             get
             {
@@ -42,7 +41,7 @@ namespace BansheeEngine
             }
         }
 
-        public Quaternion rotation
+        public Quaternion Rotation
         {
             get
             {
@@ -57,7 +56,7 @@ namespace BansheeEngine
             }
         }
 
-        public Quaternion localRotation
+        public Quaternion LocalRotation
         {
             get
             {
@@ -72,7 +71,7 @@ namespace BansheeEngine
             }
         }
 
-        public Vector3 scale
+        public Vector3 Scale
         {
             get
             {
@@ -82,7 +81,7 @@ namespace BansheeEngine
             }
         }
 
-        public Vector3 localScale
+        public Vector3 LocalScale
         {
             get
             {
@@ -97,6 +96,60 @@ namespace BansheeEngine
             }
         }
 
+        public Matrix4 WorldTransform
+        {
+            get
+            {
+                Matrix4 value;
+                Internal_GetWorldTransform(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Matrix4 LocalTransform
+        {
+            get
+            {
+                Matrix4 value;
+                Internal_GetLocalTransform(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 Forward
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetForward(mCachedPtr, out value);
+                return value;
+            }
+            set
+            {
+                Internal_SetForward(mCachedPtr, value);
+            }
+        }
+
+        public Vector3 Right
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetRight(mCachedPtr, out value);
+                return value;
+            }
+        }
+
+        public Vector3 Up
+        {
+            get
+            {
+                Vector3 value;
+                Internal_GetUp(mCachedPtr, out value);
+                return value;
+            }
+        }
+
         // For internal use
         private SceneObject()
         {
@@ -138,6 +191,46 @@ namespace BansheeEngine
             return Internal_GetChild(mCachedPtr, idx);
         }
 
+        public void LookAt(Vector3 direction, Vector3 up)
+        {
+            Internal_LookAt(mCachedPtr, direction, up);
+        }
+
+        public void Move(Vector3 amount)
+        {
+            Internal_Move(mCachedPtr, amount);
+        }
+
+        public void MoveLocal(Vector3 amount)
+        {
+            Internal_MoveLocal(mCachedPtr, amount);
+        }
+
+        public void Rotate(Quaternion amount)
+        {
+            Internal_Rotate(mCachedPtr, amount);
+        }
+
+        public void Roll(Degree angle)
+        {
+            Internal_Roll(mCachedPtr, angle);
+        }
+
+        public void Yaw(Degree angle)
+        {
+            Internal_Yaw(mCachedPtr, angle);
+        }
+
+        public void Pitch(Degree angle)
+        {
+            Internal_Pitch(mCachedPtr, angle);
+        }
+
+        public void Destroy(bool immediate = false)
+        {
+            Internal_Destroy(mCachedPtr, immediate);
+        }
+
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_CreateInstance(SceneObject instance, string name);
 
@@ -185,5 +278,47 @@ namespace BansheeEngine
 
         [MethodImpl(MethodImplOptions.InternalCall)]
         private static extern void Internal_SetLocalScale(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetLocalTransform(IntPtr nativeInstance, out Matrix4 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetWorldTransform(IntPtr nativeInstance, out Matrix4 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_LookAt(IntPtr nativeInstance, Vector3 direction, Vector3 up);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Move(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_MoveLocal(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Rotate(IntPtr nativeInstance, Quaternion value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Roll(IntPtr nativeInstance, Radian value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Yaw(IntPtr nativeInstance, Radian value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Pitch(IntPtr nativeInstance, Radian value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_SetForward(IntPtr nativeInstance, Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetForward(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetUp(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_GetRight(IntPtr nativeInstance, out Vector3 value);
+
+        [MethodImpl(MethodImplOptions.InternalCall)]
+        private static extern void Internal_Destroy(IntPtr nativeInstance, bool immediate);
     }
 }

+ 2 - 0
SBansheeEngine/Include/BsScriptComponent.h

@@ -24,6 +24,8 @@ namespace BansheeEngine
 		static void internal_removeComponent(MonoObject* parentSceneObject, MonoReflectionType* type);
 		static MonoObject* internal_getSceneObject(ScriptComponent* nativeInstance);
 
+		static bool checkIfDestroyed(const GameObjectHandleBase& handle);
+
 		ScriptComponent(MonoObject* instance, const GameObjectHandle<ManagedComponent>& managedComponent);
 		~ScriptComponent() {}
 

+ 17 - 0
SBansheeEngine/Include/BsScriptSceneObject.h

@@ -39,6 +39,23 @@ namespace BansheeEngine
 		static void internal_setLocalRotation(ScriptSceneObject* nativeInstance, Quaternion value);
 		static void internal_setLocalScale(ScriptSceneObject* nativeInstance, Vector3 value);
 
+		static void internal_getLocalTransform(ScriptSceneObject* nativeInstance, Matrix4* value);
+		static void internal_getWorldTransform(ScriptSceneObject* nativeInstance, Matrix4* value);
+		static void internal_lookAt(ScriptSceneObject* nativeInstance, Vector3 direction, Vector3 up);
+		static void internal_move(ScriptSceneObject* nativeInstance, Vector3 value);
+		static void internal_moveLocal(ScriptSceneObject* nativeInstance, Vector3 value);
+		static void internal_rotate(ScriptSceneObject* nativeInstance, Quaternion value);
+		static void internal_roll(ScriptSceneObject* nativeInstance, Radian value);
+		static void internal_yaw(ScriptSceneObject* nativeInstance, Radian value);
+		static void internal_pitch(ScriptSceneObject* nativeInstance, Radian value);
+		static void internal_setForward(ScriptSceneObject* nativeInstance, Vector3 value);
+		static void internal_getForward(ScriptSceneObject* nativeInstance, Vector3* value);
+		static void internal_getUp(ScriptSceneObject* nativeInstance, Vector3* value);
+		static void internal_getRight(ScriptSceneObject* nativeInstance, Vector3* value);
+
+		static void internal_destroy(ScriptSceneObject* nativeInstance, bool immediate);
+		static bool checkIfDestroyed(ScriptSceneObject* nativeInstance);
+
 		ScriptSceneObject(MonoObject* instance, const HSceneObject& sceneObject);
 
 		void _onManagedInstanceDeleted();

+ 31 - 5
SBansheeEngine/Source/BsScriptComponent.cpp

@@ -30,6 +30,9 @@ namespace BansheeEngine
 		ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(parentSceneObject);
 		HSceneObject so = static_object_cast<SceneObject>(scriptSO->getNativeHandle());
 
+		if (checkIfDestroyed(so))
+			return nullptr;
+
 		// We only allow single component per type
 		const Vector<HComponent>& mComponents = so->getComponents();
 		for(auto& component : mComponents)
@@ -57,6 +60,9 @@ namespace BansheeEngine
 		ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(parentSceneObject);
 		HSceneObject so = static_object_cast<SceneObject>(scriptSO->getNativeHandle());
 
+		if (checkIfDestroyed(so))
+			return nullptr;
+
 		const Vector<HComponent>& mComponents = so->getComponents();
 		for(auto& component : mComponents)
 		{
@@ -79,16 +85,19 @@ namespace BansheeEngine
 		ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(parentSceneObject);
 		HSceneObject so = static_object_cast<SceneObject>(scriptSO->getNativeHandle());
 
-		const Vector<HComponent>& mComponents = so->getComponents();
 		Vector<MonoObject*> managedComponents;
 
-		for(auto& component : mComponents)
+		if (!checkIfDestroyed(so))
 		{
-			if(component->getTypeId() == TID_ManagedComponent)
+			const Vector<HComponent>& mComponents = so->getComponents();
+			for (auto& component : mComponents)
 			{
-				GameObjectHandle<ManagedComponent> managedComponent = static_object_cast<ManagedComponent>(component);
+				if (component->getTypeId() == TID_ManagedComponent)
+				{
+					GameObjectHandle<ManagedComponent> managedComponent = static_object_cast<ManagedComponent>(component);
 
-				managedComponents.push_back(managedComponent->getManagedInstance());
+					managedComponents.push_back(managedComponent->getManagedInstance());
+				}
 			}
 		}
 
@@ -109,6 +118,9 @@ namespace BansheeEngine
 		ScriptSceneObject* scriptSO = ScriptSceneObject::toNative(parentSceneObject);
 		HSceneObject so = static_object_cast<SceneObject>(scriptSO->getNativeHandle());
 
+		if (checkIfDestroyed(so))
+			return;
+
 		// We only allow single component per type
 		const Vector<HComponent>& mComponents = so->getComponents();
 		for(auto& component : mComponents)
@@ -130,6 +142,9 @@ namespace BansheeEngine
 
 	MonoObject* ScriptComponent::internal_getSceneObject(ScriptComponent* nativeInstance)
 	{
+		if (checkIfDestroyed(nativeInstance->mManagedComponent))
+			return nullptr;
+
 		HSceneObject sceneObject = nativeInstance->mManagedComponent->sceneObject();
 
 		ScriptSceneObject* scriptSO = ScriptGameObjectManager::instance().getScriptSceneObject(sceneObject);
@@ -139,6 +154,17 @@ namespace BansheeEngine
 		return scriptSO->getManagedInstance();
 	}
 
+	bool ScriptComponent::checkIfDestroyed(const GameObjectHandleBase& handle)
+	{
+		if (handle.isDestroyed())
+		{
+			LOGWRN("Trying to access a destroyed GameObject with instance ID: " + handle.getInstanceId());
+			return true;
+		}
+
+		return false;
+	}
+
 	void ScriptComponent::_onManagedInstanceDeleted()
 	{
 		mManagedInstance = nullptr;

+ 167 - 12
SBansheeEngine/Source/BsScriptSceneObject.cpp

@@ -35,6 +35,22 @@ namespace BansheeEngine
 		metaData.scriptClass->addInternalCall("Internal_SetRotation", &ScriptSceneObject::internal_setRotation);
 		metaData.scriptClass->addInternalCall("Internal_SetLocalRotation", &ScriptSceneObject::internal_setLocalRotation);
 		metaData.scriptClass->addInternalCall("Internal_SetLocalScale", &ScriptSceneObject::internal_setLocalScale);
+
+		metaData.scriptClass->addInternalCall("Internal_GetLocalTransform", &ScriptSceneObject::internal_getLocalTransform);
+		metaData.scriptClass->addInternalCall("Internal_GetWorldTransform", &ScriptSceneObject::internal_getWorldTransform);
+		metaData.scriptClass->addInternalCall("Internal_LookAt", &ScriptSceneObject::internal_lookAt);
+		metaData.scriptClass->addInternalCall("Internal_Move", &ScriptSceneObject::internal_move);
+		metaData.scriptClass->addInternalCall("Internal_MoveLocal", &ScriptSceneObject::internal_moveLocal);
+		metaData.scriptClass->addInternalCall("Internal_Rotate", &ScriptSceneObject::internal_rotate);
+		metaData.scriptClass->addInternalCall("Internal_Roll", &ScriptSceneObject::internal_roll);
+		metaData.scriptClass->addInternalCall("Internal_Yaw", &ScriptSceneObject::internal_yaw);
+		metaData.scriptClass->addInternalCall("Internal_Pitch", &ScriptSceneObject::internal_pitch);
+		metaData.scriptClass->addInternalCall("Internal_SetForward", &ScriptSceneObject::internal_setForward);
+		metaData.scriptClass->addInternalCall("Internal_GetForward", &ScriptSceneObject::internal_getForward);
+		metaData.scriptClass->addInternalCall("Internal_GetUp", &ScriptSceneObject::internal_getUp);
+		metaData.scriptClass->addInternalCall("Internal_GetRight", &ScriptSceneObject::internal_getRight);
+
+		metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptSceneObject::internal_destroy);
 	}
 
 	void ScriptSceneObject::internal_createInstance(MonoObject* instance, MonoString* name)
@@ -46,6 +62,9 @@ namespace BansheeEngine
 
 	void ScriptSceneObject::internal_setParent(ScriptSceneObject* nativeInstance, MonoObject* parent)
 	{
+		if (checkIfDestroyed(nativeInstance))
+			return;
+
 		ScriptSceneObject* parentScriptSO = ScriptSceneObject::toNative(parent);
 
 		nativeInstance->mSceneObject->setParent(parentScriptSO->mSceneObject);
@@ -53,6 +72,9 @@ namespace BansheeEngine
 
 	MonoObject* ScriptSceneObject::internal_getParent(ScriptSceneObject* nativeInstance)
 	{
+		if (checkIfDestroyed(nativeInstance))
+			return nullptr;
+
 		HSceneObject parent = nativeInstance->mSceneObject->getParent();
 
 		ScriptSceneObject* parentScriptSO = ScriptGameObjectManager::instance().getScriptSceneObject(parent);
@@ -64,11 +86,17 @@ namespace BansheeEngine
 
 	UINT32 ScriptSceneObject::internal_getNumChildren(ScriptSceneObject* nativeInstance)
 	{
-		return nativeInstance->mSceneObject->getNumChildren();
+		if (!checkIfDestroyed(nativeInstance))
+			return nativeInstance->mSceneObject->getNumChildren();
+		else
+			return 0;
 	}
 
 	MonoObject* ScriptSceneObject::internal_getChild(ScriptSceneObject* nativeInstance, UINT32 idx)
 	{
+		if (checkIfDestroyed(nativeInstance))
+			return nullptr;
+
 		UINT32 numChildren = nativeInstance->mSceneObject->getNumChildren();
 		if(idx >= numChildren)
 		{
@@ -87,57 +115,184 @@ namespace BansheeEngine
 
 	void ScriptSceneObject::internal_getPosition(ScriptSceneObject* nativeInstance, Vector3* value)
 	{
-		*value = nativeInstance->mSceneObject->getWorldPosition();
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getWorldPosition();
+		else
+			*value = Vector3();
 	}
 
 	void ScriptSceneObject::internal_getLocalPosition(ScriptSceneObject* nativeInstance, Vector3* value)
 	{
-		*value = nativeInstance->mSceneObject->getPosition();
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getPosition();
+		else
+			*value = Vector3();
 	}
 
 	void ScriptSceneObject::internal_getRotation(ScriptSceneObject* nativeInstance, Quaternion* value)
 	{
-		*value = nativeInstance->mSceneObject->getWorldRotation();
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getWorldRotation();
+		else
+			*value = Quaternion();
 	}
 
 	void ScriptSceneObject::internal_getLocalRotation(ScriptSceneObject* nativeInstance, Quaternion* value)
 	{
-		*value = nativeInstance->mSceneObject->getRotation();
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getRotation();
+		else
+			*value = Quaternion();
 	}
 
 	void ScriptSceneObject::internal_getScale(ScriptSceneObject* nativeInstance, Vector3* value)
 	{
-		*value = nativeInstance->mSceneObject->getWorldScale();
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getWorldScale();
+		else
+			*value = Vector3();
 	}
 
 	void ScriptSceneObject::internal_getLocalScale(ScriptSceneObject* nativeInstance, Vector3* value)
 	{
-		*value = nativeInstance->mSceneObject->getWorldScale();
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getWorldScale();
+		else
+			*value = Vector3();
 	}
 
 	void ScriptSceneObject::internal_setPosition(ScriptSceneObject* nativeInstance, Vector3 value)
 	{
-		nativeInstance->mSceneObject->setWorldPosition(value);
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->setWorldPosition(value);
 	}
 
 	void ScriptSceneObject::internal_setLocalPosition(ScriptSceneObject* nativeInstance, Vector3 value)
 	{
-		nativeInstance->mSceneObject->setPosition(value);
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->setPosition(value);
 	}
 
 	void ScriptSceneObject::internal_setRotation(ScriptSceneObject* nativeInstance, Quaternion value)
 	{
-		nativeInstance->mSceneObject->setWorldRotation(value);
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->setWorldRotation(value);
 	}
 
 	void ScriptSceneObject::internal_setLocalRotation(ScriptSceneObject* nativeInstance, Quaternion value)
 	{
-		nativeInstance->mSceneObject->setRotation(value);
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->setRotation(value);
 	}
 
 	void ScriptSceneObject::internal_setLocalScale(ScriptSceneObject* nativeInstance, Vector3 value)
 	{
-		nativeInstance->mSceneObject->setScale(value);
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->setScale(value);
+	}
+
+	void ScriptSceneObject::internal_getLocalTransform(ScriptSceneObject* nativeInstance, Matrix4* value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getLocalTfrm();
+		else
+			*value = Matrix4();
+	}
+
+	void ScriptSceneObject::internal_getWorldTransform(ScriptSceneObject* nativeInstance, Matrix4* value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getWorldTfrm();
+		else
+			*value = Matrix4();
+	}
+
+	void ScriptSceneObject::internal_lookAt(ScriptSceneObject* nativeInstance, Vector3 direction, Vector3 up)
+	{
+
+	}
+
+	void ScriptSceneObject::internal_move(ScriptSceneObject* nativeInstance, Vector3 value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->move(value);
+	}
+
+	void ScriptSceneObject::internal_moveLocal(ScriptSceneObject* nativeInstance, Vector3 value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->moveRelative(value);
+	}
+
+	void ScriptSceneObject::internal_rotate(ScriptSceneObject* nativeInstance, Quaternion value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->rotate(value);
+	}
+
+	void ScriptSceneObject::internal_roll(ScriptSceneObject* nativeInstance, Radian value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->roll(value);
+	}
+
+	void ScriptSceneObject::internal_yaw(ScriptSceneObject* nativeInstance, Radian value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->yaw(value);
+	}
+
+	void ScriptSceneObject::internal_pitch(ScriptSceneObject* nativeInstance, Radian value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->pitch(value);
+	}
+
+	void ScriptSceneObject::internal_setForward(ScriptSceneObject* nativeInstance, Vector3 value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->setForward(value);
+	}
+
+	void ScriptSceneObject::internal_getForward(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getForward();
+		else
+			*value = Vector3();
+	}
+
+	void ScriptSceneObject::internal_getUp(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getUp();
+		else
+			*value = Vector3();
+	}
+
+	void ScriptSceneObject::internal_getRight(ScriptSceneObject* nativeInstance, Vector3* value)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			*value = nativeInstance->mSceneObject->getRight();
+		else
+			*value = Vector3();
+	}
+
+	void ScriptSceneObject::internal_destroy(ScriptSceneObject* nativeInstance, bool immediate)
+	{
+		if (!checkIfDestroyed(nativeInstance))
+			nativeInstance->mSceneObject->destroy(immediate);
+	}
+
+	bool ScriptSceneObject::checkIfDestroyed(ScriptSceneObject* nativeInstance)
+	{
+		if (nativeInstance->mSceneObject.isDestroyed())
+		{
+			LOGWRN("Trying to access a destroyed SceneObject with instance ID: " + nativeInstance->mSceneObject.getInstanceId());
+			return true;
+		}
+
+		return false;
 	}
 
 	void ScriptSceneObject::_onManagedInstanceDeleted()

+ 0 - 4
SceneView.txt

@@ -2,10 +2,6 @@
  GIZMO TODO:
   - Make a C# wrapper for Renderable
 
-Need to defer destruction of Components until all component updates have finished. Otherwise I risk destroying a component referenced by some
-other script since the order to Update() methods isn't clearly defined.
- - Add [ExecPriority] attribute for Update() method
- - Make sure Component update is called
  - Do I handle it gracefully if user tries to access destroyed component or scene object?
   - I don't, at least not with SceneObject. I will try to access HSceneObject handle even if its
     destroyed. Add a check.