- Home /
Problems with variables across scripts
First and foremost, thank you for reading this question. I have already viewed the "Accessing variables across scripts" Official YOUTUBE Video many many times. I have also read many questions and answers on this forum hoping to glean some information that may help. Still having problems, you all are my last hope.
I think I may not be understanding some of the relationships involved between classes.
HERE are SCREENSHOTS of my Editor/Inspector proving that my PREFABS should be linked properly:
LOGIC:
Fist I set GameController as static. I understand this allows it to have global variables that other classes can access and modify.
Then, I generate 6 different spheres with different colors.
Then, the game increases the Z position for each cloned sphere, until >4, then it switches the direction so the spheres are supposed to come back. (Z position declination)
And while the Spheres, do correctly Instantiate() on the screen, and move forward on the Z axis.....
THE PROBLEM:
is that the spheres continue on the +Z axis forever. They never switch and come back
In GameController script, the print function for refscript.tempVector always prints "0,0,0"
It's as if Gamecontroller never received the appropriate value.
GameController.cs
sing UnityEngine; using System.Collections;
public class GameController : MonoBehaviour {
public static GameController controller; // Allows this script to store the base values and this is now the holder if such values.
//Loading Script use
public Material greenMaterial;
public Material blueMaterial;
public Material whiteMaterial;
public Material redMaterial;
public Material pinkMaterial;
public Material yellowMaterial;
public float speedInterval;
// For referencing the vales on ObjectBehavior.cs
public GameObject objectContainingScript; // PUBLICVAR (its a GameObject) (insert in the editor which object contains the script)
// GENERAL DEFINITIONS (HIDDEN IN INSPECTOR)
[HideInInspector]public Objectbehavior scriptref; // PUBLICVAR (The Class ObjectBehavior) (set it as scriptref)
[HideInInspector]public Material materialToUse;
private GameObject sphere;
private float myX;
private Vector3 tempVector;
void Awake (){
if (controller == null)
{
DontDestroyOnLoad (gameObject);
controller = this;
}
else if (controller != this)
{
Destroy(gameObject);
}
}
//THIS SCRIPT
// Use this for initialization
void Start () {
sphere = objectContainingScript; // its the same object so we can use it.
scriptref = objectContainingScript.GetComponent<Objectbehavior> ();
int ballType = 1; // greenMaterial by default
for (myX = 0; myX < 6; myX++)
{
tempVector[0] = myX*2;
tempVector[1] = 0;
tempVector[2] = 0;
ballType = (int)Random.Range (1f,7f);
if (ballType == 1){materialToUse = greenMaterial;}
if (ballType == 2){materialToUse = redMaterial;}
if (ballType == 3){materialToUse = yellowMaterial;}
if (ballType == 4){materialToUse = blueMaterial;}
if (ballType == 5){materialToUse = pinkMaterial;}
if (ballType == 6){materialToUse = whiteMaterial;}
sphere.renderer.material = materialToUse; // set the clone sphere's color to the color necessary
Instantiate (sphere, tempVector, transform.rotation );
}
}
// Update is called once per frame
void Update () {
values inside of the object's script <ObjectBehavior>
print (scriptref.mytempVector); //scriptref.tempVector always = 0,0,0 @ RUNTIME , YET THE BALL MOVES FORWARD
if (scriptref.mytempVector[2] > 4) {scriptref.direction = -1;} // I am trying to check that balls Z position, and if exceeeds parameter then switch it's direction
if (scriptref.mytempVector[2] < 0) {scriptref.direction = 1;} // ****** it autocompletes the variable like there is a connection, but then it keeps returning 0,0,0
// The editor Scene view proves the balls move outward in a positive Z direction
}
}
ObjectBehavior.cs
using UnityEngine; using System.Collections;
public class Objectbehavior : MonoBehaviour {
public int direction;
[HideInInspector]public Vector3 mytempVector;
[HideInInspector]public float stepInterval;
// Use this for initialization
void Start ()
{
gameObject.tag = "temp";
direction = 1;
stepInterval = GameController.controller.speedInterval;
}
// Update is called once per frame
void Update () {
mytempVector = transform.position; //
if (direction == 1) {mytempVector [2] = mytempVector [2] + stepInterval;} //
if (direction == -1) {mytempVector [2] = mytempVector [2] - stepInterval;} //
transform.position = mytempVector;
print (mytempVector); // Proves it is moving in a positive Z direction initially , but never comes back
}
}
You know...I wanna check the instanced variables of the cloned sphere. I also want to be sure the direction variable is specific to each cloned sphere. In case I add 40 of them.
Answer by Mmmpies · Dec 24, 2014 at 06:25 PM
No you don't make scripts static, you should avoid making variables static where possible and in this case you don't need to.
What is the GameController script attached to in the hierarchy?
Whatever it is find that object and then use "THATOBJECT".getComponent().speedInterval;
let's say you've got an empty gameObject called GC that your GameController is attached to then you'd set your stepInterval to the public speedInterval like this
stepInterval = Find("GC").GetComponent<GameController>().speedInterval;
public is all you need for the variable to be accessible but you need to identify which script you're referencing.
Think about this, if you have a health script attached to enemies then you'd use the same script for all enemies. If you attack one enemy then you identify that enemy by a collision with your character and find the health script component attached to that specific enemy.
That's why you have to find where the script is attached and get the GameController script. It's not obvious because you'll likely only have 1 GameController but it still follows the same principals.
Thanks for the very quick reply. And this DOES resolve my stepInterval from within Objectbehavior. Though this was not really a problem I mentioned.
But, using your same method. I have an idea to fix my real problem: In my UPDATE function inside GameController.cs ( which yes is attached to an empty GameObject )..
tempVector = GameObject.Find ("Sphere(Clone)").GetComponent<Objectbehavior> ().myTempVector;
if (tempVector[2] > 4f) {GameObject.Find ("Sphere(Clone)").GetComponent<Objectbehavior> ().direction = -1;}
if (tempVector[2] < 0f) {GameObject.Find ("Sphere(Clone)").GetComponent<Objectbehavior> ().direction = 1;}
However, when I run the program. Only the one of the balls in the scene will actually hears the direction turning -1. There are 6 balls in the scene. Do I need an array or something?
I need to run a check on all the balls in the scene to see if ANY of them are > 4 on the Z plane. And if so, then that individual ball needs to reverse direction.
Find will find one and give up.
Tag you spheres e.g. Spheres (you could probably have worked that yourself! :¬) )
Then use:
GameObject[] mySpheres;
mySpheres = GameObject.FindGameObjectsWithTag("Spheres");
foreach(GameObject aSphere in mySpheres)
{
// each sphere will cycle through all are now refferenced
// with aSphere as the variable name. e.g.
if (tempVector[2] > 4f)
{
aSphere.GetComponent<Objectbehaviour>().direction = -1;
}
}
I'm typing that without checking and my typing is really poor so there may be typos, in fact when I first typed typing i spelled it typoing!
Actually yes, that worked brilliantly.
Wow, I really messed up some key structure on this. I guess my biggest problem was understanding how to interact with "children" / instanced versions of the original sphere.
Thank you again for taking the time to help me through this! UPVOTE+1 If I could....
Certain level of irony that you can't give out karma points yet!
No problem though, took me ages to get my head round linking script variables, and I can't cash in the points even if you were able to add them.
Don't know if it helps your ability to interact on here but i'll click on the thumbs up for getting back to me. You'd be amazed the number of people that get a fix and wander off never to be seen again!
One last question. I did try different variable types, but I am not sure which cast type is returned when you say this function....
stepInterval = Find("GC").GetComponent<GameController>().speedInterval;
Ideally, it would be nice to do something more like this:
objectreference = GameObject.Find ("GC").GetComponent<GameController>();
stepInterval = objectreference.speedInteral;
But what type would objectreference be when I Declare it at the top? I tried GameObject but it didnt seem to work for me.