- Home /
Script not changing a public variable of another's game object script
This is a simple script of a game object that colides with something:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColisaoNoPe : MonoBehaviour
{
public GameObject alvo;
// Start is called before the first frame update
private void Start()
{
}
// Update is called once per frame
private void Update()
{
}
private void OnTriggerEnter2D(Collider2D other)
{
print("ColisaoNoPe collision with " + other);
if (other.gameObject.CompareTag("piso"))
{
alvo.GetComponent<MovLinear>().piso = true;
print("ColisaoNoPe piso -> true");
}
//alvo.GetComponent<MovLinear>().ColisaoNoPe(other, true);
}
private void OnTriggerExit2D(Collider2D other)
{
//if (other.gameObject.CompareTag("piso")) alvo.GetComponent<MovLinear>().piso = false;
//alvo.GetComponent<MovLinear>().ColisaoNoPe(other, false);
}
}
The script 'MovLinear' in 'alvo' has the boolean variable 'piso' declared as public and set to false in the Start function. There is a print in a fixed update to see the 'piso' state, the result is always false.
I also tried to make a public function that changes a private variable, however what happens is the 'piso' variable only changes inside the scope of the function, so will remains unchanged for the rest of the script. It seems a new bool piso is auto-created inside a function, this is bizarre to me, though I am not understanding how the scope of variables works in C#...
Answer by cs120319992 · May 29, 2019 at 10:50 AM
// attach this script to object in hierarchy (example: FirstObject)
public class FirstScript : Monobehaviour {
public bool myBool = true;
}
// attach this script to object in hierarchy
public class SecondScript : Monobehaviour {
public FirstScript firstScript; // add in this field object with script FirstObject
public void Change() {
firstScript.myBool = false;
}
}
It works! $$anonymous$$y $$anonymous$$d look at this script and send an error message because I have to drag an object to the script class FirstScript, but that's the way it works, so be it.
I celebrated too soon. It only works in this test. The bool var is set by OnTrigger event and when the class is instantiated inside the script, que object is not linked altogether, it seem just an instance, so what happens to the object does not reflect inside the script - two separated words. I tried the reverse approach, trying to get a boolean var inside the other script but the issue is the same. It is not possible at all to work like this, downvote for Unity on this!
// If i correctly understood, you instantiate object with script ColisaoNoPe
// If that is correct, then check code below
// The first script (This script connect to prefab), then you'll instantiate this prefab with connected script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ColisaoNoPe : $$anonymous$$onoBehaviour
{
public GameObject alvo;
private void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag("piso"))
alvo.GetComponent<$$anonymous$$ovLinear>().piso = true;
}
private void OnTriggerExit2D(Collider2D other)
{
if (other.gameObject.CompareTag("piso"))
alvo.GetComponent<$$anonymous$$ovLinear>().piso = false;
}
}
// The second script have boolean piso, when ColisaoNoPe appear OnTrigger, bool state piso must change
public class $$anonymous$$ovLinear : $$anonymous$$onobehaviour {
public bool piso;
private void Update() {
Debug.Log("Piso is: " + piso);
}
}
// The third script is the script which respawn and set references
public class Spawner() {
public $$anonymous$$ovLinear movLinear; // This is only object and connect it from hierarchy
public GameObject prefab; // This is prefab and connect it from resources
public void Spawn() {
// On spawn create new object
GameObject obj = Instantiate(prefab);
// Get attached script ColisaNoPe
ColisaoNoPe cnp = obj.GetComponent<ColisaoNoPe>();
// And set reference alvo to original moveLinear
cnp.alvo = movLinear.gameObject;
}
}
Like your script is showing, the problem was the way objects are instantiated in the scene. I still have difficulties to understand this "backward" procedure of creating prefabs (a class?) from an object that is already in the scene, plus one object is child of another, plus I'd migrate from 2018 to 1019 that seems different dealing with prefabs. So alvo can't have assigned a game object that is already in scene, must be an asset or prefab - but then, won't be the same anymore, so the public var won't be the same either. $$anonymous$$y solution is similar as you wrote, I am getting alvo on the fly by GameObject.Find at Start and than I will have the object that really matters!
Answer by gaggedegg · May 30, 2019 at 09:53 AM
@gustavopinent You can refer piso by using FindObjectOfType object
FindObjectOfType<Class_name_in_which_variable_is_declared>().piso = true;
Hope this helps :)
FindObjectOfType
will return the first active loaded object of Type Class_name_in_which_variable_is_declared
. If there are multiple instances of the component, you may not retrieve the correct one.
If there are multiple instances you can use list/arrays to store the instances and access directly from that.
Though your answer is a clue for a solution. I really prefer to pick the object on the fly, but the other method should work. I am probably misunderstanding the concepts of Unity but also I feel there is some bugs around the way objects are instantiated when I press play.