- Home /
fixing a variable value during coroutine
hello, i will briefly explain my situation: i have a script that:
gets the mouse position twice;
calculates the magnitude and the angle of the line between the two points;
istantiates a prefab at the first position
a coroutine that scales the prefab along the line (var lengthC)
the problem is that when i istantiate a new object before the scaling of the other object is complete, i suppose that the variable lengthC gets updated and the previous coroutine stops. is there a way to get around it? can i like call the variable inside the coroutine and while it is executing the variable will have a fixed value?
here is the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SpawnaCresci : MonoBehaviour
{
[SerializeField] GameObject myCube;
[SerializeField] float width = 1f;
[SerializeField] float height = 1f;
[SerializeField] Vector3 inputPosA = Vector3.zero;
[SerializeField] Vector3 inputPosB = Vector3.zero;
[SerializeField] Vector3 result;
[SerializeField] Vector3 avoidBehindCamera;
private GameObject thisCube;
private float lengthC;
[SerializeField] float growFactor = 0.1f;
// Use this for initialization
void Start()
{
avoidBehindCamera.z = 10f;
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
inputPosA = Camera.main.ScreenToWorldPoint(Input.mousePosition + avoidBehindCamera);
}
if (Input.GetMouseButtonUp(0))
{
inputPosB = Camera.main.ScreenToWorldPoint(Input.mousePosition + avoidBehindCamera);
SpawnAlongLine();
}
}
void SpawnAlongLine()
{
// Vector3 posC = ((inputPosB - inputPosA) * 0.5F) + inputPosA;
lengthC = (inputPosB - inputPosA).magnitude;
float sineC = (inputPosB.y - inputPosA.y) / lengthC;
float angleC = Mathf.Asin(sineC) * Mathf.Rad2Deg;
if (inputPosB.x < inputPosA.x) { angleC = 0 - angleC; }
Debug.Log("inputPosA" + inputPosA + " : inputPosB" + inputPosB + /*" : posC" + posC + */" : lengthC " + lengthC + " : sineC " + sineC + " : angleC " + angleC);
thisCube = Object.Instantiate(myCube, inputPosA, Quaternion.identity);
thisCube.transform.rotation = Quaternion.Euler(0, 0, angleC);
thisCube.transform.parent = null;
StartCoroutine(Scale());
}
IEnumerator Scale()
{
float timer = 0;
while (lengthC > thisCube.transform.localScale.x)
{
timer = Time.deltaTime;
thisCube.transform.localScale += new Vector3(1, 0, 0) * timer * growFactor ;
thisCube.transform.localPosition += thisCube.transform.right * timer * growFactor * 0.5f;
yield return null;
}
}
}
Answer by Casiell · Sep 03, 2018 at 10:30 AM
You can pass the value as a paramether to your coroutine. Or create local variable inside the coroutine and assign the value from lengthC at the beginning.
First solution is better in this case
sorry, i'm a total noob and i have never used coroutines on my own before; isn't this the way to pass a parameter?
StartCoroutine(Scale(lengthC));
}
IEnumerator Scale(float lengthC)
{
float timer = 0;
while (lengthC > thisCube.transform.localScale.x)
{
timer = Time.deltaTime;
thisCube.transform.localScale += new Vector3(1, 0, 0) * timer * growFactor ;
thisCube.transform.localPosition += thisCube.transform.right * timer * growFactor * 0.5f;
yield return null;
}
}
because it is not working :(
i have also noticed that the velocity of the transform builds up if the previous coroutine has not yet finished! :(