Explorar el Código

Added Character controller component wrapper

BearishSun hace 9 años
padre
commit
a974ea6735

+ 3 - 0
BansheeCore/BansheeCore.vcxproj

@@ -302,6 +302,7 @@
     <ClInclude Include="Include\BsCBoxCollider.h" />
     <ClInclude Include="Include\BsCCapsuleCollider.h" />
     <ClInclude Include="Include\BsCCapsuleColliderRTTI.h" />
+    <ClInclude Include="Include\BsCCharacterController.h" />
     <ClInclude Include="Include\BsCCollider.h" />
     <ClInclude Include="Include\BsCColliderRTTI.h" />
     <ClInclude Include="Include\BsCD6Joint.h" />
@@ -310,6 +311,7 @@
     <ClInclude Include="Include\BsCDistanceJointRTTI.h" />
     <ClInclude Include="Include\BsCFixedJointRTTI.h" />
     <ClInclude Include="Include\BsCharacterController.h" />
+    <ClInclude Include="Include\BsCCharacterControllerRTTI.h" />
     <ClInclude Include="Include\BsCHingeJoint.h" />
     <ClInclude Include="Include\BsCHingeJointRTTI.h" />
     <ClInclude Include="Include\BsCJointRTTI.h" />
@@ -516,6 +518,7 @@
     <ClCompile Include="Source\BsCapsuleCollider.cpp" />
     <ClCompile Include="Source\BsCBoxCollider.cpp" />
     <ClCompile Include="Source\BsCCapsuleCollider.cpp" />
+    <ClCompile Include="Source\BsCCharacterController.cpp" />
     <ClCompile Include="Source\BsCCollider.cpp" />
     <ClCompile Include="Source\BsCD6Joint.cpp" />
     <ClCompile Include="Source\BsCDistanceJoint.cpp" />

+ 9 - 0
BansheeCore/BansheeCore.vcxproj.filters

@@ -749,6 +749,12 @@
     <ClInclude Include="Include\BsCharacterController.h">
       <Filter>Header Files\Physics</Filter>
     </ClInclude>
+    <ClInclude Include="Include\BsCCharacterController.h">
+      <Filter>Header Files\Components</Filter>
+    </ClInclude>
+    <ClInclude Include="Include\BsCCharacterControllerRTTI.h">
+      <Filter>Header Files\RTTI</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Source\BsCoreApplication.cpp">
@@ -1186,5 +1192,8 @@
     <ClCompile Include="Source\BsCharacterController.cpp">
       <Filter>Source Files\Physics</Filter>
     </ClCompile>
+    <ClCompile Include="Source\BsCCharacterController.cpp">
+      <Filter>Source Files\Components</Filter>
+    </ClCompile>
   </ItemGroup>
 </Project>

+ 4 - 0
BansheeCore/Include/BsCBoxCollider.h

@@ -34,9 +34,13 @@ namespace BansheeEngine
 		/** Gets the position of the box shape, relative to the component's scene object. */
 		Vector3 getCenter() const { return mLocalPosition; }
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the box collider that this component wraps. */
 		SPtr<BoxCollider> _getInternal() const { return std::static_pointer_cast<BoxCollider>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCCapsuleCollider.h

@@ -46,9 +46,13 @@ namespace BansheeEngine
 		/** @copydoc CapsuleCollider::getRadius() */
 		float getRadius() const { return mRadius; }
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the capsule collider that this component wraps. */
 		SPtr<CapsuleCollider> _getInternal() const { return std::static_pointer_cast<CapsuleCollider>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 158 - 0
BansheeCore/Include/BsCCharacterController.h

@@ -0,0 +1,158 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsCharacterController.h"
+#include "BsComponent.h"
+
+namespace BansheeEngine 
+{
+	/** @addtogroup Components-Core
+	 *  @{
+	 */
+
+	/**
+	 * @copydoc	CharacterController
+	 *
+	 * Wraps CharacterController as a Component.
+	 */
+    class BS_CORE_EXPORT CCharacterController : public Component
+    {
+    public:
+		CCharacterController(const HSceneObject& parent);
+
+		/** @copydoc CharacterController::move */
+		inline CharacterCollisionFlags move(const Vector3& displacement);
+
+		/** @copydoc CharacterController::getFootPosition */
+		inline Vector3 getFootPosition() const;
+
+		/** @copydoc CharacterController::setFootPosition */
+		inline void setFootPosition(const Vector3& position);
+
+		/** @copydoc CharacterController::getRadius */
+		float getRadius() const { return mDesc.radius; }
+
+		/** @copydoc CharacterController::setRadius */
+		inline void setRadius(float radius);
+
+		/** @copydoc CharacterController::getHeight */
+		float getHeight() const { return mDesc.height; }
+
+		/** @copydoc CharacterController::setHeight */
+		inline void setHeight(float height);
+
+		/** @copydoc CharacterController::getUp */
+		Vector3 getUp() const { return mDesc.up; }
+
+		/** @copydoc CharacterController::setUp */
+		inline void setUp(const Vector3& up);
+
+		/** @copydoc CharacterController::getClimbingMode */
+		CharacterClimbingMode getClimbingMode() const { return mDesc.climbingMode; }
+
+		/** @copydoc CharacterController::setClimbingMode */
+		inline void setClimbingMode(CharacterClimbingMode mode);
+
+		/** @copydoc CharacterController::getNonWalkableMode */
+		CharacterNonWalkableMode getNonWalkableMode() const { return mDesc.nonWalkableMode; }
+
+		/** @copydoc CharacterController::setNonWalkableMode */
+		inline void setNonWalkableMode(CharacterNonWalkableMode mode);
+
+		/** @copydoc CharacterController::getMinMoveDistance */
+		float getMinMoveDistance() const { return mDesc.minMoveDistance; }
+
+		/** @copydoc CharacterController::setMinMoveDistance */
+		inline void setMinMoveDistance(float value);
+
+		/** @copydoc CharacterController::getContactOffset */
+		float getContactOffset() const { return mDesc.contactOffset; }
+
+		/** @copydoc CharacterController::setContactOffset */
+		inline void setContactOffset(float value);
+
+		/** @copydoc CharacterController::getStepOffset */
+		inline float getStepOffset() const { return mDesc.stepOffset; }
+
+		/** @copydoc CharacterController::setStepOffset */
+		inline void setStepOffset(float value);
+
+		/** @copydoc CharacterController::getSlopeLimit */
+		Radian getSlopeLimit() const { return mDesc.slopeLimit; }
+
+		/** @copydoc CharacterController::setSlopeLimit */
+		inline void setSlopeLimit(Radian value);
+
+		/** @copydoc CharacterController::getLayer */
+		UINT64 getLayer() const { return mLayer; }
+
+		/** @copydoc CharacterController::setLayer */
+		inline void setLayer(UINT64 layer);
+
+		/** @copydoc CharacterController::onColliderHit */
+		Event<void(const ControllerColliderCollision&)> onColliderHit;
+
+		/** @copydoc CharacterController::onControllerHit */
+		Event<void(const ControllerControllerCollision&)> onControllerHit;
+
+		/** @cond INTERNAL */
+
+	    /**	Returns the character controller that this component wraps. */
+		SPtr<CharacterController> _getInternal() const { return std::static_pointer_cast<CharacterController>(mInternal); }
+
+		/** @endcond */
+
+		/************************************************************************/
+		/* 						COMPONENT OVERRIDES                      		*/
+		/************************************************************************/
+	protected:
+		friend class SceneObject;
+
+		/** @copydoc Component::onInitialized() */
+		void onInitialized() override;
+
+		/** @copydoc Component::onDestroyed() */
+		void onDestroyed() override;
+
+		/** @copydoc Component::onDisabled() */
+		void onDisabled() override;
+
+		/** @copydoc Component::onEnabled() */
+		void onEnabled() override;
+
+		/** @copydoc Component::onTransformChanged() */
+		void onTransformChanged(TransformChangedFlags flags) override;
+
+    protected:
+		/** Updates the position by copying it from the controller to the component's scene object. */
+		void updatePositionFromController();
+
+		/** Updates the dimensions of the controller by taking account scale of the parent scene object. */
+		void updateDimensions();
+
+		/** Triggered when the internal controller hits a collider. */
+		void triggerOnColliderHit(const ControllerColliderCollision& value);
+
+		/** Triggered when the internal controller hits another controller. */
+		void triggerOnControllerHit(const ControllerControllerCollision& value);
+
+		SPtr<CharacterController> mInternal;
+		CHAR_CONTROLLER_DESC mDesc;
+		UINT64 mLayer = 1;
+
+		/************************************************************************/
+		/* 								RTTI		                     		*/
+		/************************************************************************/
+	public:
+		friend class CCharacterControllerRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+	protected:
+		CCharacterController() {} // Serialization only
+     };
+
+	 /** @} */
+}

+ 67 - 0
BansheeCore/Include/BsCCharacterControllerRTTI.h

@@ -0,0 +1,67 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsCCharacterController.h"
+#include "BsGameObjectRTTI.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT CCharacterControllerRTTI : public RTTIType<CCharacterController, Component, CCharacterControllerRTTI>
+	{
+	private:
+		BS_PLAIN_MEMBER_NAMED(mPosition, mDesc.position)
+		BS_PLAIN_MEMBER_NAMED(mContactOffset, mDesc.contactOffset)
+		BS_PLAIN_MEMBER_NAMED(mStepOffset, mDesc.stepOffset)
+		BS_PLAIN_MEMBER_NAMED(mSlopeLimit, mDesc.slopeLimit)
+		BS_PLAIN_MEMBER_NAMED(mMinMoveDistance, mDesc.minMoveDistance)
+		BS_PLAIN_MEMBER_NAMED(mHeight, mDesc.height)
+		BS_PLAIN_MEMBER_NAMED(mRadius, mDesc.radius)
+		BS_PLAIN_MEMBER_NAMED(mUp, mDesc.up)
+		BS_PLAIN_MEMBER_NAMED(mClimbingMode, mDesc.climbingMode)
+		BS_PLAIN_MEMBER_NAMED(mNonWalkableMode, mDesc.nonWalkableMode)
+		BS_PLAIN_MEMBER(mLayer)
+
+	public:
+		CCharacterControllerRTTI()
+		{
+			BS_ADD_PLAIN_FIELD(mPosition, 0);
+			BS_ADD_PLAIN_FIELD(mContactOffset, 1);
+			BS_ADD_PLAIN_FIELD(mStepOffset, 2);
+			BS_ADD_PLAIN_FIELD(mSlopeLimit, 3);
+			BS_ADD_PLAIN_FIELD(mMinMoveDistance, 4);
+			BS_ADD_PLAIN_FIELD(mHeight, 5);
+			BS_ADD_PLAIN_FIELD(mRadius, 6);
+			BS_ADD_PLAIN_FIELD(mUp, 7);
+			BS_ADD_PLAIN_FIELD(mClimbingMode, 8);
+			BS_ADD_PLAIN_FIELD(mNonWalkableMode, 9);
+			BS_ADD_PLAIN_FIELD(mLayer, 10);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "CCharacterController";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_CCharacterController;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return GameObjectRTTI::createGameObject<CCharacterController>();
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 1 - 0
BansheeCore/Include/BsCCollider.h

@@ -21,6 +21,7 @@ namespace BansheeEngine
     {
     public:
 		CCollider(const HSceneObject& parent);
+		virtual ~CCollider() {}
 
 		/** @copydoc Collider::setIsTrigger */
 		inline void setIsTrigger(bool value);

+ 4 - 0
BansheeCore/Include/BsCD6Joint.h

@@ -79,9 +79,13 @@ namespace BansheeEngine
 		/** @copydoc D6Joint::setDriveVelocity */
 		inline void setDriveVelocity(const Vector3& linear, const Vector3& angular);
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the D6 joint that this component wraps. */
 		SPtr<D6Joint> _getInternal() const { return std::static_pointer_cast<D6Joint>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCDistanceJoint.h

@@ -55,9 +55,13 @@ namespace BansheeEngine
 		/** @copydoc DistanceJoint::hasFlag */
 		inline bool hasFlag(DistanceJoint::Flag flag) const;
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the distance joint that this component wraps. */
 		SPtr<DistanceJoint> _getInternal() const { return std::static_pointer_cast<DistanceJoint>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCFixedJoint.h

@@ -22,9 +22,13 @@ namespace BansheeEngine
     public:
 		CFixedJoint(const HSceneObject& parent);
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the fixed joint that this component wraps. */
 		SPtr<FixedJoint> _getInternal() const { return std::static_pointer_cast<FixedJoint>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCHingeJoint.h

@@ -46,9 +46,13 @@ namespace BansheeEngine
 		/** @copydoc HingeJoint::hasFlag */
 		inline bool hasFlag(HingeJoint::Flag flag) const;
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the hinge joint that this component wraps. */
 		SPtr<HingeJoint> _getInternal() const { return std::static_pointer_cast<HingeJoint>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 2 - 1
BansheeCore/Include/BsCJoint.h

@@ -21,7 +21,8 @@ namespace BansheeEngine
     {
     public:
 		CJoint(const HSceneObject& parent);
-		
+		virtual ~CJoint() {}
+
 		/** @copydoc Joint::getBody */
 		inline HRigidbody getBody(JointBody body) const;
 

+ 4 - 0
BansheeCore/Include/BsCMeshCollider.h

@@ -28,9 +28,13 @@ namespace BansheeEngine
 		/** @copydoc MeshCollider::getMesh */
 		HPhysicsMesh getMesh() const { return mMesh; }
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the mesh collider that this component wraps. */
 		SPtr<MeshCollider> _getInternal() const { return std::static_pointer_cast<MeshCollider>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCPlaneCollider.h

@@ -34,9 +34,13 @@ namespace BansheeEngine
 		/** Gets the distance of the plane from the local origin, along its normal vector. */
 		float getDistance() const { return mDistance; }
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the plane collider that this component wraps. */
 		SPtr<PlaneCollider> _getInternal() const { return std::static_pointer_cast<PlaneCollider>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCSliderJoint.h

@@ -40,9 +40,13 @@ namespace BansheeEngine
 		/** @copydoc SliderJoint::hasFlag */
 		inline bool hasFlag(SliderJoint::Flag flag) const;
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the slider joint that this component wraps. */
 		SPtr<SliderJoint> _getInternal() const { return std::static_pointer_cast<SliderJoint>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCSphereCollider.h

@@ -34,9 +34,13 @@ namespace BansheeEngine
 		/** Gets the position of the sphere shape, relative to the component's scene object. */
 		Vector3 getCenter() const { return mLocalPosition; }
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the sphere collider that this component wraps. */
 		SPtr<SphereCollider> _getInternal() const { return std::static_pointer_cast<SphereCollider>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 0
BansheeCore/Include/BsCSphericalJoint.h

@@ -34,9 +34,13 @@ namespace BansheeEngine
 		/** @copydoc SphericalJoint::hasFlag */
 		inline bool hasFlag(SphericalJoint::Flag flag) const;
 
+		/** @cond INTERNAL */
+
 	    /**	Returns the spherical joint that this component wraps. */
 		SPtr<SphericalJoint> _getInternal() const { return std::static_pointer_cast<SphericalJoint>(mInternal); }
 
+		/** @endcond */
+
 		/************************************************************************/
 		/* 						COMPONENT OVERRIDES                      		*/
 		/************************************************************************/

+ 4 - 4
BansheeCore/Include/BsCharacterController.h

@@ -133,7 +133,7 @@ namespace BansheeEngine
 		 *
 		 * @copydoc	CHAR_CONTROLLER_DESC::minMoveDistance
 		 */
-		virtual float getMinMoveDistance() = 0;
+		virtual float getMinMoveDistance() const = 0;
 
 		/** 
 		 * Sets minimum move distance.
@@ -147,7 +147,7 @@ namespace BansheeEngine
 		 *
 		 * @copydoc	CHAR_CONTROLLER_DESC::contactOffset
 		 */
-		virtual float getContactOffset() = 0;
+		virtual float getContactOffset() const = 0;
 
 		/** 
 		 * Sets the contact offset.
@@ -161,7 +161,7 @@ namespace BansheeEngine
 		 *
 		 * @copydoc	CHAR_CONTROLLER_DESC::stepOffset
 		 */
-		virtual float getStepOffset() = 0;
+		virtual float getStepOffset() const = 0;
 
 		/** 
 		 * Sets the step offset.
@@ -175,7 +175,7 @@ namespace BansheeEngine
 		 *
 		 * @copydoc	CHAR_CONTROLLER_DESC::slopeLimit
 		 */
-		virtual Radian getSlopeLimit() = 0;
+		virtual Radian getSlopeLimit() const = 0;
 
 		/**
 		 * Sets the slope angle.

+ 1 - 1
BansheeCore/Include/BsCommandQueue.h

@@ -135,7 +135,7 @@ namespace BansheeEngine
 		bool notifyWhenComplete;
 	};
 
-	/** Contains a list of commands you may queue for later execution on the core thread. */
+	/** Manages a list of commands that can be queued for later execution on the core thread. */
 	class BS_CORE_EXPORT CommandQueueBase
 	{
 	public:

+ 2 - 1
BansheeCore/Include/BsCorePrerequisites.h

@@ -453,7 +453,8 @@ namespace BansheeEngine
 		TID_CHingeJoint = 1104,
 		TID_CSphericalJoint = 1105,
 		TID_CSliderJoint = 1106,
-		TID_CD6Joint = 1107
+		TID_CD6Joint = 1107,
+		TID_CCharacterController = 1108
 	};
 }
 

+ 200 - 0
BansheeCore/Source/BsCCharacterController.cpp

@@ -0,0 +1,200 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#include "BsCCharacterController.h"
+#include "BsSceneObject.h"
+#include "BsCCharacterControllerRTTI.h"
+
+using namespace std::placeholders;
+
+namespace BansheeEngine
+{
+	CCharacterController::CCharacterController(const HSceneObject& parent)
+		: Component(parent)
+	{
+		setName("CharacterController");
+
+		mNotifyFlags = TCF_Transform;
+	}
+
+	CharacterCollisionFlags CCharacterController::move(const Vector3& displacement)
+	{
+		CharacterCollisionFlags output;
+
+		if (mInternal == nullptr)
+			return output;
+
+		output = mInternal->move(displacement);
+		updatePositionFromController();
+	}
+
+	Vector3 CCharacterController::getFootPosition() const
+	{
+		if (mInternal == nullptr)
+			return Vector3::ZERO;
+
+		return mInternal->getFootPosition();
+	}
+
+	void CCharacterController::setFootPosition(const Vector3& position)
+	{
+		if (mInternal == nullptr)
+			return;
+
+		mInternal->setFootPosition(position);
+		updatePositionFromController();
+	}
+
+	void CCharacterController::setRadius(float radius)
+	{
+		mDesc.radius = radius;
+
+		if (mInternal != nullptr)
+			updateDimensions();
+	}
+
+	void CCharacterController::setHeight(float height)
+	{
+		mDesc.height = height;
+
+		if (mInternal != nullptr)
+			updateDimensions();
+	}
+
+	void CCharacterController::setUp(const Vector3& up)
+	{
+		mDesc.up = up;
+
+		if (mInternal != nullptr)
+			mInternal->setUp(up);
+	}
+
+	void CCharacterController::setClimbingMode(CharacterClimbingMode mode)
+	{
+		mDesc.climbingMode = mode;
+
+		if (mInternal != nullptr)
+			mInternal->setClimbingMode(mode);
+	}
+
+	void CCharacterController::setNonWalkableMode(CharacterNonWalkableMode mode)
+	{
+		mDesc.nonWalkableMode = mode;
+
+		if (mInternal != nullptr)
+			mInternal->setNonWalkableMode(mode);
+	}
+
+	void CCharacterController::setMinMoveDistance(float value)
+	{
+		mDesc.minMoveDistance = value;
+
+		if (mInternal != nullptr)
+			mInternal->setMinMoveDistance(value);
+	}
+
+	void CCharacterController::setContactOffset(float value)
+	{
+		mDesc.contactOffset = value;
+
+		if (mInternal != nullptr)
+			mInternal->setContactOffset(value);
+	}
+
+	void CCharacterController::setStepOffset(float value)
+	{
+		mDesc.stepOffset = value;
+
+		if (mInternal != nullptr)
+			mInternal->setStepOffset(value);
+	}
+
+	void CCharacterController::setSlopeLimit(Radian value)
+	{
+		mDesc.slopeLimit = value;
+
+		if (mInternal != nullptr)
+			mInternal->setSlopeLimit(value);
+	}
+
+	void CCharacterController::setLayer(UINT64 layer)
+	{
+		mLayer = layer;
+
+		if (mInternal != nullptr)
+			mInternal->setLayer(layer);
+	}
+
+	void CCharacterController::onInitialized()
+	{
+
+	}
+
+	void CCharacterController::onDestroyed()
+	{
+		// This should release the last reference and destroy the internal controller
+		mInternal = nullptr;
+	}
+
+	void CCharacterController::onDisabled()
+	{
+		// This should release the last reference and destroy the internal controller
+		mInternal = nullptr;
+	}
+
+	void CCharacterController::onEnabled()
+	{
+		mDesc.position = SO()->getWorldPosition();
+		mInternal = CharacterController::create(mDesc);
+
+		mInternal->onColliderHit.connect(std::bind(&CCharacterController::triggerOnColliderHit, this, _1));
+		mInternal->onControllerHit.connect(std::bind(&CCharacterController::triggerOnControllerHit, this, _1));
+
+		mInternal->setLayer(mLayer);
+		updateDimensions();
+	}
+
+	void CCharacterController::onTransformChanged(TransformChangedFlags flags)
+	{
+		if (!SO()->getActive() || mInternal == nullptr)
+			return;
+
+		mInternal->setPosition(SO()->getWorldPosition());
+	}
+
+	void CCharacterController::updatePositionFromController()
+	{
+		mNotifyFlags = (TransformChangedFlags)0;
+		SO()->setWorldPosition(mInternal->getPosition());
+		mNotifyFlags = TCF_Transform;
+	}
+
+	void CCharacterController::updateDimensions()
+	{
+		Vector3 scale = SO()->getWorldScale();
+		float height = mDesc.height * Math::abs(scale.y);
+		float radius = mDesc.radius * Math::abs(std::max(scale.x, scale.z));
+
+		mInternal->setHeight(height);
+		mInternal->setRadius(radius);
+	}
+
+	void CCharacterController::triggerOnColliderHit(const ControllerColliderCollision& value)
+	{
+		onColliderHit(value);
+	}
+
+	void CCharacterController::triggerOnControllerHit(const ControllerControllerCollision& value)
+	{
+		onControllerHit(value);
+	}
+
+	RTTITypeBase* CCharacterController::getRTTIStatic()
+	{
+		return CCharacterControllerRTTI::instance();
+	}
+
+	RTTITypeBase* CCharacterController::getRTTI() const
+	{
+		return CCharacterController::getRTTIStatic();
+	}
+}

+ 4 - 4
BansheePhysX/Include/BsPhysXCharacterController.h

@@ -65,25 +65,25 @@ namespace BansheeEngine
 		void setNonWalkableMode(CharacterNonWalkableMode mode) override;
 
 		/** @copydoc CharacterController::getMinMoveDistance */
-		float getMinMoveDistance() override;
+		float getMinMoveDistance() const override;
 
 		/** @copydoc CharacterController::setMinMoveDistance */
 		void setMinMoveDistance(float value) override;
 
 		/** @copydoc CharacterController::getContactOffset */
-		float getContactOffset() override;
+		float getContactOffset() const override;
 
 		/** @copydoc CharacterController::setContactOffset */
 		void setContactOffset(float value) override;
 
 		/** @copydoc CharacterController::getStepOffset */
-		float getStepOffset() override;
+		float getStepOffset() const override;
 
 		/** @copydoc CharacterController::setStepOffset */
 		void setStepOffset(float value) override;
 
 		/** @copydoc CharacterController::getSlopeLimit */
-		Radian getSlopeLimit() override;
+		Radian getSlopeLimit() const override;
 
 		/** @copydoc CharacterController::setSlopeLimit */
 		void setSlopeLimit(Radian value) override;

+ 4 - 4
BansheePhysX/Source/BsPhysXCharacterController.cpp

@@ -174,7 +174,7 @@ namespace BansheeEngine
 		mController->setNonWalkableMode(toPxEnum(mode));
 	}
 
-	float PhysXCharacterController::getMinMoveDistance()
+	float PhysXCharacterController::getMinMoveDistance() const
 	{
 		return mMinMoveDistance;
 	}
@@ -184,7 +184,7 @@ namespace BansheeEngine
 		mMinMoveDistance = value;
 	}
 
-	float PhysXCharacterController::getContactOffset()
+	float PhysXCharacterController::getContactOffset() const
 	{
 		return mController->getContactOffset();
 	}
@@ -194,7 +194,7 @@ namespace BansheeEngine
 		mController->setContactOffset(value);
 	}
 
-	float PhysXCharacterController::getStepOffset()
+	float PhysXCharacterController::getStepOffset() const
 	{
 		return mController->getStepOffset();
 	}
@@ -204,7 +204,7 @@ namespace BansheeEngine
 		mController->setStepOffset(value);
 	}
 
-	Radian PhysXCharacterController::getSlopeLimit()
+	Radian PhysXCharacterController::getSlopeLimit() const
 	{
 		return Radian(mController->getSlopeLimit());
 	}