script assistance/workaround yield affecting animations.

Here’s my enemy ai’s patrol state. I think his yield waitforseconds() delay is stopping his waitidle animation from playing while he’s waiting. the script works as it is supposed to, except when he is waiting at a waypoint like he’s supposed to he just stands in a froze first frame of his waitidle animation until it’s time is up then resumes as he should.

//=====PATROL==============

function patrolstate () {

var way1distance = (waypoint1.position - myTransform.position).magnitude;
var way2distance = (waypoint2.position - myTransform.position).magnitude;
var way3distance = (waypoint3.position - myTransform.position).magnitude;
var way4distance = (waypoint4.position - myTransform.position).magnitude;



if (attacking == false && chasing == false && patrol == true){



	if(patrol == true && nextwaypoint1 == true && way1canwait == false && way1distance <= waypointThreshold){
      patrolspeed = patrolspeedreset;
      waiting = false;
      nextwaypoint1 = false;
      nextwaypoint2 = true;
      nextwaypoint3 = false;
      nextwaypoint4 = false;
      }
	else if(patrol == true && nextwaypoint2 == true && way2canwait == false && way2distance <= waypointThreshold){
	  patrolspeed = patrolspeedreset;
	  waiting = false;
	  nextwaypoint1 = false;
      nextwaypoint2 = false;
      nextwaypoint3 = true;
      nextwaypoint4 = false;
      }      
	else if(patrol == true && nextwaypoint3 == true && way3canwait == false && way3distance <= waypointThreshold){
	  patrolspeed = patrolspeedreset;
	  waiting = false;
	  nextwaypoint1 = false;
      nextwaypoint2 = false;
      nextwaypoint3 = false;
      nextwaypoint4 = true;
      }
	else if(patrol == true && nextwaypoint4 == true && way4canwait == false && way4distance <= waypointThreshold){
	  patrolspeed = patrolspeedreset;
	  waiting = false;
	  nextwaypoint1 = true;
      nextwaypoint2 = false;
      nextwaypoint3 = false;
      nextwaypoint4 = false;
      }


	if(patrol == true && nextwaypoint1 == true && way1canwait == true && way1distance <= waypointThreshold){
      patrolspeed = 0;
      animation.Stop(walk.name);
      animation[waitidle.name].speed = 1;
      animation.CrossFade(waitidle.name);
      waiting = true;
      yield WaitForSeconds(waypointDelayTime);
      waiting = false;
      patrolspeed = patrolspeedreset;
      nextwaypoint1 = false;
      nextwaypoint2 = true;
      nextwaypoint3 = false;
      nextwaypoint4 = false;
      return;
      }      
      

      
	else if(patrol == true && nextwaypoint2 == true && way2canwait == true && way2distance <= waypointThreshold){
      patrolspeed = 0;
      animation.Stop(walk.name);
      animation[waitidle.name].speed = 1;
      animation.CrossFade(waitidle.name);      
      waiting = true;
      yield WaitForSeconds(waypointDelayTime);
      waiting = false;
      patrolspeed = patrolspeedreset;
      nextwaypoint1 = false;
      nextwaypoint2 = false;
      nextwaypoint3 = true;
      nextwaypoint4 = false;
      return;
      
      }      
	  

      
	else if(patrol == true && nextwaypoint3 == true && way3canwait == true && way3distance <= waypointThreshold){
      patrolspeed = 0;
      animation.Stop(walk.name);
      animation[waitidle.name].speed = 1;
      animation.CrossFade(waitidle.name);	  
	  waiting = true;
	  yield WaitForSeconds(waypointDelayTime);
	  waiting = false;
	  patrolspeed = patrolspeedreset;
	  nextwaypoint1 = false;
      nextwaypoint2 = false;
      nextwaypoint3 = false;
      nextwaypoint4 = true;
      return;
      
      }      

      
	else if(patrol == true && nextwaypoint4 == true && way4canwait == true && way4distance <= waypointThreshold){
      patrolspeed = 0;
      animation.Stop(walk.name);
      animation[waitidle.name].speed = 1;
      animation.CrossFade(waitidle.name);	  
	  waiting = true;
	  yield WaitForSeconds(waypointDelayTime);
	  waiting = false;
	  patrolspeed = patrolspeedreset;
	  nextwaypoint1 = true;
      nextwaypoint2 = false;
      nextwaypoint3 = false;
      nextwaypoint4 = false;
      return;
      
      }      
      


	if (nextwaypoint1 == true && way1distance > waypointThreshold && waiting == false){
	     myTransform.LookAt(waypoint1.position); 
	     myTransform.Translate(patrolspeed * Vector3.forward * Time.deltaTime);
	     animation[walk.name].speed = walk_anim_speed;
         animation.Play(walk.name);
     } 
	else if (nextwaypoint2 == true && way2distance > waypointThreshold && waiting == false){
	     myTransform.LookAt(waypoint2.position);
	     myTransform.Translate(patrolspeed * Vector3.forward * Time.deltaTime);
	     animation[walk.name].speed = walk_anim_speed;
         animation.Play(walk.name);
     }
	else if (nextwaypoint3 == true && way3distance > waypointThreshold && waiting == false){
	     myTransform.LookAt(waypoint3.position);
	     myTransform.Translate(patrolspeed * Vector3.forward * Time.deltaTime);
	     animation[walk.name].speed = walk_anim_speed;
         animation.Play(walk.name);
     }
     
	else if (nextwaypoint4 == true && way4distance > waypointThreshold && waiting == false){
	     myTransform.LookAt(waypoint4.position);
	     myTransform.Translate(patrolspeed * Vector3.forward * Time.deltaTime);
	     animation[walk.name].speed = walk_anim_speed;
         animation.Play(walk.name);
     }     
               

}
}

thanks to any that assist.

I was wondering if using Time.time would allow the delay and still enable his animation to run.

I am just saying this purely because it might help the questioner

All of what follows is purely my opinion.

It is true that about all I do all day is get drunk and write bad code to make things move around behaviourly - so when it comes to bad code and making things move around, you can trust me !

(A) you absolutely need to learn about and use state machines (which is little more than “an enumerator”) exactly as whydoidoit mentions

note that “state machines!” sounds really complicated but it amounts to about 2 lines of code

You simply cannot proceed - unless you want to write 1000s of lines of spaghetti - unless you practice making state machines. (recall: state machines are “enumerators”. not hard.)

(B) you should completely drop, forget about, and never use “yield” and “waitfor…”.

Those are system commands used for system programming at the lowest level. They have no connection, at all, to making a fun little video game which is cake. They are IMO utterly, completely, totally, 1000% wrong. They are irrelevant to the task at hand. They are low-level systems commands with no connection - at all - to making a little video game. It would be as if you were fooling with printer drivers or something. Heh!! So forget that.

How I would proceed is like this – again this is JUST ME…

I am incredibly stupid and can barely read so I only do things the “very easy way”…

here’s the “very easy way” …

(1) write a script of 5 or 6 lines that you attach to the actor (your car or whatever it is). call that script “behaveThisWay”.

(I often call them “walkThisWay” because I like Classic Rock. But “behave This Way” is less confusing, because, what the script will do is make the actor Behave Some Way. You can see that “Walk This Way” is just kind of a joke - it might not actually involve walking, but rather teleporting, zapping donuts or whatever. So in summary … call it “BehaveThisWay,” or, something similar in your favourite language.)

(2) in that script have an enumerator.

nobody despises computer languages more than me but you are going to have to learn how to use enumerators. pls note that it is one line of code.

I must reiterate (joke) that you are going to have to learn how to use the enumerator syntax.

(3) so in the script just switch and have him behave however you want for the various Enumerated thingies.

I haven’t remember the syntax for “switch” statements and I’m not going to in the few years remaining before my death, but in pseudocode it will be somethin glike

if enumeration == walking randomly like idiot

write some code to make him walk randomly like idiot

if enumeration == fuelling up

write some code to make him run a fuelling animation and play music

if enumeration == walking towards a Transform

write some code to make him walk towards that transform

and so on.

Finally - we’ll you’re done. There is no “finally”. its al that easy.

In the rest of your game just “command him to do what you want”. eg set the enumerator (“state machine!”) to “walk like idiot” or whatever

Finally just use Invoke (or whatever in your favourite programming language) to make him do stuff.

99.9999% of all video game code is just lists of Invoke commands.

so if you want him to fuel up it is something like

invoke 0.1  behavior = screeh to stop
invoke 0.1 pay screech SFX
invoke 0.5 behaviour == fuelling up
invoke 0.5 play glug glug sound effects
invoke 2.5 play fuel sloshing on to ground SFX
invoke 2.7 play ding ding ding SFX
invoke 3,1 behaviour = floating to air
invoke 3.4 play afterburners SFX
invoke 3.4 play earthquake screen effects
invoke 3.8 behaviour = seek to current waypoint

and so on

You don’t have to play guitar like Brian May to do this. Video games are easy - have fun!

if this is of no help to you, just cheerfully ignore it.


#aside
.
personally I can’t handle switch statements any time early in the morning, like before Thursday.

So I personally very simply just write “please do this” functions. Of course, it amounts to exactly the same thing.

Say you had a bullet. I’d write four functions,

pleaeseNowRelaxOffscreen()
pleaseNowFlyThroughAir()
pleaseNowExplodeAndThenBounceAroundCrazyStyle()
pleaseDoWhackyZumbaDancingRoutine()

Incredibly simply, all the other code just calls those at the right time. eg user presses trigger, someBullet.pleaseNowFlyThroughAir(). the bullet hits the clown’s crash helmet, bullet[4].pleaseNowExplodeAndThenBounceAroundCrazyStyle(). And so on.

You can see this is effectively, well it is, a state machine. (There’s a stupid hair-splitting comp-sci term for the difference in the two approaches, but nobody cares.)

So, do that if you like.

Following your advice I took out the yield waitforseconds and modified the script using invoke. I was running into the same bug, and after some searching I found a conflict in another part of my script that was causing the animation error.

I now see the benefits of Invoke, I’m sure I’m not using it in a manner Fattie would prefer, but I now have another tool in my arsenal. so thank you all.

Here’s a small snippet of the modded code:

function Update(){

if (waiting == true){

      animation.Play(waitidle.name);

}

}


function patrolstate () {

if(patrol == true && nextwaypoint1 == true && way1canwait == true && way1distance <= waypointThreshold){

      patrolspeed = 0;
      animation.Stop(walk.name);
      animation.Play(waitidle.name);
      waiting = true;
      if (waiting == true){
      	Invoke( "waypointIdle", waypointDelayTime );
      	animation.Play(waitidle.name);
      }      
      }

function waypointIdle () {

var way1distance = (waypoint1.position - myTransform.position).magnitude;

var way2distance = (waypoint2.position - myTransform.position).magnitude;

var way3distance = (waypoint3.position - myTransform.position).magnitude;

var way4distance = (waypoint4.position - myTransform.position).magnitude;
      
if(patrol == true && nextwaypoint1 == true && way1canwait == true && way1distance <= waypointThreshold){

	  waiting = false;
      patrolspeed = patrolspeedreset;
      nextwaypoint1 = false;
      nextwaypoint2 = true;
      nextwaypoint3 = false;
      nextwaypoint4 = false;
      //return;
      }

My script now works as it should, my next step will be implimenting the Arrays for the waypoints to give the game designer more options.