Ok, working in a team environment definitely helped here. I take no credit for solving this as it was my teammate with some help from his friend that got this working.
Essentially, we had to have our gun let the AIController know it was shooting a projectile and then pass that to it. Here is the code that makes it all come together. Hopefully the next person looking to do something like this won't have to struggle as much as we did.
Weapon:
Code:
class UTWeap_TreatGun extends UTWeap_RocketLauncher_Content
placeable;
var Bewildered_AIController Watawala;
simulated function PostBeginPlay()
{
local Controller Mybot;
super.PostBeginPlay();
foreach WorldInfo.AllControllers(class'Controller', MyBot)
{
if (Bewildered_AIController(Mybot) != none)
{
Watawala=Bewildered_AIController(MyBot);
break;
}
}
}
simulated function Projectile ProjectileFire()
{
local vector RealStartLoc;
local Projectile SpawnedProjectile;
// tell remote clients that we fired, to trigger effects
IncrementFlashCount();
if( Role == ROLE_Authority )
{
// this is the location where the projectile is spawned.
RealStartLoc = GetPhysicalFireStartLoc();
// Spawn projectile
SpawnedProjectile = Spawn(GetProjectileClass(),,, RealStartLoc);
if( SpawnedProjectile != None && !SpawnedProjectile.bDeleteMe )
{
SpawnedProjectile.Init( Vector(GetAdjustedAim( RealStartLoc )) );
}
//WorldInfo.Game.Broadcast(self, 'Ill projectile your face'');
Watawala.SetTarget(SpawnedProjectile);
// Return it up the line
return SpawnedProjectile;
}
return None;
}
function AdjustLockTarget(actor NewLockTarget)
{
}
function FireLoad()
{
}
DefaultProperties
{
WeaponProjectiles(0)=class'UTProj_Treat'
AmmoCount=100
bHidden=true
}
AIController:
Code:
class Bewildered_AIController extends AIController;
var() Vector TempDest;
var float targetDistance;
var Actor Target;
var int WaitDistance;
event Possess(Pawn inPawn, bool bVehicleTransition)
{
super.Possess(inPawn, bVehicleTransition);
Pawn.SetMovementPhysics();
}
function SetTarget(Projectile TreatTarget)
{
WorldInfo.Game.Broadcast(self, 'In Set Target');
WorldInfo.Game.Broadcast(self, TreatTarget);
Target=TreatTarget;
WorldInfo.Game.Broadcast(self, Target);
GoToState('Follow');
}
//I'm adding a default idle state so the Pawn doesn't try to follow a player that doesn't exist yet.
auto state Idle
{
event SeePlayer (Pawn Seen)
{
super.SeePlayer(Seen);
target = Seen;
targetDistance = VSize(Pawn.location - target.location);
WorldInfo.Game.Broadcast(self, targetDistance);
if(targetDistance > WaitDistance)
GotoState('Follow');
else
GotoState('Idle');
}
Begin:
}
state Follow
{
ignores SeePlayer;
function bool FindNavMeshPath()
{
// Clear cache and constraints (ignore recycling for the moment)
NavigationHandle.PathConstraintList = none;
NavigationHandle.PathGoalList = none;
// Create constraints
class'NavMeshPath_Toward'.static.TowardGoal( NavigationHandle,target );
class'NavMeshGoal_At'.static.AtActor( NavigationHandle, target,32 );
// Find path
return NavigationHandle.FindPath();
}
Begin:
if( NavigationHandle.ActorReachable( target) )
{
FlushPersistentDebugLines();
//Direct move
MoveToward( target,target );
}
else if( FindNavMeshPath() )
{
NavigationHandle.SetFinalDestination(target.Location);
FlushPersistentDebugLines();
NavigationHandle.DrawPathCache(,TRUE);
// move to the first node on the path
if( NavigationHandle.GetNextMoveLocation( TempDest, Pawn.GetCollisionRadius()) )
{
DrawDebugLine(Pawn.Location,TempDest,255,0,0,true);
DrawDebugSphere(TempDest,16,20,255,0,0,true);
MoveTo( TempDest, target );
}
}
else
{
//We can't follow, so get the hell out of this state, otherwise we'll enter an infinite loop.
GotoState('Idle');
}
if (vsize(pawn.location - target.location) <= WaitDistance)
{
gotostate('Idle');
}
else
{
goto 'Begin';
}
}
simulated event GetPlayerViewPoint(out vector out_Location, out Rotator out_Rotation)
{
// AI does things from the Pawn
if (Pawn != None)
{
out_Location = Pawn.Location;
out_Rotation = Rotation; //That's what we've changed
}
else
{
Super.GetPlayerViewPoint(out_Location, out_Rotation);
}
}
DefaultProperties
{
WaitDistance=512
}
Hit_Actor:
Code:
class Bewildered_HitActor extends Actor
placeable;
DefaultProperties
{
Begin Object Class=DynamicLightEnvironmentComponent Name=MyLightEnvironment
bEnabled=TRUE
End Object
Begin Object Class=StaticMeshComponent Name=MeshComp
StaticMesh=StaticMesh'NEC_Deco.SM.Mesh.S_NEC_Deco_SM_Cuchulainn_Pose3'
End Object
Components.Add(MeshComp)
CollisionComponent=MeshComp
bCollideActors=true
bBlockActors=true
BlockRigidBody=true
}
The Bot:
Code:
class Bewildered_Bot extends UDKPawn
placeable;
var int BotForm;
var Projectile Target;
function CheckActorInFront()
{
local vector HitLocation, HitNormal, extent;
local TraceHitInfo HitInfo;
local actor HitActor;
local float TraceDist;
TraceDist = 160;
HitActor = Trace(HitLocation, HitNormal, Location + TraceDist*Vector(Rotation), Location, True,extent * 0, HitInfo, /*TRACEFLAG_PhysicsVolumes*/);
//WorldInfo.Game.Broadcast(self, HitActor);
if (Bewildered_HitActor(HitActor) !=none && BotForm == 1)
{
HitActor.Destroy();
}
}
simulated function Tick(float DeltaTime)
{
//WorldInfo.Game.Broadcast(self, BotForm);
CheckActorInFront();
}
DefaultProperties
{
BotForm = 1;
Begin Object Name=CollisionCylinder
CollisionHeight=+22.000000
end object
Begin Object class=SkeletalMeshComponent Name=BewilderedPawnSkeletalMesh
// SkeletalMesh=SkeletalMesh'CH_IronGuard_Male.Mesh.SK_CH_IronGuard_MaleA'
SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Jazz'
// AnimSets(0)=AnimSet'CH_AnimHuman.Anims.K_AnimHuman_BaseMale'
AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Jazz_Anims'
// AnimTreeTemplate=AnimTree'CH_AnimHuman_Tree.AT_CH_Human'
AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Jazz_AnimTree'
// PhysicsAsset=PhysicsAsset'CTF_Flag_IronGuard.Mesh.S_CTF_Flag_IronGuard_Physics'
PhysicsAsset=PhysicsAsset'ga_agent.AgentDefault_Physics'
HiddenGame=FALSE
HiddenEditor=FALSE
End Object
Mesh=BewilderedPawnSkeletalMesh
Mass=1000000.00
Components.Add(BewilderedPawnSkeletalMesh)
ControllerClass=class'Bewildered.Bewildered_AIController'
bJumpCapable=true
bCanJump=true
GroundSpeed=325.0 //Making the bot faster than the player
bPushesRigidBodies=true
bCallRigidBodyWakeEvents=true
bAvoidLedges=true
BlockRigidBody=true
SightRadius=10000
Alertness=1.0
bAllowFluidSurfaceInteraction=true
bAlwaysEncroachCheck=true
DrawScale=.5
}
I still don't fully understand the code, I can follow the logic, but not exactly sure how it's implemented. The hit_actor is used so the bot knows it's out there. And the AI changes the target from Player to 'Treat' based on the gun. Also we wanted to incorporate a means to have the bot stay in it's position unless we are a certain distance away from it. This still needs some work since when you shoot the gun the bot is facing away from you and won't come back until it sees you. But since we are not programmers and have 3 more months to figure that out, I'm not too worried about it.
There may be extraneous code in here or code that does nothing at all, but like I said we are neophytes and have 3 months to get it all figured out.
Bookmarks