- Home /
C# taking variable from other script
Hello, I started using unity few weeks ago and now I have a problem with taking variable from another script. Once I pickup object "Cherry" in-game my variable "knivedelay" should increase, however i have tried doing it but it did not update, can someone help me. I have tried doing it with game objects but it did not work. Thanks in advance. Spawning.cs :
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
public class Spawning : MonoBehaviour {
public float coindelay = 1f;
public float knivedelay = 4f;
public GameObject knive;
public GameObject coin;
// Use this for initialization
void Start () {
InvokeRepeating("CoinSpawn", coindelay, coindelay);
InvokeRepeating("KniveSpawn", knivedelay, knivedelay);
print(coindelay);
}
//Prefabs spawning
void CoinSpawn () {
Instantiate(coin, new Vector3(Random.Range(-10,10), 12, 0), Quaternion.identity);
}
void KniveSpawn()
{
Instantiate(knive, new Vector3(Random.Range(-10, 10), 12, 0), Quaternion.identity);
}
}
CherryPickUp.cs :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class CherryPickUp : MonoBehaviour
{
public static bool isCherry = false;
public static float cherryScore = 0.0f;
// Update is called once per frame
void OnTriggerEnter2D(Collider2D other)
{
if (other.tag == "Player")
{
isCherry = true;
Destroy(gameObject);
cherryScore += 10;
GameObject.Find("TheCherry").GetComponent<Spawning>().knivedelay -= 0.5f;
/*for (int i = 0; i < n; i++)
{
Spawning.coindelay = Spawning.coindelay + 10f;
Debug.Log(Spawning.coindelay);
}
}
else {
isCherry = false;
}
Debug.Log(isCherry);
/* while (true)
{
if (isCherry == true)
{
Spawning.coindelay = Spawning.coindelay + 5f;
}
}
/*while (isCherry == true)
{
Spawning.coindelay += 5f;
}*/
}
}
}
Answer by JonPQ · Dec 18, 2018 at 09:23 PM
your problem is here.... GameObject.Find("TheCherry").GetComponent().knivedelay -= 0.5f;
For this to work, there must be object named "TheCherry" with component Spawning on that object (not on a parent or child object) This is also hard to debug or step through one line at a time to see what is wrong. It is also very,very slow to execute.... really avoid using GameObject.Find and avoid using GetComponent
Try to only use them during the Start() and Awake() functions, so they are used on setup only, and not all of the time. Even better if you expose public variables and setup the references to the other components on a prefab (if possible)
split that line into 3 lines with intermediate, temporary variables, and it will be easy to debug to see which step is failing. GameObject obj = GameObject.Find("TheCherry"); if(obj !=null) Spawning spwn = obj.GetComponent() else Debug.Log( "cant find TheCherry"); etc...
Answer by Hellium · Dec 18, 2018 at 09:28 PM
Supposing you don't get any NullReferenceException
, once InvokeRepeating
is called, even if you change the parameter of the delay, it won't be taken into account. You need to use a coroutine instead
public class Spawning : MonoBehaviour {
public float coindelay = 1f;
public float knivedelay = 4f;
public GameObject knive;
public GameObject coin;
// Use this for initialization
void Start ()
{
StartCoroutine( SpawnCoins() );
StartCoroutine( SpwanKnives() );
}
//Prefabs spawning
IEnumerator SpawnCoins ()
{
while( coindelay > Mathf.Epsilon )
{
yield return new WaitForSeconds( coindelay );
Instantiate(coin, new Vector3(Random.Range(-10,10), 12, 0), Quaternion.identity);
}
}
IEnumerator SpwanKnives()
{
while( knivedelay > Mathf.Epsilon )
{
yield return new WaitForSeconds( knivedelay );
Instantiate(knive, new Vector3(Random.Range(-10, 10), 12, 0), Quaternion.identity);
}
}
}