How can I pass parameters into IEnumerator method?
I am trying to pass Ray
as a parameter of IEnumerator
method, but it doesn't change passed object. I would be grateful if someone explain to me why. I thought if variable is reference type it should be changed wherever it is called.
public class Rays : MonoBehaviour
{
private Ray rayR;
private Ray rayL;
void Start()
{
rayR = new Ray(transform.position + new Vector3(0, -0.8f, 0), transform.up);
rayL = new Ray(transform.position + new Vector3(0, -0.8f, 0), transform.up);
}
void Update()
{
Debug.DrawRay(rayR.origin, rayR.direction * 2, Color.blue);
Debug.DrawRay(rayL.origin, rayL.direction * 2, Color.blue);
if (Input.GetKeyDown(KeyCode.D))
{
rayR.direction = transform.forward;
StartCoroutine(RayBack(rayR));
}
else if (Input.GetKeyDown(KeyCode.A))
{
rayL.direction = -transform.forward;
StartCoroutine(RayBack(rayL));
}
if (Physics.Raycast(rayR,2))
{
RotateCylinder.rotateRight = false;
}
if (Physics.Raycast(rayL, 2))
{
RotateCylinder.rotateRight = true;
}
}
IEnumerator RayBack(Ray ray)
{
yield return new WaitForSeconds(1);
Debug.Log("kdv");
ray.direction = transform.up;
rayR.direction = transform.up;
}
}
Ray
is a struct
and structs are passed by copy. This means that ray.direction = transform.up;
modifies a copy (to no consequence outside of this method scope) meanwhile rayR.direction = transform.up;
does something opposite - it modifies a struct that is allocated in memory inside this Rays
class.
@andrew-lukasik , thank you . I just thought that Ray is class therefore reference type . Sorry for disturbing . But how can I pass parameter to IEnumerator be reference , because when I put modifier "ref" it gives an error?
Struct must be contained in some kind of memory allocation object to pass it here. But you can do something different and use System.Action
parameter with inlined method (lambda expression)
StartCoroutine( ExecuteAfterDelay( () => rayR.direction = transform.up , 1f ) );
IEnumerator ExecuteAfterDelay ( System.Action action , float seconds )
{
yield return new WaitForSeconds(seconds);
action();
}
Don't overuse it tho. Lambda expressions often allocate garbage memory + has "gotchas" of their own (struct variable capture, boxing, etc.).
Your answer
Follow this Question
Related Questions
Any Way to Improve These Scripts or Increase Game Performance? 0 Answers
Unity Editor can't find IEnumerated 2 Answers
How can i change the value of a variable from an IEnumerator 0 Answers
How can i WaitForSeconds after destroying GameObject to load the next Scene? 0 Answers
IEnumerator, Unexpected symbol? 3 Answers