The question is answered, right answer was accepted
Boolean, IEnumerator and SetActive probleme.BUG
Hi, normally I always look in the forums before asking a question (it's even the first time I ask a question on this forum).
I have 2 scripts, the problem probably comes from the Shoot script because by removing the delay and the IEnumerator (and therefore the WaitForSecond) I can change side of my player and shoot as many times as I want to side but without delay so it pulls in Permanently, but when I put a delay (With a boolean and an IEnumerator) I can only change sides 3 times on each side and then I can not shoot anymore but only change sides. To change sides I use the SetActive function to do this.
Thanks to those who will help me because I do not understand the reason for this problem!
Player script+hierarchy+inspector;
//Change side player shoot
[SerializeField] int SelectedArm = 1;
[SerializeField] int SelectedArmLeft = 1;
[SerializeField] int SelectedArmRight = 2;
public GameObject left;
public GameObject right;
void Start()
{
right.SetActive(false);
}
void FixedUpdate()
{
//Change side
Side();
}
void Side()
{
//Change side of boat
if (Input.GetKeyDown(KeyCode.E))
{
SelectedArm += 1;
if (SelectedArm == SelectedArmLeft)
{
left.SetActive(true); right.SetActive(false);
}
if (SelectedArm == SelectedArmRight)
{
left.SetActive(false); right.SetActive(true);
}
if (SelectedArm > SelectedArmRight)
{
SelectedArm = SelectedArmLeft; left.SetActive(true); right.SetActive(false);
}
}
}
Shoot script+hierarchy+inspector;
public Rigidbody rgBullet;
public float impulseForce = 85;
public float timeBetweenShoot = 0.8f;
public bool canShoot = true;
Transform spawn;
void Start()
{
spawn = GetComponentInChildren<Transform>(); //Transform of canon child
}
void FixedUpdate()
{
if (canShoot == true)
{
StartCoroutine(Shoot());
}
}
public IEnumerator Shoot()
{
if (Input.GetKey(KeyCode.Space))
{
Rigidbody bulletInstance;
bulletInstance = Instantiate(rgBullet, spawn.position, spawn.rotation) as Rigidbody;
bulletInstance.AddForce(spawn.forward * impulseForce, ForceMode.Impulse);
canShoot = false;
yield return new WaitForSeconds(timeBetweenShoot); // wait 0.8 second befor next shoot
canShoot = true;
}
}
I hope the solution is not simple because I will be an idiot ^^
Answer by DawidNorasDev · Jun 19, 2018 at 03:14 PM
This code have many flows. 1. Don't do logic in FixedUpdate. Especially don't check there for Input. 2. Do not call coroutines in update just to check in them if there was an input 3. Note: Coroutines cannot run on disabled objects. Maybe you disable object, than coroutine wants to return and click "canShoot" to true, but it cannot, because object is disabled.
[SerializeField] int SelectedArm = 1;
[SerializeField] int SelectedArmLeft = 1;
[SerializeField] int SelectedArmRight = 2;
Check out enums to get rid of this code with increments. It really doesn't help understand what is going on
Solution: You can try not to disable object, but to change public bool isNowShooting
on them. And than in Update check for it. That way, you never disable it, and coroutine can finish.
Thank you for the answer, I try that and I tell you if it works.
Answer by PourRine · Jun 19, 2018 at 03:47 PM
Thanks a lot I understand better now why it does not work before, it works great thanks :)
Follow this Question
Related Questions
I'd like my object to be active only when space key is NOT pressed 1 Answer
How can I use "animator.SetTrigger()" if "animator.SetBool()" has been true for X amount of seconds? 0 Answers
How to erase message after 3 seconds 1 Answer
My Coroutine Ignores the Boolean 1 Answer
Get Time A Bool Has Been True 4 Answers