Announcement

Collapse
No announcement yet.

Having issues with AI Health Bars

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Having issues with AI Health Bars

    Hello,

    My team and I are working on a project with multiple AI on the screen at one time. I've set up a health bar to display over their heads. I've accomplished this by creating a new socket above their head, and attached an empty actor to it (that will display their health @ run time). Also should note that currently we have 3 different types of AI, and 2/3 are extended from the first. The health bar shows up exactly as I want it to for the base AI, but for the other two, one shows up far away from the AI on screen, and the 3rd doesn't show up at all. Also when there are multiple AI of the 2nd and 3rd type, the health bars do not show up at all.

    Here's a link to a screen grab of what I was talking about. Note that the health bar that looks like its pinned to the floor stays at that position no matter the camera position/rotation.
    http://imgur.com/sCVcMXo
    Thanks!

    Empty Health Bar Actor:
    Code:
    class HealthBarActor extends Actor;
    
    
    defaultproperties
    {
    }
    Base AI:
    Code:
    class Turtle extends Pawn placeable;
    
    var HealthBarActor HBActor;
    var bool bTouchSnowCheck;
    var bool bSlowDown;
    var bool IsFullySlowed;
    var float speed;
    var float halfSpeed;
    
    event PostBeginPlay()
    {
        local Vector loc;
        local Rotator myRot;
        Super.PostBeginPlay();
        GetALocalPlayerController().myHUD.AddPostRenderedActor(self);
        if(Mesh != none && Mesh.GetSocketByName('HealthBarSocket') != none)
        {
            Mesh.GetSocketWorldLocationAndRotation('HealthBarSocket',loc, myRot);
            HBActor = Spawn(class'HealthBarActor',,,loc, myRot);
            if(HBActor != none)
            {
                HBActor.Setbase(self,,Mesh,'HealthBarSocket');
            }
        }
    }
    
    Simulated event PostRenderFor(PlayerController PC, Canvas Canvas, Vector CameraPosition, Vector CamerDir)
    {
        local Vector ScreenPos;
        ScreenPos = Canvas.Project(HBActor.Location);
        Canvas.SetPos(ScreenPos.X - 50, ScreenPos.Y);
        Canvas.SetDrawColor(0, 255, 0);
        Canvas.DrawRect(Health, 10);
    }
    
    event TakeDamage(int Damage, Controller InstigatedBy, vector HitLocation, vector Momentum, class<DamageType> DamageType, optional TraceHitInfo HitInfo, optional Actor DamageCauser)
    {
        if (Health - Damage < 0)
        {
            WorldInfo.Game.Broadcast(self, "Turtle is Dead!");
            Destroy();
        }
        else
        {
            PlaySound(SoundCue'KismetGame_Assets.Sounds.Turtle_Death_Cue');
            Super.TakeDamage(Damage, InstigatedBy, HitLocation, Momentum, DamageType, HitInfo, DamageCauser);
        }
    }
    
    event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
    {
    
        if(Other.IsA('CloudPawn')) 
        {
            if(bSlowDown == false)
            {
    			bSlowDown=true;
    			WorldInfo.Game.Broadcast(self, "bSlowDown is true");
    			bTouchSnowCheck = true;
    			SlowSpeed();
            }
        }
    }
    
    event UnTouch(Actor Other)
    {
    	bSlowDown=false;
    	WorldInfo.Game.Broadcast(self, "bSlowDown is false");
    }
    
    
    function SlowSpeed()
    {
        if(bTouchSnowCheck && GroundSpeed >= halfSpeed && bSlowDown)
        {
    		if(GroundSpeed == halfSpeed)
    		{
    			GroundSpeed = halfSpeed;
    		}
    	
        }
    }
    
    defaultproperties
    {
        GroundSpeed=+0150.0000
        halfSpeed=+0075.0000
        ControllerClass=class'TurtleAI' 
        bTouchSnowCheck = false
        bSlowDown=false
        Begin Object Name=CollisionCylinder
            CollisionRadius=+0034.000000
            CollisionHeight=+0034.000000
            BlockZeroExtent=FALSE
        End Object
        
        Components.Remove(Sprite)
        
        Begin Object Class=SkeletalMeshComponent Name=NanoPawnMesh
        SkeletalMesh=SkeletalMesh'WN_Package.SkeletalMesh.Turtle'
        AnimSets(0)=AnimSet'WN_Package.Anims.Turtle_Anims'
        AnimTreeTemplate=AnimTree'WN_Package.Anims.Turtle_AnimTree'
        BlockZeroExtent=TRUE
        BlockNonZeroExtent=TRUE
        CollideActors=TRUE
        BlockRigidBody=TRUE
        RBChannel=RBCC_Pawn
        RBCollideWithChannels=(Default=TRUE,Pawn=TRUE,DeadPawn=TRUE,BlockingVolume=TRUE,EffectPhysics=TRUE,FracturedMeshPart=TRUE,SoftBody=TRUE)
        bIgnoreControllersWhenNotRendered=TRUE
        End Object
        Mesh=NanoPawnMesh
        Components.Add(NanoPawnMesh)
    }
    2nd AI:
    Code:
    class BombTurtle extends Turtle;
    
    event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
    {
    
        if(Other.IsA('CloudPawn')) 
        {
            if(IsFullySlowed == false)
            {
    			bSlowDown=true;
    			WorldInfo.Game.Broadcast(self, "bSlowDown is true");
    			bTouchSnowCheck = true;
    			SlowSpeed();
            }
        }
    }
    
    event UnTouch(Actor Other)
    {
    	bSlowDown=false;
    	WorldInfo.Game.Broadcast(self, "bSlowDown is false");
    }
    
    function SlowSpeed()
    {
        if(bTouchSnowCheck && GroundSpeed >= halfSpeed && bSlowDown)
        {
    		if(GroundSpeed == halfSpeed)
    		{
    			GroundSpeed = halfSpeed;
    		}
    	
        }
    }
    
    defaultproperties
    {
    	GroundSpeed=+075.0000
    	halfSpeed = +037.5000
    	ControllerClass=class'TurtleAI' 
    	
    	Begin Object Name=CollisionCylinder
    		CollisionRadius=+0034.000000
    		CollisionHeight=+0010.000000
    		BlockZeroExtent=FALSE
    	End Object
    	
    	Components.Remove(NanoPawnMesh)
    	
    	Begin Object Class=SkeletalMeshComponent Name=TurtleBombMesh
    	SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_TurtleBomb_01'
    	AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_TurtleBomb_01_Anims'
    	AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.TurtleBomb_AnimTree'
    	BlockZeroExtent=TRUE
    	BlockNonZeroExtent=TRUE
    	CollideActors=TRUE
    	BlockRigidBody=TRUE
    	RBChannel=RBCC_Pawn
    	RBCollideWithChannels=(Default=TRUE,Pawn=TRUE,DeadPawn=TRUE,BlockingVolume=TRUE,EffectPhysics=TRUE,FracturedMeshPart=TRUE,SoftBody=TRUE)
    	bIgnoreControllersWhenNotRendered=TRUE
    	End Object
    	Mesh=TurtleBombMesh
    	Components.Add(TurtleBombMesh)
    }
    3rd AI:
    Code:
    class Snake extends Turtle placeable;
    
    event Touch( Actor Other, PrimitiveComponent OtherComp, vector HitLocation, vector HitNormal )
    {
    
        if(Other.IsA('CloudPawn')) 
        {
            if(IsFullySlowed == false)
            {
    			bSlowDown=true;
    			WorldInfo.Game.Broadcast(self, "bSlowDown is true");
    			bTouchSnowCheck = true;
    			SlowSpeed(); 
            }
        }
    }
    
    event UnTouch(Actor Other)
    {
    	bSlowDown=false;
    	WorldInfo.Game.Broadcast(self, "bSlowDown is false");
    }
    
    
    function SlowSpeed()
    {
        if(bTouchSnowCheck && GroundSpeed >= halfSpeed && bSlowDown)
        {
    		if(GroundSpeed == halfSpeed)
    		{
    			GroundSpeed = halfSpeed;
    		}
    	
        }
    }
    
    defaultproperties
    {
        GroundSpeed=+0350.0000
        bTouchSnowCheck = false
    	halfSpeed=+0175.0000
        Components.Remove(NanoPawnMesh)
        
        Begin Object Class=SkeletalMeshComponent Name=SnakePawnMesh
        SkeletalMesh=SkeletalMesh'KismetGame_Assets.Anims.SK_Snake'
        AnimSets(0)=AnimSet'KismetGame_Assets.Anims.SK_Snake_Anims'
        AnimTreeTemplate=AnimTree'KismetGame_Assets.Anims.Snake_AnimTree'
        BlockZeroExtent=TRUE
        BlockNonZeroExtent=TRUE
        CollideActors=TRUE
        BlockRigidBody=TRUE
        RBChannel=RBCC_Pawn
        RBCollideWithChannels=(Default=TRUE,Pawn=TRUE,DeadPawn=TRUE,BlockingVolume=TRUE,EffectPhysics=TRUE,FracturedMeshPart=TRUE,SoftBody=TRUE)
        bIgnoreControllersWhenNotRendered=TRUE
        End Object
        Mesh=SnakePawnMesh
        Components.Add(SnakePawnMesh)
    }

    #2
    I noticed that u have placeable set inside of these classes, possibly try spawning them in with kismet

    Comment


      #3
      Thanks for the suggestion caseyholcomb, but removing the placeable call didn't do anything. Still getting the same bug as before. I did however forget to list some warnings I get in the console during runtime:

      Code:
      ScriptWarning: Accessed None 'HBActor'
      	BombTurtle Hudson_Test.TheWorld:PersistentLevel.BombTurtle_0
      	Function wateringnature.Turtle:PostRenderFor:004E
      ScriptWarning: Accessed None 'HBActor'
      	Snake Hudson_Test.TheWorld:PersistentLevel.Snake_0
      	Function wateringnature.Turtle:PostRenderFor:004E
      It seems to be saying there is something wrong with what I have in my PostRenderFor function. Does anyone know what '004E' is in reference to?

      PS this was from a small level I have set up for testing. In it, one unit of each type of AI is spawned into the level via kismet.

      Comment


        #4
        004E is irrelevant
        look at what the warning is telling you

        Accessed None 'HBActor' - means HBActor does not reference an actor
        Function wateringnature.Turtle:PostRenderFor - this is the function it has a problem with

        so looking in that function for HBActor i see this line

        ScreenPos = Canvas.Project(HBActor.Location);

        to fix this make HBActor an actual reference to an actor that exists in the world

        Comment


          #5
          Thanks for the advice tegleg. Can you elaborate on what you mean by 'actual reference to an actor'? I tried creating another two empty actors and simply copy/paste the stuff from turtle into the other 2 scripts replacing the empty actor reference w/ a new one. That didn't work, still got the warning, just with a different name for the new empty actor. I also tried placing everything inside my game script, and just made it reference any actor of type turtle in the level for what to attach it to. Not only did that not work, but nothing showed up after that.

          When you say make an actual reference, do you mean typing something like, "WorldInfo.Game.HealthBarActor"?

          Comment


            #6
            Look at the error:
            Code:
            Accessed None 'HBActor'
            Which means that your var 'HBActor' is equal to 'None,' which means it does not have a reference to the actor that it should. So when you are trying to Project the actors location in your PostRender function, you get an error - you cannot reference the Location of an actor that does not exist.

            Make sure that you set the reference to HBActor correctly and that it is constantly updated. In your PostRender function, you need to add this additional check so that this error is not capable of even occurring in the first place.

            Code:
            Simulated event PostRenderFor(PlayerController PC, Canvas Canvas, Vector CameraPosition, Vector CamerDir)
            {
                local Vector ScreenPos;
                
                if ( HBActor != None ) {
                    ScreenPos = Canvas.Project(HBActor.Location);
                    Canvas.SetPos(ScreenPos.X - 50, ScreenPos.Y);
                    Canvas.SetDrawColor(0, 255, 0);
                    Canvas.DrawRect(Health, 10);
                } 
            }

            Comment

            Working...
            X