Jump to content
  • entries
    10
  • comments
    21
  • views
    22,127

The first toddler steps of AI


Chris Paulson

2,144 views

 Share

Youtube video of my AI.

 

Red line is path found by recast.

White text is current behaviours running in behaviour tree.

 

 

 

Here's what the BT looks like (yes it is C++)

alive::Node* moveToEnemy(std::string type = "walk")
{
   return alive::TreeBuilder()
		.execute<ActionMoveToEnemy>()
			.type(type)
		.end();
}

alive::Node* resetToStart()
{
   return alive::TreeBuilder()
	.composite<alive::SequenceNode>()
		.execute<ActionCurrentMode>()
			.mode("resetToStart")
		.end()
		.execute<ActionAnimate>()
			.Speed(1)
			.Name("rifle_idle")
			.AnimType(PLAY_REPEAT)
		.end() 
		.composite<alive::ParallelNode>()
			.execute<LookForward>()
				.Parallel(true)
			.end()
			.execute<ActionStopMove>()
			.end()
		.end()
	.end();
}

alive::Node* gunAttack()
{
   return alive::TreeBuilder()
	.composite<alive::SequenceNode>()
		.execute<ActionCurrentMode>()
			.mode("gunAttack")
		.end()
		.execute<hasGun>()
			.Equals(true)
		.end()
		.execute<CanSeeEnemy>()
			.Equals(true)
			.Parallel(false)
		.end()
		.execute<ActionStopMove>()
		.end()
		.execute<ActionAnimate>()
			.Speed(1)
			.TranTime(1)
			.Name("rifle_idle")
			.AnimType(PLAY_REPEAT)
		.end() 
		.composite<alive::ParallelNode>()
			.execute<CanSeeEnemy>()
				.Equals(true)
			.end()
			.execute<WithinFiringRange>()
				.Equals(true)
			.end()
			.execute<AimAtEnemy>()
			.end()
			.composite<alive::SequenceNode>()
				.decorator<alive::RepeatNode>()
					.composite<alive::SelectorNode>()
						.execute<NeedToAim>()
							.Equals(true)
						.end()
						.execute<FireAtEnemy>()
						.end()
						.execute<ActionTimer>()
							.time(0.01)
						.end()
					.end()
				.end()
			.end()
		.end()
	.end();
}


alive::Node* moveToAttackPosition()
{
   return alive::TreeBuilder()
	.composite<alive::SequenceNode>()
		.execute<ActionCurrentMode>()
			.mode("moveToAttackPosition")
		.end()
		.execute<hasGun>()
			.Equals(true)
		.end()
		.add(resetToStart()).end()
		.composite<alive::ParallelNode>()
			.execute<IsSeenIdle>()
				.Equals(false)
			.end()
			.execute<WithinFiringRange>()
				.Equals(true)
			.end()
			.execute<hasGoodAimAtEnemy>()
				.Equals(false)
			.end()
			.add(moveToEnemy()).end()
		.end()
	.end();
}

alive::Node* moveToWithinRifleRange()
{
   return alive::TreeBuilder()
	.composite<alive::SequenceNode>()
		.execute<ActionCurrentMode>()
			.mode("moveToWithinRifleRange")
		.end()
		.execute<hasGun>()
			.Equals(true)
		.end()
		.composite<alive::ParallelNode>()
			.execute<LookForward>()
				.Parallel(true)
			.end()
			.execute<IsSeenIdle>()
				.Equals(false)
			.end()
			.execute<WithinFiringRange>()
				.Equals(false)
			.end()
			.add(moveToEnemy()).end()
		.end()
	.end();
}
alive::Node* hunt()
{
   return alive::TreeBuilder()
	.composite<alive::SequenceNode>()
		.execute<ActionCurrentMode>()
			.mode("hunt")
		.end()
		.composite<alive::ParallelNode>()
			.execute<LookForward>()
				.Parallel(true)
			.end()
			.execute<IsSeenIdle>()
				.Equals(false)
			.end()
			.execute<CanSeeEnemy>()
				.Equals(false)
			.end()
			.add(moveToEnemy()).end()
		.end()
	.end();
}

void Crawler::init(Pedestrian* pPedestrian, Vision *pvision, ActorGun *pRifle)
{
//			.decorator<alive::RepeatNode>()
//	.decorator<alive::ErrorHandlerNode>()
   alive::Node* behave = alive::TreeBuilder()
.decorator<alive::RepeatNode>()
	.add(resetToStart()).end()
	.composite<alive::SelectorNode>()
		// Reset to default
		// Attack with gun
		.add(gunAttack()).end()

		// Move to a aim position
		.add(moveToAttackPosition()).end()

		// Move to attack (to melle or to get in firing range)
		.add(moveToWithinRifleRange()).end()

		// Hunt
		.add(hunt()).end()

		// Move to waypoint
		.composite<alive::ParallelNode>()
			.execute<CanSeeEnemy>()
				.Equals(false)
			.end()
			.composite<alive::SequenceNode>()
				.add(resetToStart()).end()
				.execute< CrawlerCompare<bool> >()
					.Variable(&Crawler::hasWaypoint)
					.Reference(true)
				.end()
				.execute<ActionMoveToWaypoint>()
				.end()
			.end()
		.end()
		// Idle
		.composite<alive::SequenceNode>()
			.execute<ActionCurrentMode>()
				.mode("idle")
			.end()
			.composite<alive::ParallelNode>()
				.execute<CanSeeEnemy>()
					.Equals(false)
				.end()
				.composite<alive::SequenceNode>()
					.add(resetToStart()).end()
					.execute<ActionAnimate>()
						.Speed(1)
						.Name("rifle_idle")
						.AnimType(PLAY_ONCE)
					.end()
				.end()
			.end()
		.end()
	.end()
.end();

rifle = pRifle;
pedestrian = pPedestrian;
vision = pvision;

//	alive::InitializeWithBlackboard<Crawler> initialize(*this);
alive::InitializeWithBlackboard<Crawler> *initialize = new alive::InitializeWithBlackboard<Crawler>(*this);
m_Brain.registry.setAddObserver(*initialize);
   m_Brain.registry.setAddObserver(*new InitializeAction(*this));

   //m_Brain.registry.setAddObserver(*new InitializeAction(*this));
   m_Brain.add(*behave);
}

void Crawler::Update( float gameLoopTime )
{
pedestrian->currentAction = pedestrian->currentMode + ",";
m_Brain.tick();
pedestrian->Update( gameLoopTime );
}

void Crawler::Render( float gameLoopTime)
{
pedestrian->Render( gameLoopTime );
vision->Render( pedestrian->scene->cam );
}

 Share

3 Comments


Recommended Comments

LOL, that must be the most reference utilizing C++ program I've ever seen. Methods after methods after methods seperated by dots.

Link to comment

Same here. I can't follow how that is working at all. Never seen that syntax. It's almost like it's a with statement with all the .Function()

Link to comment
Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...