- Home /
Coroutine not starting properly with enemy patrol script
Hello,
I have been trying to get this patrol sequence on the enemy to work as intended for the past 48 hours but with no luck.
What I have reached so far is that the code runs well and the enemy patrols left and right as expected, however the StartCoroutine(TakeSkull()); doesn't run whatever I do. I even changed it to Invoke("TakeSkull", 0.3f) and changed it into a function and it didn't work.
All I want to achieve is that the enemy moves to a waypoint, change animation to taking the skull, once finished change animation to throwing the skull, a skull is created to do so and then moves to the other waypoint to do the same exact process.
To control the animation of the enemy I have a blend tree with x =1 y = 0 for moving in the direction. x= 0 and y = 0 for taking the skull and x = -1 and y = 0 for throwing it.
Here is the code: Code
Anyone can shed some light or direct me to the correct method of doing this please? I'd really appreciate it. Sorry I am still a beginner when it comes to coding.
Answer by Fredex8 · Mar 28, 2016 at 10:10 AM
Stick a debug in at the start of NormalPatrol()
and see how often it is actually getting called.
if (hp > hp / 2)
{
NormalPatrol();
}
It's going to be starting that function every frame that the health is more than half and if if (transform.position != currentWaypoint)
is false it is going to try and start simultaneous coroutines that may clash with each other. I'd use a boolean to make sure that function is only ever going to run once at a time:
if (hp > hp / 2)
{
if (patrolling == false)
{
patrolling = true;
NormalPatrol();
}
}
Then set patrolling = false;
at the end of NormalPatrol.
I'd also call StartCoroutine(ThrowSkulls())
; from within TakeSkulls()
so you know that ThrowSkulls is only going to happen once the boss has actually taken the skulls.
IEnumerator TakeSkulls()
{
gameObject.GetComponent<Animator>().SetFloat("x", 0);
yield return new WaitForSeconds(0.3f);
StartCoroutine(ThrowSkulls());
}
I see, thanks a lot for the tips, I am going to use it as you've mentioned. One thing though that I don't understand at all...
How come I call the coroutine from inside the coroutine?
The way I understand it is like a function (but with wait time) so if I don't call the function somewhere in the Unity methods it won't work?
What I mean is, let's say we have a function:
int Addition(int x, int y)
{
return x + y;
}
The above will never be called if it is put like that, I have to go to Start() or Update() or any of these methods to call it Addition (1, 2); right? Or my understanding of coroutine is flawed? It is at least what I got from Unity's video about it.
Calling StartCoroutine from inside another coroutine is fine.
On a separate note though, I feel I should point out that if (hp > hp/2)
will always be true unless hp is a negative value or zero. Did you mean to use separate values like if (hp > maxHp/2)
?
Answer by Bunny83 · Mar 28, 2016 at 02:56 PM
You have several logic errors in your code:
First of all most of your "hp" conditions are pointless. Things like
(hp > hp / 2)
is always true as long as hp is greater than 0. A value "a" is always greater than half of that value. For example 100 is greater than 50(==100/2) so is 4 greater than 2(==4/2). All those conditions are almost like constants. You might want to compare to the enemys max health.Next thing is you can only wait inside of Coroutines. When you start a coroutine the StartCoroutine call will return immediately without waiting. It just starts the coroutine which will run independently from the code that started the coroutine. Your "WaitTime" coroutine is pretty pointless since nothing happens inside that coroutine. If you have some code / steps you want to run in sequence with a pause in between, that code has to be inside a coroutine. A coroutine, once started, is managed by Unity. It runs on the MonoBehaviour that was used to start it. A coroutine has nothing to do with a normal method. It's something completely different. When you invoke your coroutine, it actually creates a statemachine object which you usually pass to StartCoroutine. Unity will store that statemachine object internally and go through it's "states" automatically.
Thank you very much for your explanation, I can't believe I feel in these traps with the conditions. I also see what do you mean with Coroutines, although when I have code inside (which was the case before as you can see from the commented logic), it didn't feel like there was a wait time. I tried using the same time values as the one in animation clip but it won't work.
I'll try again using all code in Coroutine including the Invoke and see what happens. Thanks a lot for the advice :)
Your answer
![](https://koobas.hobune.stream/wayback/20220612073440im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
Issue involving coroutines and animation 0 Answers
How do I stop moving when attacking? 1 Answer
Coroutine mystery (for a noob) 1 Answer