- Home /
Do all scripts have to be attached to an object?
When we create scripts, we attach them to an object. I'm new to using Unity, and I was wondering how the workflow is with this engine. Is it common practice to have every script attached to an object? Or is it common to have "unattached" scripts? If I want to create a script that would run as soon as the game starts, would it make the most sense to attach it to an object? And how would I create a script that isn't attached to an object? Can anyone refer me to a page where I can read about common practice in Unity? Thanks.
Answer by Lysander · Jan 03, 2018 at 06:55 AM
Disclaimer: Most of this is just personal preference, and I don't claim any of it to be gospel. That said, I feel pretty strongly about the "common practices" I've seen with Unity, so I may be a bit enthusiastic in expression of my dislike for them.
All scripts are "objects", because C# is an object-oriented-programming language (with all of the advantages and disadvantages that brings), so all classes and structs, no matter what, derive from System.Object. That's true of every program written in the language, regardless of the platform/engine. However, I'll continue under the assumption that you're talking about GameObjects specifically.
Only Components (MonoBehaviours) need to be attached to GameObjects, and if fact only they CAN be. The great majority of scripts in games are not Components, but data objects and utility classes for performing operations on data objects, like with any other program. You can create a normal non-MonoBehaviour script by just right clicking in the Project files tab and saying Create C# Script, naming the script, opening it in an IDE (double clicking it works), and deleting the part where it derives from MonoBehaviour. If it doesn't derive from MonoBehaviour, then it's not a component, and you don't need to / can't attach it to GameObject.
Most loose scripts you create will automatically be in the global namespace and can be referenced by eachother without any using statements, unless you place them in their own namespace. There are exceptions though.
If you need something to run as soon as the game starts, there are two primary ways to do that- make a Component and attach it to a GameObject in the starting scene, being sure that the GameObject and Component start off enabled, and add an Awake or Start function to the Component, or use the RuntimeInitializeOnLoad attribute on any static method (you can set it to run before or after the first scene loads).
The workflow actually isn't that complicated- Unity developers tend to aggressively overuse Components, for data storage as well as behaviours, but there's absolutely no requirement to do so, and in fact things are easier if you don't. Keep all of your pre-built static data in files (ScriptableObjects, XML, JSON, whatever you like), keep your runtime data in collections in static managers, and only reference any of that data from Components, and things run a lot more smoothly. Just make sure each GameObject that requires data to function properly has access to the data it needs, through assigned ID numbers or enum values or whatever.
Components are behaviours- they're how things behave and interact with eachother in a scene. Components can reference other components on the same GameObject with GetComponent trivially, as well as accessing their parent and child objects with only marginally more effort. A hierarchy of GameObjects in the scene that stand for a single logical unit is often referred to as an "entity"- for instance, a "character entity" could have a Transform component to say where the character exists in 3D space, a Rigidbody component to say "I need to interact with the physics engine", a Collider component to say "I need a box/sphere/capsule shape to define my physical boundaries and how physics objects collide with me", a MeshFilter component to give it a mesh, a MeshRenderer component to say how to render that mesh to the screen, an Animator component to say how the mesh should be animated, etc... Entities tend to interact with eachother either through collisions (rigidbodies and colliders) and raycasts (like infrared beams fired ahead to detect colliders at a distance).
Worth noting that most tutorials and guides you find will lead you down the path of abusing MonoBehaviours as data containers as well though- but it's best to keep it firmly in mind that they should only be behaviours, as the name suggests. If you want to learn about common practices in Unity, there's no better place than the official Unity Learn section of the website. Watch the entire "Interface and Essentials" section, and everything up through Beginner and Intermediate in the "Scripting" section, and you'll have a fairly good idea of how things work. It should only take a few hours- most of the videos are not very long, and Unity isn't that complicated to figure out.
Your answer
Follow this Question
Related Questions
Can someone explain calling other scripts in C#? 2 Answers
Using KeyCode or get buttonDown for activate collider 2d 1 Answer
Is there a way to recapitulate this? 1 Answer
How to add force if spherecast is true and how to set direction of sphere 0 Answers
How can I slow the velocity of my player without it affecting fall speed? 0 Answers