- Home /
how to pass values between objects in C#
Hey guys!
What would the best way be to pass through values from one object to another with code?
Example: there are three objects (A, B and C), object A generates 10 bricks every 10 seconds, Object B collects the bricks at random times (however many that may be) and delivers them to Object C. Object C now needs to add the amount of bricks delivered to the amount of bricks that is already in storage. Each object must display their current value at any state of the game via a floating gui that sits on top of the objects.
I'm still kind of new to Unity so please forgive me if the answer is obvious, and a massive thanks for any help received.
Oh man... so many ways of accomplishing this. Just don't let people convince you to use Object.Find("name"), or FindObjectByTag(""). Both are horrible and should be removed from the Unity API imo.
You either create references in your classes to other class types you need access to, and assign those references via code or in-editor, or you make a static game management class that obtains and stores consistent references, or if the objects exist in the game and walk around like NPC's you could have trigger events... there is too many answers for this man, just come up with an idea and try it.
It is a shame to call Objec.Find methods useless, yeah if you build single scene games it is useless but in a vast amount of case they come quite handy. Give me a way to assign object references on runtime through a script or a way to check if an object does exist in a scene i could keep going but there is no point and i am not trying to change your opinion, the problem is you misinfor$$anonymous$$g people. Of course manual assignments are better but you can't always assign something through the editor. Using .Find methods are "heavy" but calling them once in a scene does not create problems you could also call a garbage collection afterwards to ensure no lag will occure later. Best regards.
I've built some very complex games and systems using Unity and not once have I ever needed to find an object by name. I dislike making references in-editor as well, but the way I see it, if you are generating objects at runtime, you ABSOLUTELY HAVE ACCESS TO THE OBJECT, ergo, a reference is possible. If you chose to ignore that reference and try and find it later using its name, that is just misuse. Especially since the only relevant way to find an object by its name is if its name is UNIQUE, which again, requires you to declare the name. At this time you could of simply added it to a list of references, or set it as a member of another class. Afterwards, finding a specific object in a list is still far superior to finding an object in a scene by its freaking name!
Fact is, those methods of finding objects aren't necessary. If you've ever built a standalone application without any existing framework, you would know that as well. Because the only references you have, are the ones you create. The idea that it is a trivial call because it happens on Awake() is absurd in a large project, with say, thousands of gameobjects, this will make the initialization take far longer than needed. As well, the idea that you somehow have the opportunity to name an object, but still don't have a reference to it is absurd. Point is, finding an object by a name string is stupid, and so is a lot of the Unity standards. I love Unity though because I can choose what I want to, and don't want to use.
Also calling a GC.Collect() after init seems outrageous. Let the GC do its thing unless you have a damned good reason to force a collection.
None of your scenarios would even require a find by string reference. Plus that seems to go against OOP itself, technically you are storing actual data in your class, making it technically not re-usable.
Answer by toddisarockstar · Apr 02, 2017 at 05:48 PM
I have to somewhat disagree with rob as long as you only do lookups once so they dont effect proficiency during game play. i usually do them in the start function like this:
nameofotherscript bscript;
void Start () {
bscript=GameObject.Find ("name of object").GetComponent<nameofotherscript>();
}
//now you can access the variables in the other script like this:
bscript.somevariable=true;
variables have to be public !!!!!!
Say what you will, but I've written a ton of code in Unity and never needed to use GameObject.Find("name"), because it isn't necessary. Also it has the worst overhead of any finding method because it has to iterate every single GameObject in the scene until it finds a match.
On top of that, getting the GameObject by a string name is prone to errors - it means you now have to be careful about what you name that object and other objects in your scene to avoid getting erroneous results.
I would wonder why in this example, someone wouldn't just have a public nameofotherscript variable ins$$anonymous$$d and assign it in the editor.
If I were to use on trigger enter, would that also consume more performance than what is actually needed?
@RobAnthem, @BobisGod234 - Yes, for static, hand-crafted levels, it's trivial to drag a reference to a scene object into a public variable slot in the inspector. But have you done much work with procedurally-generated games? In which case, you do not have an object reference at edit-time. Indeed your scene hierarchy may be completely empty, and the object you need to reference may (or may not!) get instantiated in the scene hierarchy only at runtime. In such cases, GameObject.Find() is entirely appropriate (and necessary).
I disagree, even in procedural generation you should have access to the object at generation and assign its relevance wherever it is needed. If you have the ability to give it a name at creation, then you have the ability to store a reference to the object. With events and callbacks, you can even make it a breeze to catch new instantiations.
The main problem with .Find is its quite open to abuse (often by relatively inexperienced developers that may not be aware of better approaches to solve a problem). It is still a useful feature for the occasional odd edge case.
Even in your example, I would be tempted to assign the run time instantiated component to a static variable in Awake() and access it from other scripts via that (assu$$anonymous$$g that there is only one instance of this component, which seems plausible enough, given GameObject .Find returns one GameObject, I assume this is some sort of singleton class). Alternatives to .Find would be dependent on the specifics of the problem of course.
when i have large numbers of objects/items/enemies I generally keep them in lists or arrays in a master script anyways. I use a lot of loops and try to do as much coding as i can from the masterscript. so i don't have a need for lookups often. in my last project the levels are spawned during runtime because the players have a level designer, and the AI have no individual scripts attached because it was easier to let the AI account for each other when they where all moved from the master script.
I do agree with you that the Find function is on the "list" of things that weigh heavy on a CPU when done often. And i also agree with you that a game should have some organizational setup for references. I generally call it a few times at most on startup to get a couple main scripts talking. whatever milliseconds lost during my intro screen goes unnoticed. $$anonymous$$y last finished game has over 8000 lines i wrote for it.
more and more i find myself writing my own versions of unity's functions to be more proficiant to my personal project. but there are many people here just trying to get started with coding and unity and just need to see thier ping pong ball bounce around. and if gameobject.find can save a begginer from banging there head against a key board all night. I say go for it. LOL
Answer by chazzysb · Apr 03, 2017 at 05:07 PM
Make you life easier by using the NotificationCentre
http://wiki.unity3d.com/index.php?title=CSharpNotificationCenter
Your answer
Follow this Question
Related Questions
edit values for multiple objects concurrently 1 Answer
Same script on multiple objects. 2 Answers
Multiple objects, same script, different values 2 Answers
Multiple Materials on Multiple Objects -runtime- 1 Answer
Loadlevelasync - Application Hangs 2 Answers