I’m coding on my own as a hobby and need some outside oversight into coding practices. I want to make a manager that monitors the distance of objects from the player and makes them kinematic or enables/disables them based on distance and possibly other factors.
I’d like to make it as re-usable as possible so I was thinking two scripts. One that sits on the player and one that goes on each object that I want managed by it. The scripts on the objects would find the script on the player at start and add themselves to it’s list of managed objects. The script on the player would then iterate through the list on some interval and enable/disable, or whatever other behavior, based on distance and booleans on the object scripts. That lets me just add a script and tick a few boxes to any object I want managed, throw the player manager on the player and bam, works for any project I want, independent from how the objects are spawned or anything else etc.
So a number of questions:
Am I on the right track as far as generally acceptable practices and from a “I might want to work with others eventually” standpoint?
It seems like this would all make more sense just being on the objects except then they can’t enable/disable themselves. I’d have to have multiple scripts if I wanted isKinematic etc. managed by the objects and enable/disable managed by the manager which seems cumbersome and I think would add a performance hit? Is there just a better way that I’m not thinking of? Should there even be anything attached to the player or does it make more sense to have a manager script separate from everything?
If the approach does make sense how do I have the objects find any instances of the manager script on start to add themselves?
I’m fairly certain that interfaces have a place here but haven’t had any practice with them so not sure how to work that in exactly or is that just over complicating it?
Thanks in advance, I’ve only ever worked alone so I’m struggling with getting an idea of best practices.
My first thought is why not just use a trigger SphereCollider and handle OnTriggerEnter/OnTriggerExit instead of managing a list of objects and running code every update for every object in that list. It would probably be a lot more efficient.
Is there any reason you need to activate/deactivate the entire GameObject? Couldn’t you just enable/disable certain components that perform the behavior you’re worried about, and keep the “DistanceManager” component enabled all the time? Having multiple scripts on an object is not really a problem per se. It becomes more of a problem when they all have Update() methods for example, but the kind of script we’re discussing doesn’t need Update, especially if you’re using Physics events like OnTriggerEnter.
Use either the Singleton pattern or FindGameObjectByTag. You can find examples easily enough with Google.
Probably better off just using specific components for the distance management stuff. Save other behavior for other components. Unity really shines when you use “composition”, where you have lots of smaller components doing small simple jobs, instead of trying to shove too much into single scripts with OOO concepts like inheritance.
Thank you PraetorBlue, I was thinking using the physics system just to detect when objects come within/leave a certain distance would be a huge performance cost compared to just calculating the distance with Vector3.Distance(). That’s probably not the case though with the way Unity uses Octrees for the physics engine. If it’s faster that way anyway then it’s a no brainer to just throw a trigger sphere on each object and have them do whatever they need when the player comes into contact with it. Which of course makes the rest of the questions moot.
Edit: Well now I have more questions. I do want to be able to disable the entire object since I don’t want to have to set up each individual component I want to enable/disable for every object I add. I also want to enable/disable Kinematic at a separate distance and possibly other actions. But now I need a parent object and multiple child objects so I can tell which trigger came in contact with the player. It also complicates any collider/trigger interactions on all future objects because the colliders all report collision up to the parent. Or I need multiple additional objects with rigidbodies Which puts me at a convoluted solution where every object added going forward will have significant manual work and added complexity. There has to be a better way that’s more re-usable and doesn’t add so much manual labor and convolution to all future work. Especially since probably 95% of 3d games have to accomplish this somehow, it seems like there should be a simple solution.