rect lerp coroutine

Hey guys, I wrote this function to lerp rects for GUI animation.

public static IEnumerator RectLerp(Rect rectToChange, Rect final, float travelTime){
		Debug.Log(rectToChange);
		if (RectLerping || rectToChange == final) yield break;
		RectLerping = true;
		float timer = 0.0f;
		Vector4 start = new Vector4(rectToChange.x, rectToChange.y, rectToChange.width, rectToChange.height);
		Vector4 end = new Vector4(final.x, final.y, final.width, final.height);
		while (timer <= 1.0f){
			float t = Mathf.Sin((timer*2-1) * Mathf.PI / 2.0f)/2 + 0.5f;

			Vector4 newVec = Vector4.Lerp(start, end, t);
			rectToChange = new Rect(newVec.x, newVec.y, newVec.z, newVec.w);
			timer += Time.deltaTime / travelTime;
			yield return null;
		}
		rectToChange = final;
		RectLerping = false;
		Debug.Log(rectToChange);
	}

I called it like

void Start(){
		cardRect = new Rect(0, Screen.width * 145f/1920, Screen.width * 7/18 * 1/2, Screen.width* 5/18 * 1/2);
}
    void Update(){
    		if (Input.GetKeyUp(KeyCode.M)){
    			StartCoroutine(Lerp.RectLerp(cardRect, new Rect(0, Screen.width * 145f/1920, Screen.width * 7/18, Screen.width* 5/18), 1f));
    		}
    }
    
    void OnGUI(){
    		GUI.DrawTexture(cardRect, hoverTexture);
    }

Well, according to the debug statements, the coroutine works perfectly. But the cardRect variable never gets updated, so the texture is the same size as original.

What am I doing wrong here?

1 Answer

1

Rect is a value type and not a reference type. This means that any changes made to the Rect will be local.

Instead of modifying the local Rect, try assigning to a member variable.

I don't get it. If I input cardRect as the rectToChange argument, they should reference the same memory and therefore change both, right? I did the same thing with Quaternion rotation and Vector3 translation, except I input the transform instead of the rotation/position and that worked just fine. Or in order for it to work that way, would I have to change each attribute (x, y, width, height) separately instead of using the new keyword? edit nevermind, just tried that, didn't work. edit cardRect is a member variable that I pass into the function.

@ProtoTerminator - research the difference between variables that are stored by value and ones that are stored by reference. Research the 'out' and 'ref' keyworks in C#. A rect is a struct that is stored by value.

I already tried out, but iterators do not allow it.

So since I cannot reference the rect and I cannot use the out keyword, how can I update the rect?

You'll need to have a member variable on the class. For example: private Rect m_RectToChange; And change that instead of using a parameter.