- Home /
IEnumerator coroutines crashing app when launched with datatyle "GameObject" passed in
Hi guys,
I have a game where there is a claw that is supposed to open and close its claws when a particular button is tapped (which posts a notification). The following is the code from CraneBehavior.cs that launches the relevant coroutines:
void OpenClaw()
{
StartCoroutine("OpenClaw", craneClaw1);
StartCoroutine("OpenClaw", craneClaw2);
StartCoroutine("OpenClaw", craneClaw3);
StartCoroutine("OpenClaw", craneClaw4);
}
void CloseClaw()
{
StartCoroutine("CloseClaw", craneClaw1);
StartCoroutine("CloseClaw", craneClaw2);
StartCoroutine("CloseClaw", craneClaw3);
StartCoroutine("CloseClaw", craneClaw4);
}
IEnumerator OpenClaw (GameObject claw)
{
Vector3 angles = transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle + 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = Mathf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
transform.eulerAngles = angles;
yield return null;
}
}
IEnumerator CloseClaw (GameObject claw)
{
Vector3 angles = transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle - 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = Mathf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
transform.eulerAngles = angles;
yield return null;
}
}
OpenClaw() and CloseClaw(), which start coroutines that open and close the claw, cause the app to crash when called (When testing the app in the editor, the editor/player freezes without even printing an error. When built to my phone, it gets a bad notification in Xcode). I suspect that the crashes are being caused by the coroutine code, since this problem was nonexistent when TogglePlayMode was present but did not call the relevant coroutines to open and close the claw. Both OpenClaw() and CloseClaw() are called in the following bit of code in the same file. It responds to a notification posted to the wiki's NotificationCenter.cs shared notification center:
void TogglePlayMode()
{
// This opens and closes the claw
if (clawOpen)
{
clawOpen = false;
// TODO: Close the claw by sending a rotate message
CloseClaw();
}
else
{
clawOpen = true;
// TODO: Open the claw by sending a rotate message
OpenClaw();
}
}
What is wrong with my coroutine implementation, if my hypothesis is correct?
MachCUBED
The editor freezing is definitely somewhere in your while() code logic, sorry i can't be more specific.
The funny thing is that the exact same while loop works ok in a different script called TapRotationLogic.cs:
public class TapRotationLogic : $$anonymous$$onoBehaviour {
void OnTap ()
{
StartCoroutine("RotateGameObject", 1.0f);
}
IEnumerator RotateGameObject (float duration)
{
Debug.Log("Tapped to rotate");
Vector3 angles = transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle + 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = $$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
transform.eulerAngles = angles;
yield return null;
}
}
}
In my CraneBehavior.cs script, the value "duration" is a class member declared like so:
public float duration = 0.5f;
All instances of crane (the GameObject with CraneBehavior.cs attached to it) have the same duration of 0.5 sec. I can't see how specifying my duration value like that can cause things to crash.
Answer by Bunny83 · Feb 21, 2013 at 02:08 PM
I'm pretty sure that your problem comes from the combination of those points:
using the string version of StartCoroutine
Having two functions named "OpenClaw"
Starting OpenClaw inside OpenClaw.
I strongly recommend to use a different name for the coroutine. Also it's better for performance to start the coroutine like this:
StartCoroutine(OpenClaw(craneClaw1));
This would already fix your problem i guess.
You're correct: the na$$anonymous$$g conflict was the cause.
Fixed code (will change the form of StartCoroutine later):
void OpenClaw()
{
StartCoroutine("OpenClawEnum", craneClaw1);
StartCoroutine("OpenClawEnum", craneClaw2);
StartCoroutine("OpenClawEnum", craneClaw3);
StartCoroutine("OpenClawEnum", craneClaw4);
}
void CloseClaw()
{
StartCoroutine("CloseClawEnum", craneClaw1);
StartCoroutine("CloseClawEnum", craneClaw2);
StartCoroutine("CloseClawEnum", craneClaw3);
StartCoroutine("CloseClawEnum", craneClaw4);
}
IEnumerator OpenClawEnum (GameObject claw)
{
Vector3 angles = claw.transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle + 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = $$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
claw.transform.eulerAngles = angles;
yield return null;
}
}
IEnumerator CloseClawEnum (GameObject claw)
{
Vector3 angles = claw.transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle - 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = $$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
claw.transform.eulerAngles = angles;
yield return null;
}
}
Answer by liamcary · Feb 21, 2013 at 12:38 PM
I didn't think this would cause it to crash, but it looks like you're just modifying the eulerangles of whatever transform the CraneBehavious script is attached to. You pass the claw objects into the Open and Close coroutines but never reference them. "transform.eulerAngles" accesses the transform that the script is attached to. To rotate the claws you need "claw.transform.eulerAngles".
I haven't checked if this fixes the crash, but the rest of the script seems legit.
Using your suggestion (which, as you said, should rotate the claws) to make the following code didn't solve the crashing bug. Here is the new code:
IEnumerator OpenClaw (GameObject claw)
{
Vector3 angles = claw.transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle + 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = $$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
claw.transform.eulerAngles = angles;
yield return null;
}
}
IEnumerator CloseClaw (GameObject claw)
{
Vector3 angles = claw.transform.eulerAngles;
float startTime = Time.time;
float startAngle = angles.y;
float endAngle = startAngle - 45; // -45 for left turn
while(duration >= Time.time - startTime)
{
angles.y = $$anonymous$$athf.LerpAngle(startAngle,endAngle,(Time.time - startTime) / duration);
claw.transform.eulerAngles = angles;
yield return null;
}
}
Your answer
Follow this Question
Related Questions
What is way to flash the screen WITHOUT using a Texture? 2 Answers
Melee-hits being recognized too often 1 Answer
I'm having trouble with Coroutines.. 2 Answers
Unity Editor Crashes On Play Because of Import Script 1 Answer
c# Using an IEnumerator yield WaitForSeconds to temporarily pause a While loop 3 Answers