Download

Pawn Uncontrollable After GoToState()

For my pawn, I created a state that ’ locks on ’ to a target. The state works and all, but once the state is committed and goes through all the code, i cannot move my pawn around at all.
No warnings or errors come up in the Log and I’m not sure what to do to enable control over my pawn again( though still possessed )

This is how the state is called, simple exec function to start all of this


exec function ToggleCombat()
{ 
    GoToState('EngageCombat');
}

And now here is the state code, it does not loop.


state EngageCombat
{
    function CheckForEnemies()
    {
        if(BladePawn(Pawn) != None)
        {
            foreach WorldInfo.AllPawns(class'BladeAIPawn', PendingTarget)
            {
				if(PendingTarget != LockTarget)
				{
					`log(" did fast trace");
					if(FastTrace(PendingTarget.Location, Pawn.Location)) // if nothing inbetween
					{
						if(PendingTarget.Health > 0)
						{						
							LockedTargets.AddItem(PendingTarget); // add to lock targets
							`log(" the pending target is "$PendingTarget);
							CountEnemies();
						}                           
					}
				}
            }
        }
    }
    
    function CountEnemies()
    {
        if(BladePawn(Pawn).Health > 0 && BladePawn(Pawn) != None)
        {
            AmountTargets = LockedTargets.Length;
            if(AmountTargets == 1 || AmountTargets > 1)
            {
                bCombat = true; // there is an enemy 
                LockOnTarget();
            }
            else if(AmountTargets == 0 || AmountTargets < 0)
            {
                GoToState('');
				bLockedOn = false;
            }               
        }
    }
    
    function LockOnTarget()
    {
		bLockedOn = true;
		`log(" lock target = " $ LockedTargets[0]);  
        LockTarget = LockedTargets[0]; // find the first enemy in the array       
		BladeHUD(myhud).SetTargetIcon(LockTarget.FaceIcon,LockTarget.Level,LockTarget.Health);				
		LockRotation();
	}
	
	function LockRotation()
	{
		if(bLockedOn)
		{		
			Pawn.SetRotation(rotator(LockTarget.Location - Pawn.Location));
			Pawn.SetViewRotation(rotator(LockTarget.Location - Pawn.Location));
			DrawDebugLine(Pawn.Location,LockTarget.Location,0,0,255,true);	
			Pawn.ZeroMovementVariables();
			`log("pawn is locked on target");
			return;
		}	
	}	
Begin:
    CheckForEnemies();
}

I think it has something to do with the Pawn::SetRotation() function maybe? Im not quite sure, any help anyone??? Appreciate it.

I’m not entirely certain how you’re expecting this lock on mechanic to work.

So I can only point out a potential issue with your posted code.
Once you call ToggleCombat you will be stuck in that state (unless you’re changing state somewhere else that is not in the code above). Now you may be wondering why since you’re calling GotoState from CountEnemies. Well if CheckForEnemies reaches the inner-most body (so PendingTarget.Health > 0) you add PendingTarget to LockedTargets (so its length is >= 1) and then call CountEnemies. You can already see you’ll never be able to meet the else if condition (AmountTargets <= 0) and never call GoToState. The reason for this is that LockedTargets is guaranteed to have at least one item at the point you call CountEnemies (unless there’s more to it than what you’ve posted).
What you may (or may not) have intended to do was add all PendingTargets to LockedTargets first and then (after foreach WorldInfo.AllPawns) call CountEnemies. That way it would be possible that you didn’t find any LockedTargets and would leave the state again.
Another option (kind of already suggested by the name ToggleCombat) would be to first check whether you’re in state EngageCombat in ToggleCombat. If not GotoState(‘EngageCombat’) otherwise (you’re already in that state) leave it again GotoState(’’). Depends on whether you want the exec (player) to cancel EngageCombat or not.

Similarly the if (bLockedOn) condition is unnecessary since bLockedOn is always true when you call LockRotation from LockOnTarget.

About setting rotation, you may also want to set the Controller rotation, not just the one of the pawn (again depending on what you want).
Also keep in mind your only running through this code once when you enter the Begin: label of EngageCombat (could be intentional?). So if the target you’re locked on to moves, you aren’t updating the rotation to remain locked on.

Something I’m not entirely sure about is whether calling GotoState(’’) will work or whether it would be better to use PushState/PopState. That way you could preserve the previous state and simply go back to it after EngageCombat.

If you want players to be able to move in EngageCombat you may want to look at the other states like PlayerWalking etc. and copy their movement code (PlayerMove, ProcessMove) for now. This may become more complex if you want EngageCombat to be “additive” and applicable for any state (so flying, swimming, etc.) and not just walking.