• Unity3D - Discussion
    5,004 replies, posted
So I'm brand-spanking new to programming and c# with unity seems like a good place to start. For the life of me though, I can't figure out how to reference a variable from one script and use it in another. For reference, the scripts are attached to different game objects. collisionCheck.cs Checks if the object is colliding with another collider [code] using UnityEngine; using System.Collections; public class collisionCheck : MonoBehaviour { public bool collided; public int score; public void OnCollisionEnter() //Changes "collided" to true upon colliding { collided= true; Debug.Log ("You have collided!"); } public void OnCollisionExit() //Changes "collided" to false upon exiting the collision { collided = false; } } [/code] crashCounter.cs If collisionCheck is true, adds one to "score" and prints the text on a gui. [code]using UnityEngine; using UnityEngine.UI; using System.Collections; public class crashCounter : MonoBehaviour { float CollisionCheck_Ref; Text text; void Awake () { collisionCheck.score = 0; } void Start() { GameObject collisionCheck = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); } // Update is called once per frame void Update () { text.text = "Crashes: " + collisionCheck.score; } } [/code] I don't quite understand the documentation included in the API when it comes to referencing other scripts. [editline]8th January 2015[/editline] And forgive me if this isn't the right thread to talk about stuff like this, since I figured Unity's scripting was involved it seemed appropriate.
[code]using UnityEngine; using UnityEngine.UI; using System.Collections; public class crashCounter : MonoBehaviour { float CollisionCheck_Ref; Text text; void Awake () { collisionCheck.score = 0; } void Start() { // you declare a local variable here... GameObject collisionCheck = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); // which immediately goes out of scope } // Update is called once per frame void Update () { // but then you try to use it here? text.text = "Crashes: " + collisionCheck.score; } } [/code] ^Added comments to the above code, which I think points out what at least one problem is.
[QUOTE=TheGoodDoctorF;46886223]So I'm brand-spanking new to programming and c# with unity seems like a good place to start. For the life of me though, I can't figure out how to reference a variable from one script and use it in another. For reference, the scripts are attached to different game objects. collisionCheck.cs Checks if the object is colliding with another collider [code] using UnityEngine; using System.Collections; public class collisionCheck : MonoBehaviour { public bool collided; public int score; public void OnCollisionEnter() //Changes "collided" to true upon colliding { collided= true; Debug.Log ("You have collided!"); } public void OnCollisionExit() //Changes "collided" to false upon exiting the collision { collided = false; } } [/code] crashCounter.cs If collisionCheck is true, adds one to "score" and prints the text on a gui. [code]using UnityEngine; using UnityEngine.UI; using System.Collections; public class crashCounter : MonoBehaviour { float CollisionCheck_Ref; Text text; void Awake () { collisionCheck.score = 0; } void Start() { GameObject collisionCheck = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); } // Update is called once per frame void Update () { text.text = "Crashes: " + collisionCheck.score; } } [/code] I don't quite understand the documentation included in the API when it comes to referencing other scripts. [editline]8th January 2015[/editline] And forgive me if this isn't the right thread to talk about stuff like this, since I figured Unity's scripting was involved it seemed appropriate.[/QUOTE] Objects in most programming languages live inside of a "scope". Brackets denote where a scope starts and ends, when a scope ends, all objects that are not referenced somewhere else, are destroyed. [code] void Start() { GameObject collisionCheck = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); }//collisionCheck is destroyed after scope ends GameObject collisionCheck;//For the sake of the explanation, this object only exists for Foo() void Foo() { collisionCheck = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); }//collisionCheck is not destroyed because it is referenced outside of the scope void Bar() { { GameObject collisionCheck = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); }//collisionCheck is destroyed after this scope ends Debug.Log(collisionCheck.score);//Code will break since collisionCheck does not exist anymore. } [/code]
On top of that, I'm just confused as to how I reference a particular variable in another script attached to another game object. Do you have to create a variable to store the reference with something like...? [code] public GameObject collisionCheck_ref = GameObject.Find ("collisionCheck").GetComponent <collisionCheck> (); [/code] and then call the variable with something like [code] collisionCheck_ref.score = 0 [/code] collisionCheck being the script where the integer "score" is stored?. [editline]8th January 2015[/editline] If it wasn't obvious, I'm very new at this. [editline]8th January 2015[/editline] Alrighty, so after playing around I managed to get it to compile with this. [code]public class crashCounter : MonoBehaviour { public collisionCheck collisionCheck; Text text; void Awake () { collisionCheck.score = 0; } void Start() { collisionCheck = collisionCheck.GetComponent<collisionCheck> (); text = text.GetComponent<Text> (); } // Update is called once per frame void Update () { text.text = "Crashes: " + collisionCheck.score; } }[/code] However, the text is not printing when I run it. The debugger isn't giving me sass though, so I'm assuming that it's something stupid on my end.
What do you mean the text isn't printing? As in there is no text on the screen or it's not printing the result? From the looks of the code you gave it will always be 0 unless there is something in the collisionCheck class that changes it. Also, [code]public collisionCheck collisionCheck;[/code] is bad. I'm not sure if it is actually allowed but you shouldn't name your variable the same as your type verbatim like that. You'd want to do something like [code]public CollisionCheck collisionCheck;[/code]
I'll make sure to get in a habit of that, I can see how that would mess me up later. My ultimate goal here is to count how many times the player crashes and show that number via a ui ingame. I have another script that checks if the object is colliding and adds to it to "score". (score being the variable I was trying to reference earlier) I have this script (crashCounter) attached as a component to a text game object (Canvas -> Text) so that ideally, "Crashes: (score)" is printed on the ui. For some reason it is not printing at the moment and unity isn't showing me a reason why it wouldn't work. [editline]9th January 2015[/editline] This is my code as is at the moment. [code]using UnityEngine; using UnityEngine.UI; using System.Collections; public class crashCounter : MonoBehaviour { public collisionCheck CollisionCheck; public Text text; void Awake () { CollisionCheck.score = 0; } void Start() { CollisionCheck = CollisionCheck.GetComponent<collisionCheck> (); text = text.GetComponent<Text> (); } // Update is called once per frame void Update () { text.text = "Crashes: " + CollisionCheck.score; } }[/code] and the other script that works with the "score" variable. [code]using UnityEngine; using System.Collections; public class collisionCheck : MonoBehaviour { public bool collided; public int score; void start() { score = 0; } public void OnCollisionEnter() //Changes "collided" to true upon colliding { collided= true; Debug.Log ("You have collided!"); Debug.Log ("Number of collisions: " + score); score = score + 1; } public void OnCollisionExit() //Changes "collided" to false upon exiting the collision { collided = false; } }[/code] and the console spits out this error, which I can't quite decipher. [img]http://i.gyazo.com/e4646330fb0223fc5c0ddf05ae6a1570.png[/img] I'm sorry to shit up the thread like this. The resources that are out there just aren't helping with this particular problem.
You want to check line :12 [code] CollisionCheck = CollisionCheck.GetComponent<collisionCheck> (); [/code] You're trying to use what you're trying to get. It's like putting a box in the same box.
[QUOTE=TheGoodDoctorF;46887339] - snip - [/QUOTE] Your compiler is stating that there is a object in your script that is trying to access, but not yet initialized. You need to learn about the order of execution, which comes first. As you can see, in the Awake function, you are trying to set a variable to a object that has not been assigned yet, until it's been assigned in the Start function. So instead of this [Code]void Awake () { CollisionCheck.score = 0; } void Start() { CollisionCheck = CollisionCheck.GetComponent<collisionCheck> (); text = text.GetComponent<Text> (); } [/Code] Do this [Code] void Start() { CollisionCheck = CollisionCheck.GetComponent<collisionCheck> (); // Variable is being assigned CollisionCheck.score = 0; // set the values here. text = text.GetComponent<Text> (); } [/code] The order of execution goes where Awake is called first before anything else, then the start, and then the Update. If you try to establish a object variable in the Start function, but trying to set variable within that object in the Awake, it will raise an exception. Edit; Thanks kidd, was trying to find it, but got draft away. [QUOTE=Kidd;46893792]To add to Skibur's post about execution order. This link explains it. [url]http://docs.unity3d.com/Manual/ExecutionOrder.html[/url][/QUOTE]
Just started on my first game wish me luck.
To add to Skibur's post about execution order. This link explains it. [url]http://docs.unity3d.com/Manual/ExecutionOrder.html[/url]
Thanks for the advice guys. Solved the problem I was having (Had to use GameObject.Find to properly reference my component. I'll post screenshots of what I'm working on when I have something more to show for it.
[QUOTE=TheGoodDoctorF;46894401]Thanks for the advice guys. Solved the problem I was having (Had to use GameObject.Find to properly reference my component. I'll post screenshots of what I'm working on when I have something more to show for it.[/QUOTE] GameObject.Find is a really expensive operation, when used improperly. What are you trying to achieve doing this? Why not declare your variable public, and then assign the object in the inspector?
I wasn't aware that you could do that until just now. That is incredibly useful. [editline]11th January 2015[/editline] Just got rid of all my instances of GameObject.Find without breaking anything. I feel very stupid now :v:
[QUOTE=Skibur;46895258]GameObject.Find is a really expensive operation, when used improperly. What are you trying to achieve doing this? Why not declare your variable public, and then assign the object in the inspector?[/QUOTE] Problem with that at least it happened to me is that sometimes when I start unity all the variables that had scripts or objects were cleared.
[QUOTE=BoowmanTech;46901780]Problem with that at least it happened to me is that sometimes when I start unity all the variables that had scripts or objects were cleared.[/QUOTE] You must have done something wrong then. Renamed variables perhaps, or deleted a meta file or two somewhere? Because that doesn't "just happen" randomly.
Anyone know what causes scripts to not update after changing variables in the script? It always catches me off-guard. I'll save the script and hit play and nothing changes. So I keep changing the variable in the script and eventually I notice in the inspector that it isn't updating.
If it's public and shows up in the inspector, then yeah - it will always use the value stored in the scene or the prefab.
It's not something that is constant. 90% of the time the public variable updates just fine if I change the variable in the script. Just at some point something causes the inspector to never update. Just wondering what causes it so I could avoid it.
[QUOTE=Kidd;46902512]It's not something that is constant. 90% of the time the public variable updates just fine if I change the variable in the script. Just at some point something causes the inspector to never update. Just wondering what causes it so I could avoid it.[/QUOTE] Unless you change something important, public variable values will not update in the inspector, even if you change their default in the script. This is by design.
I'm going to have to test this tomorrow. I could have sworn that if the variable is public but I change the variable in the script instead it would update the inspector with the change.
[QUOTE=KillaMaaki;46902026]You must have done something wrong then. Renamed variables perhaps, or deleted a meta file or two somewhere? Because that doesn't "just happen" randomly.[/QUOTE] Oh ok, I mean it happened once or twice in like 6-8 months so I probably did something.
[QUOTE=Kidd;46902584]I'm going to have to test this tomorrow. I could have sworn that if the variable is public but I change the variable in the script instead it would update the inspector with the change.[/QUOTE] Only assignments done on initialization are taken from the inspector. While the scene is running, public variables can be edited by code and the changes show up in the inspector.
Amazing, I figured out I can load PNGs runtime, and can have huge PNGs which are only 30kb big and use them as textures.
Has anyone used [URL="https://www.assetstore.unity3d.com/en/#!/content/23569"]RAIN[/URL] before? If you have can you give me a quick rundown on how it works, all of the tutorials I've seen don't give me a simple AI setup they go for the most complex system and I just want a capsule to chase a player if it sees them.
[QUOTE=Kidd;46902512]It's not something that is constant. 90% of the time the public variable updates just fine if I change the variable in the script. Just at some point something causes the inspector to never update. Just wondering what causes it so I could avoid it.[/QUOTE] If your script isn't updating like it should have, then there's a chances that you may have too many warnings or errors coming from your script that's preventing it to update. If you are using monodeveloper, you can hit F8 to quickly debug your script for errors or warnings. Then hopping over to Unity would make the script compile much much faster.
I think that someone should make a list of FAQ and answers from this thread so that people like me who just discovered it can get quick answers to their problems via ctrl+f... and so that the people who come here all the time don't see the same questions over and over. It should go in the OP, ideally.
[video=youtube;WKdQBRDMMGI]http://www.youtube.com/watch?v=WKdQBRDMMGI[/video] aerobraking
How do I go about detecting LOCAL sideways velocity and killing it? As in, for a top-down 2D vehicle tire? If I just take rigidbody2D.velocity.x, it will take into account velocity relative to world, so if the tire turns 90 degrees, it will fully resist traveling in the direction the vehicle is going.
[QUOTE=Drury;46911839]How do I go about detecting LOCAL sideways velocity and killing it? As in, for a top-down 2D vehicle tire? If I just take rigidbody2D.velocity.x, it will take into account velocity relative to world, so if the tire turns 90 degrees, it will fully resist traveling in the direction the vehicle is going.[/QUOTE] [url=http://docs.unity3d.com/ScriptReference/Transform.InverseTransformDirection.html]transform.InverseTransformDirection[/url]?
So here's what I have [code]if (transform.InverseTransformDirection(rigidbody2D.velocity.x,rigidbody2D.velocity.y,0) != Vector3.zero); { rigidbody2D.AddForce(-transform.TransformDirection(rigidbody2D.velocity.x,rigidbody2D.velocity.y,0)*20); } [/code] Needless to say it doesn't work. It does kinda simulate friction from all directions (not what I want but close), but when I push it in a funny way it spins out and goes all across the place. If I don't multiply by 20, it's barely noticeable. I've tried to counter rotation with sine and cosine as well but no luck. I lack the experience to do this properly I guess. [editline]12th January 2015[/editline] And yeah if I replace rigidbody2D.velocity.y with 0 in addforce just goes off when I touch it.
Sorry, you need to Log In to post a reply to this thread.