I am taking an object (shotObject) and using a coroutine to loop through some colors/alphas to make it look like its disappearing. Once the alpha is 0, I want to setActive to false. When I test my code, the object disapears immediately but I can see my debug messages in the console showing that the color changes are happening. I have googled and read the unity docs and watched the unity video on this.
Here’s the code:
private void CheckForEnemy()
{
if (_raycastManager.GetCurrentFoundObject() != null)
{
shotObject = _raycastManager.GetCurrentFoundObject().transform.root.gameObject;
if (shotObject.tag == "Enemy")
{
DestroyEnemy();
}
}
}
private void DestroyEnemy()
{
shotObject.GetComponent<NavMeshAgent>().speed = 0;
shotObject.GetComponent<DroneActions>().IsShooting = false;
StartCoroutine(FadeEffect());
}
private IEnumerator FadeEffect()
{
Renderer[] components = shotObject.GetComponentsInChildren<Renderer>();
foreach (Renderer r in components)
{
r.material.mainTexture = null;
}
foreach (Color c in destructionColors)
{
foreach (Renderer r in components)
{
r.material.color = c;
Debug.Log("Fading out drone to color: " + c);
}
yield return new WaitForSeconds(waitBetweenColors);
}
yield return new WaitForSeconds(1f);
shotObject.SetActive(false);
}
I don’t want to place SetActive in my fadeEffect method (it shouldn’t go there). But, from what I understand of the unity docs/video, this version should work. Help please, thanks!
Try to add a boolean to check for coroutine entry and exit based on it’s value of true/false, and also check if you’re creating multiple Coroutines for the same object, that might have some weird effect. I still see it flowing properly, the logic doesn’t appear off, but the code doesn’t tell me on which monobehaviours they stay.
If possible, try to put the FadeEffect under the fading Enemy so never more than one coroutine is created, and disable the collider on entry.
Does Debug.Log("Fading out drone to color: " + c); actually appear in the logs, and does it respect the timing set by yield return new WaitForSeconds(waitBetweenColors); ?
Set waitBetweenColors to a large value ~3-4-5 seconds, see what happens.
Also I will guess there should be no chance that no renderers or colors are present.
Try adding a yield return null at the end of the IEnumerator. I’m not sure but I think it causes an issue if your return options in the enumeration are all under conditions with no default
The last console message is:
Fading out drone to color: RGBA(0.000, 0.000, 0.000, 0.000)
UnityEngine.Debug:Log(Object)
c__Iterator0:MoveNext() (at Assets/Scripts/GameManager.cs:110)
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
I get a message for each color change prior as well and each pops up at the right time (roughly 1 1/2 seconds each). I changed the waitForColors to 5 and the messages popped up slowly. With the new WaitForSeconds at the end, the object still disappears immediately.
Updated code:
private void DestroyEnemy()
{
_hasFaded = false;
shotObject.GetComponent<NavMeshAgent>().speed = 0;
shotObject.GetComponent<DroneActions>().IsShooting = false;
StartCoroutine(FadeEffect());
if (_hasFaded)
{
shotObject.SetActive(false);
}
}
private IEnumerator FadeEffect()
{
Renderer[] components = shotObject.GetComponentsInChildren<Renderer>();
foreach (Renderer r in components)
{
r.material.mainTexture = null;
}
foreach (Color c in destructionColors)
{
foreach (Renderer r in components)
{
r.material.color = c;
Debug.Log("Fading out drone to color: " + c);
}
yield return new WaitForSeconds(waitBetweenColors);
}
_hasFaded = true;
yield return new WaitForSeconds(waitBeforeDestroy);
}
I figured out the issue. In Update() in another class, I was checking the navMesh agent speed as one requirement for returning the object to the pool (if speed >= 0). When the object was shot by the player, I changed the speed to 0 and thus causing it to be returned to the pool (set active to false) immediately. I changed my code a bit and now you can see the object fade out as I wanted.
Talk about getting trolled by your own code. Happens to everyone. Try to keep your actions to objects standardized, such as set active in a single place, so you can check what calls that function!
Happy coding.