virtual void UpdateBehavior( float timeDelta )
	{
		// Always look for the closest possible target
		m_pApproachTarget = 0;
		if ( m_pBBIndividual->visible_rbc.Size() > 0 )
		{
			GetClosestApproachTarget();
		}

		m_pAvoidTarget = 0;
		if ( m_pBBIndividual->visible_wbc.Size() > 0 )
		{
			GetClosestAvoidTarget();
		}

		if (!m_pApproachTarget && !m_pAvoidTarget)
		{
			bool bBadHeading = m_pPhysics->IsHeadingToGameBounds( m_pBBCommon->current_position, m_pBBCommon->current_velocity );
			m_TimeToNextDirChange -= timeDelta;
			if ( bBadHeading || m_TimeToNextDirChange <= 0.0f )
			{
				m_TimeToNextDirChange = m_pBBIndividual->patrol_change_frequency;
				m_PatrolDir = AUVec3f((float)rand()/RAND_MAX - 0.5f, 0.0f, (float)rand()/RAND_MAX - 0.5f).GetNormalised();
			}
		}
	}
	void ConsumeRBC()
	{
		m_pBBCommon->current_health += m_pGlobalParameters->infected_health_gain_from_eating;
		if (m_pBBCommon->current_health >= m_pGlobalParameters->infected_max_health)
		{
			// Passed max health, so explode and convert into several viruses
			m_pGameManager->DestroyGameObject( m_pOwner->GetObjectId() );

			float radius = m_pOwner->GetCollisionRadius() * 0.7f;
			int count = m_pGlobalParameters->infected_num_viruses_on_explode;
			for (int i=0; i<count; ++i)
			{
				AUVec3f pos = m_pBBCommon->current_position + AUVec3f(
					radius * (float)cos( M_PI * 2 * i / count ),
					0.0f,
					radius * (float)sin( M_PI * 2 * i / count )			
					);
				m_pGameManager->SpawnGameObject( EGO_VIRUS, pos );
			}					
		}	
	}
	void DoInit(bool bFirstTime)
	{
		m_pGameManager = (IGameManager*)IObjectUtils::GetUniqueInterface( "GameManager", IID_IGAMEMANAGER );
		m_pBlackboardManager= (IBlackboardManager*)IObjectUtils::GetUniqueInterface( "BlackboardManager", IID_IBLACKBOARDMANAGER );
		m_pGlobalParameters = m_pGameManager->GetGlobalParameters();
		m_pGameObjectParams = &(m_pGlobalParameters->go[m_gameObjectType]);

		m_gameTeam = m_pGameObjectParams->team;
		SetModel( m_pGameObjectParams->model.c_str() );
		m_collisionRadius = m_pGameObjectParams->collision_radius;

		if (bFirstTime)
		{
			SetColor( m_bIsSelected ? m_pGameObjectParams->color_highlight : m_pGameObjectParams->color_normal);
			m_scaleModulationTime = (float)(rand()*2*M_PI/RAND_MAX);
		}
		else
		{
			SetColor( m_color ); // Set render mesh to serialised color
		}

		if (!m_pBehaviorTree)
		{
			IBehaviorTreeManager* pBTManager = (IBehaviorTreeManager*)IObjectUtils::GetUniqueInterface( "BehaviorTreeManager", IID_IBEHAVIORTREEMANAGER );

			m_pBehaviorTree = pBTManager->GetTree( m_pGameObjectParams->behavior_tree.c_str() );
			AU_ASSERT(m_pBehaviorTree);
		}

		//* Demo
		if (m_rotationAxis.IsZero())
		{
			m_rotationAxis = AUVec3f((float)rand()/RAND_MAX - 0.5f, (float)rand()/RAND_MAX - 0.5f, (float)rand()/RAND_MAX - 0.5f);
			m_rotationAxis.Normalise();
			SetRotation((float)(rand()*2*M_PI/RAND_MAX - M_PI));
		}
		//*/

		m_pEntity->SetUpdateable( this );
	}
	IGameObject* GetSelectedObject( const AUVec3f& selectPos )
	{
		IGameObject* pGameObject = 0;
		float dist = FLT_MAX;
		TGameObjects::iterator it = m_Objects.begin();
		TGameObjects::iterator itEnd = m_Objects.end();
		while (it != itEnd)
		{
			IGameObject* pObj = *it;
			const AUVec3f& objPos = pObj->GetEntity()->GetPosition();
			float testDist = AUVec3f(objPos.x - selectPos.x, 0.0f, objPos.z - selectPos.z).Magnitude();
			if ( testDist < pObj->GetCollisionRadius() && testDist < dist )
			{
				pGameObject = pObj;
				dist = testDist;
			}

			++it;
		}

		return pGameObject;
	}