- Home /
Coroutine Scale goes past maxSize, but still keeps scaling.
Hey there guys, I'm having a bit of trouble with Coroutines, first the object wouldnt scale, but that issue has since been rectified, but now Im on the issue of the scaling not stopping.
I have provided a Video to better help toward a Correct Answer.
This is the C# Script I am currently using.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class growingScript : MonoBehaviour {
public bool growing = true;
public bool isGrown = false;
public bool fertAdded = false;
ParticleSystem fertParts;
Transform dirt;
public float growFactor = 0.1f;
public float startGrow;
public float fertMult;
public float maxSize = 10.0f;
void Start()
{
dirt = gameObject.transform.parent;
fertAdded = dirt.GetComponent<plantingScript>().fertAdded;
startGrow = growFactor;
fertMult = startGrow * 2;
StartCoroutine(Scale());
}
void Update()
{
fertAdded = dirt.GetComponent<plantingScript>().fertAdded;
}
public IEnumerator Scale()
{
while (growing)
{
while (maxSize > transform.localScale.x)
{
while (fertAdded)
{
growFactor = fertMult;
transform.localScale += new Vector3(1, 1, 1) * Time.deltaTime * growFactor;
yield return null;
}
while (!fertAdded)
{
growFactor = startGrow;
transform.localScale += new Vector3(1, 1, 1) * Time.deltaTime * growFactor;
yield return null;
}
yield return null;
}
while (maxSize < transform.localScale.x)
{
growing = false;
isGrown = true;
StopCoroutine(Scale());
gameObject.layer = LayerMask.NameToLayer("Plant");
yield return null;
}
}
}
}
Answer by Igor_Vasiak · Jun 07, 2017 at 11:13 AM
Here, this works: https://0bin.net/paste/9jtkauYd+3AbC33F#F5cJjF2EkFFF+aEFVmiWMfFkN7b2Kod+iTJsAgi4JeH
Your mistake was when you tried to set growing to false inside the while that uses a true growing. When you set it to false it stops the while BEFORE it can stop the couroutine, so that's why it isn't working. Plus, if you want your script to run at yours grandmother's PC then don't use GetComponent[s]() or Find() either inside Update(), LateUpdate() or FixedUpdate(). They are already updated at Start(). (I know this sounds weird, but it's true. Just play a bit with that, and then you'll find some approach that works).
Let me know if it works for you!
Thank you, i shall have a proper look into this in the morning, but the reason being the fertAdded is in update is due to fertilizer can be added at any time, weather it be before planting or while growing, so it needs to constantly be checking to see if fertilizer is added, but will FixedUpdate() work the way i need it to? i personally have never used LateUpdate or FixedUpdate.
I guess FixedUpdate does.
The only thing FixedUpdate() does differently from Update() or LateUpdate() is that it updates on a fixed time per frames, and consequently it’s the void witch updates more closely to the physics (Rigidbody, Colliders), being the best void to use when acting with movements on general. LateUpdate() runs just after Update() stops and just before the camera renders, so now you know the main difference between them.
Actually, it’s only up for you to decide, testing and simulating. And I’ll tell you something I just learned this week with @ShadyProductions.
Once you write something = GetComponent…
or something = Find…
you’re setting the PATH for the script to find the instance. So, if you GetComponent at Start() and the values changes at any point, the script WILL detect this change and WILL update the values stored on your something variable(witch is fertAdded, in your case), unless you destroy, for some unknown reason, the “dirt” you’ve called parent. Then, yes, you can check if fertAdded is equals to null, and then re-GetComponent at Update().
But always be careful, since this is a common trap, and I was inside the cage of this trap ‘till some days before. You don’t need to pay attention on this, but I’m just warning you.
I’m glad this variant of your script worked well for you.
Answer by Vojtasle · Jun 07, 2017 at 10:59 AM
if(fertAdded)
{
growFactor = fertMult;
transform.localScale += new Vector3(1, 1, 1) * Time.deltaTime * growFactor;
yield return null;
}
if(!fertAdded)
{
growFactor = startGrow;
transform.localScale += new Vector3(1, 1, 1) * Time.deltaTime * growFactor;
yield return null;
}
yield return null;
Use if statements instead of whiles. You ended up with infinite cycle because it was not able to get out of the while cycle
Not actually… If what you said was true, the name of the question would be: "Unity 5 crashing because of whiles when I hit play!”. But he is cancelling the first while before stopping the coroutine, and that’s the problem, according to my tests. Plus, his script could really be boosted if ifs were used ins$$anonymous$$d of whiles, which makes you… 70 percent right. ;-)