When I add a script component to a game object, is it intended that we give the class the same name as the game object or prefab? It doesn’t say that anywhere, but in my previous project, I found that if I didn’t do that, the rest of the scripts didn’t treat the methods on the class as being anything to do with the physical object.
No. A GameObject’s name is just a property of the GameObject, it has no meaning in terms of the code. A component’s class name should reflect what that component does. Built-in components are examples of this: MeshCollider, ParticleSystem, even Camera.
I’m not clear about what you mean by the last part. For an external script to reference the methods of a component on a GameObject, the external script would have to get a reference to that component by calling something like GetComponent or perhaps GetComponentInChildren on the target GameObject:
public class SomeExternalScript : MonoBehaviour
{
public GameObject targetObject; // we're assuming this has a MeshCollider
void Awake()
{
MeshCollider m = targetObject.GetComponent<MeshCollider>();
// do stuff with the other object's MeshCollider here
}
}
Well when you define properties for the object - for example let’s say I have made an object with a spherical mesh and called it Obj_Ball. Then I want a property for it called “bounciness” which I am intending to change during runtime from another object - let’s say in the Update event of Obj_GameController. So I will want to say Obj_Ball.bounciness -= 1 a value which will be read by the ball in its own Update event. If I call Obj_Ball’s script Script_Ball (and say Script_Ball.bounciness) rather than Obj_Ball the GameController won’t know to affect the Property on Obj_Ball. So basically I am talking about the main script for an object the one where you can set the properties to appear in the Inspector.
there is no main script for a object, you simply add components to the object, if you need to access a script on the gameobject you use GetComponent() where T is the the type you want to access. The only thing that matters naming wise, is the filename of a MonoBehaviour class must match its Class name.
The bounciness property will never be available by referencing the Obj_Ball GameObject. There is no way to extend or derive from UnityEngine objects (they’re what C# calls “sealed” classes). Your game controller would have to know that bounciness was a property on Script_Ball, then it would need to use code similar to what I wrote earlier to grab that Script_Ball component from Obj_Ball. Or alternately you could have Unity help you by declaring Script_Ball as the public property and the Editor is smart enough to cast Obj_Ball to the Script_Ball type in the Inspector. In fact, maybe this is what you were thinking of:
public class Obj_GameController : MonoBehaviour
{
public Script_Ball scriptball; // drag Obj_Ball to this
void Update()
{
scriptball.bounciness = 1f;
scriptball.gameObject.transform.position = CalculatePosition();
}
private Vector3 CalculatePosition()
{
// ...
}
}
In the Inspector, you’d drag your Obj_Ball to the Script_Ball slot on Obj_GameController, but inside Obj_GameController, you’re still dealing with a Script_Ball object. You could refer to “scriptball.gameObject” if the controller needed to step up one level and reference Obj_Ball itself, as shown in the last line of the Update above.
Yes that’s it MV. But I found it does it automatically if you give the script the same name as the object.
They will all be added as components on the object, and can all be accessed via GetComponent()
And you access those properties through each separate component reference.
You should likely follow one of the basic tutorials in the Unity Learn section such as roll the ball. That should give you a basic grounding in how objects communicate with one another and the difference between GameObjects and Components.
This is probably a good time to learn about C# interfaces, too. Think of an interface as a way to create tightly focused behaviors. For example, Obj_Controller may only care about bounciness. Spheres roll, but cubes do not, so maybe you have two scripts: Script_Ball and Script_Cube.
Instead of having to make Obj_Controller know about both of those scripts, you can define an interface that your two scripts implement, and Obj_Controller only needs to know about the interface.
The interface (usually a separate .cs file) defines the contract – it just declares the “pattern” that any class which uses the interface must implement.
public interface IBouncyThing
{
float bounciness { get; set; }
}
Now both Script_Ball and Script_Cube can implement their own special behaviors (balls roll, cubes sit there) plus, by implementing the IBouncyThing interface, they can also expose a bounciness property to any other script that doesn’t care about anything except bounciness:
public class Script_Ball : MonoBehaviour, IBouncyThing
{
public float bounciness { get; set; } // this "implements" the IBouncyThing interface
public void RollAround()
{
// this is specific to Script_Ball
// to use it, some external script would need to know about Script_Balls
}
}
public class Script_Cube : MonoBehaviour, IBouncyThing
{
public float bounciness { get; set; } // this also "implements" the IBouncyThing interface
public void SitThereAndLookPretty()
{
// this is specific to Script_Cube
}
}
public class Obj_Controller : MonoBehaviour
{
// you can add both Obj_Ball and Obj_Block to this in Inspector
public IBouncyThing[] bouncyObjects;
void Update()
{
for(int i = 0; i < bouncyObjects.Length; i++)
{
bouncyObjects[i].bounciness = 1f;
bouncyObjects[i].gameObject.transform.position = CalculatePosition();
}
}
private Vector3 CalculatePosition()
{
// ...
}
}
Yeah I found that addressing the scriptclass from another object, then going .gameobject would reach the game object. Maybe it’s all changed now.
Thanks, though I know about Interfaces, done a fair bit of C#. I do understand what you’re all saying about getting the script via the components list of an object, but in my previous (long ago) project getting the gameobject via the script class seemed to be an easier way than getting the script via the gameobject. I just used to put everything, all the methods and stuff for the object into the one class And calling them both the same name facilitated.
Hmm ok I watched a beginner tutorial as suggested to me. It showed me you can have several script components on one gameobject, and they all know what gameobject they are attached to, for easy reference to it. So what would happen if you used the same script as a component of more than one object? And I still think this way makes it more awkward for the scripts from different objects to call things on each other.
when you put a script on a object, you are making a instance of that script, so if you put the same script on multiple objects all the instances will work independently of one and other.
When you see a component on a gameobject it is a instance of its class.
Yeah I have a feeling what my problem is, is grasping the concept of components. I am so used to a C# class being THE object, and writing for a game engine is very different. I’ll do some more reading about components, thanks.
yeah the basic object type is the GameObject, which you can not inherit from. The GameObject has a list of Components that add behaviour to it. All components on the GameObject can get reference to it via the built in gameObject property of all components, and can do the same with the transform.
Also if you are assigning references via the inspector, you can assign based on a component type, and reference that directly, just keep in mind that components must live on a GameObject and you cant manually instantiate them.
Edit: i would assume you must have come from a background in a engine like idtech3 or goldsrc where you construct complex objects with inheritance. The idea with components, is that components represent what something can do, not what it is thus it makes sense to layer in multiple components to make a complex object as opposed to sub classing to add more functionality.
You can’t inherit from GameObject. You get things like the gameObject property by inheriting from MonoBehaviour.

was typing on my phone, and that was supposed to be a Can’t
It’s sort of reading like you have the conception that a class usually represents a single object. That should be the exception, not the rule. A class should usually represent any possible number of objects. This is the power of OOP.
Writing for a game engine shouldn’t be any different from writing any other software in this respect, unless you’ve picked up some bad programming habits.
Well I haven’t programmed components before, although I have “met” them in Sims 3 modding. I have used object classes to represent a world object, as well as using them to represent small data and method holders to be passed around between major objects. In my last unity project I also used small classes for similar reasons, which were not attached to gameobjects. But I only allocated one class to each gameobject, rather than a component per aspect of the gameobject. That’s what will be the new way of thinking for me.
I am going to start by reading this: Unity: Now You're Thinking With Components | Envato Tuts+