- Home /
Empty public script variables.
Hey guys just have a few quick questions for now, probably will have more later really trying to figure out the details for Unity optimization since I'm still pretty new to programming.
For example, I have an enemy Game Object in my scene that has a general AI script that handles nearly everything that enemy type does and I have about 10-20 of that enemy in a scene. One of those enemies uses a few more public Game Objects or Prefabs within it's script for extra behavior like dropped items, or an object script reference. Nearly all the enemies don't use those extra public script variables and therefor have empty public variables.
So how much of a performance hit is it to have a bunch of objects activated with several empty public variables each? Would it be worth making new scripts for these more unique variables to avoid having empty variables on the majority of the scripts?
I am unsure how much cost this has on memory/load time since they are empty. This is for an Android/iOS project too so I'm especially interested about any Unity performance details.
Null references only take up one memory address, so it's a pretty insignificant impact in the grand scheme of things. What will take a lot of memory is if a bunch of your variables actually reference things (then the memory hit is equal to however much ram each loaded object requires).
It's less a unity thing and more a c# thing, but remember to clear your subscribers from events when you're done with them. Whenever an event has a subscriber it prevents the object from being garbage collected, resulting in 'leaked' memory.
In fact, the reson I bring it up is because an even system sounds like it could work quite well for you. With the main enemy driver raising events that the rest of the behavior scripts subscribe to, you could streamline your detection and decision logic into the driver and have different behaviors respond to those events without your master script ever knowing anything about objects it doesn't need to know about. This will remove the mass of 'empty' variables.
Thanks that is very helpful!
So if a bunch of my objects reference a prefab is that a ton of memory addresses, or do they immediately store the entire loaded object into ram?
I was hoping they were just storing the memory reference address and would not load the entire memory of the object unless it was for example Instantiated (like dropped items on an enemy).
I'm not sure if I fully follow clearing the subscribers from events. Preventing memory leaks is a concern for sure but I haven't been able to notice any yet, so I'm not sure if I'm doing it correctly.
Generally I just destroy the entire gameObject whenever I get rid of something from the scene. I am assu$$anonymous$$g that loading a new scene clears all the memory from the last one.
Does anyone have an example of the subscribers being cleared from events that iwaldrop mentioned? I think I'm doing it right, but I'm so new to program$$anonymous$$g it's really impossible for me to know.
Edit: Also am curious for some examples of the main enemy driver. Right now each enemy type has a main script that interacts with other scripts, but it sounds like maybe I'm just including too much stuff in my main script? So ins$$anonymous$$d of loading all of them in automatically in the main script it would be better to call a function within another script and object if and when that behavior actually occurs? So all the enemy item drops might be loaded onto a single gameObject and Script ins$$anonymous$$d of being included on each enemy individually?
Hopefully I'm following you. I need to study more program$$anonymous$$g and watch some more tutorials. Right now I have pretty much designed the entire game and learned program$$anonymous$$g from scratch, so it's really hard for me to know when I'm doing something wrong. I'm not the best in school haha, makes this sort of thing so much harder.
For clearing subscribers, just make sure for every += you have a corresponding -=, like so:
void OnEnable()
{
SomeController.SomeStaticEvent += HandleSomeControllerSomeStaticEvent;
}
void OnDisable()
{
SomeController.SomeStaticEvent -= HandleSomeControllerSomeStaticEvent;
}
void HandleSomeControllerSomeStaticEvent()
{
// do stuff when event is received
}
If you don't do this then even when you change scenes the event will still maintain references to destroyed objects. This may also generate errors when the event is raised, because it tries to call a method which may have null references. Either way, best practice is to do the above (clear every time you subscribe), because you can't be sure the the event you're subscribing to clears it's own refs.
WRT memory, every reference you have (including public GameObject variables assigned through the inspecter) takes memory; even if it's null (as I described above).
Hmm it seems I have much more to take into consideration then. I always thought once you load a new scene all the old stuff got destroyed except playerPrefs.
So for example if I had 10 levels it could be possible that after each level I was leaking more and more memory? So essentially the longer you play the game would become slower?
Does anyone have an example of a common game event which could leak memory? $$anonymous$$aybe quick example of the leak code and then example of way to fix it?
I really have no idea if I'm leaking or not. Everything seems to make sense with the code from my perspective but there could very well be tons of c# or general program$$anonymous$$g stuff that someone like myself would have no idea even exists.
I guess it's worth mentioning though that my levels right now can be replayed after you beat them. I'm not sure if that would make any difference in how you handle this.
If you're using pro then check memory in the profiler. If not, watch memory using the platform's monitoring tools. The only way to know for sure if you're leaking memory is to have an empty scene load before you play, record the memory value, then load the same scene at the end of play, and compare the recorded value to the current value. You have to use a 'control' scene so that your measurement isn't invalidated by having different scenes loaded or the same scene in different states.
If you successfully trash all of your references then the memory consumption for your app should be nearly identical in the instances described. Again, events are the most common gotchas because a reference to an object by an event will not allow the garbage collector to purge that object. If that object happens to be a monobehaviour with a ton of additional references then you're talking about potentially leaking a lot of ram.
Answer by umangindianic · Jun 13, 2013 at 04:39 AM
If you have non useful gameobjects or if you use gameobjects only once. SO, you can destroy your gameobject after the use of same public gameobject. For variable make it private. so, it is not use other than your same script and that can not affect the memory use or performance of the game.