Results 1 to 6 of 6
  1. #1

    Default [Solved] AI to Follow Actor (Projectile) instead of Pawn

    Hi all,

    I am a Game Design student working on my final project. I have followed Mougli's tutorials to make an AI that follows the player. It is working great (Thanks Mougli.) Anyway, The concept of the game is to have the AI chase after a "treat" (UTProjectile) that is shot out of a gun, if no projectile is in the world it should follow the player. I thought if I could change the target to the projectile it would work, but no luck there. I was wondering if there is a simple way to incorporate an:

    if (projectile)
    {make projectile target}
    else
    {make player target}

    Here is the code I am working with:
    Code:
    class Bewildered_AIController extends AIController;
    
    var Actor target;
    var() Vector TempDest;
    var float playerDistance;
    var UTProj_Treat Treat;
    //var Actor TreatFind;
    //var Vector TreatLoc;
    
    event Possess(Pawn inPawn, bool bVehicleTransition)
    {
        super.Possess(inPawn, bVehicleTransition);
        Pawn.SetMovementPhysics();
    }
    
    //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);
    //		TreatLoc = UTProj_Treat.location;
    		target = Seen;
    //		TreatFind = Bewildered.UTProj_Treat.Treat;
    
    
    
    		//if(Treat != none)
    		//{
    		//	target = treat;
    		//}
    		//else
    		//{
    		//	target = seen;
    		//}
    
    		playerDistance = VSize(Pawn.location - target.location);
    		if(playerDistance > 256)
    			GotoState('Follow');
    		else
    			GotoState('Idle');
        }
    Begin:
    }
    
    state Follow
    {
       ignores SeePlayer;
        function bool FindNavMeshPath()
        {
    	target = Treat;
            // 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) <= 1024)
    	{
    		gotostate('Idle');
    	}
        else
    	{
    		goto 'Begin';
    	}
    }
    
    DefaultProperties
    {
    }
    Everything else we are using is very basic, the projectile extends UTProjectile, My Bot extends UDKPawn, I have looked around and get the basic concept, but I am not a programer so I get lost really easily. Sorry if this is something simple, or if it has been answered before. I have looked everywhere I can think and nothing seems to explain it in a language I can understand. Thank you in advance for any help that can be offered.
    Last edited by pcasey; 08-20-2012 at 02:53 PM. Reason: Solved

  2. #2

    Default

    I am sorry to bump this, but we have been going crazy trying to figure this out.
    I am not sure if I am not clear enough in what I am trying to accomplish or if it is so basic everyone is laughing at me, but either way any help would be a God-send at this point.
    Thank you.

  3. #3
    MSgt. Shooter Person
    Join Date
    Nov 2008
    Posts
    136

    Default

    I'm fairly new at this stuff too, but it may be posible to handle this in the weapon. Like, firing the weapon hands the name of the projectile it spawned and changes your bot's target variable to it. When the projectile is destroyed [or whatever, depends on how you're wanting the game to work] it changes the target back to the player.

    Not sure how to code this.

  4. #4

    Default [Solved]

    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.

  5. #5
    Banned
    Join Date
    Feb 2011
    Location
    BXL/Paris
    Posts
    2,169

    Default

    ReceiveProjectileWarning should be called and use Focus...

  6. #6

    Default

    Quote Originally Posted by VendorX View Post
    ReceiveProjectileWarning should be called and use Focus...
    I am probably going to show more of my ignorance here, but reading about ReceiveProjectileWarning makes it sound like it warns the player if it is about to be shot, rarely, if ever, will we actually be aiming at the bot or even near the bot. The best example of what we are trying to accomplish is:
    Think of a dog and a treat gun. The dog will be by our side until we shoot the gun, then the dog will race to get the treat. If we wanted the dog to go to a new area we would shoot a treat over to the new area and the dog would chase after that new one. (In our game we actually want it to stay at the treat unless we move, shoot another treat or are a certain distance away.)
    Again, I know I have very little knowledge in this area, but I just don't understand how this function can be modded to achieve what we are going for.
    Thanks for the advice though, I didn't even know that existed.


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.