Unity’s GameObject class is used to represent anything which can exist in a Scene.
This page relates to scripting with Unity’s GameObject class. To learn about using GameObjects in the Scene and Hierarchy in the Unity Editor, see the GameObjects section of the user manual. For an exhaustive reference of every member of the GameObject class, see the GameObject script reference.
GameObjects are the building blocks for scenes in Unity, and act as a container for functional components which determine how the GameObject looks, and what the GameObject does.
In scripting, the GameObject class provides a collection of methods which allow you to work with them in your code, including finding, making connections and sending messages between GameObjects, as well as adding or removing components attached to the GameObject, and setting values relating to their status within the scene.
There are a number of properties you can modify via script which relate to the GameObject’s status in the scene. These typically correspond to the controls visible near the top of the inspector when you have a GameObject selected in the Editor.
They don’t relate to any particular component, and are visible in the inspector of a GameObject at the top, above the list of components.
All GameObjects share a set of controls at the top of the inspector relating to the GameObject’s status within the scene, and these can be controlled via the GameObject’s scripting API.
If you want a quick list of all the available API for the GameObject class, see the GameObject Script Reference.
GameObjects are active by default, but can be deactivated, which turns off all components attached to the GameObject. This generally means it will become invisible, and not receive any of the normal callbacks or events such as Update
or FixedUpdate
.
The GameObject’s active status is represented by the checkbox to the left of the GameObject’s name. You can control this using GameObject.SetActive
.
You can also read the current active state using GameObject.activeSelf
, and whether or not the GameObject is actually active in the scene using GameObject.activeInHierarchy
. The latter of these two is necessary because whether a GameObject is actually active is determined by its own active state, plus the active state of all of its parents. If any of its parents are not active, then it will not be active despite its own active setting.
Some of Unity’s systems, such as Global Illumination, Occlusion, Batching, Navigation, and Reflection Probes, rely on .You can control which of Unity’s systems consider the GameObject to be static by using GameObjectUtility.SetStaticEditorFlags
. Read more about Static GameObjects here.
Tags provide a way of marking and identifying types of GameObject in your scene and Layers provide a similar but distinct way of including or excluding groups of GameObjects from certain built-in actions, such as rendering or physics collisions.
For more information about how to use Tags and Layers in the editor, see the main user manual pages for Tags and Layers.
You can modify tag and layer values via script using the GameObject.tag
and GameObject.layer
properties. You can also check a GameObject’s tag efficiently by using the CompareTag
method, which includes validation of whether the tag exists, and does not cause any memory allocation.
You can add or remove components at runtime, which can be useful for procedurally creating GameObjects, or modifying how a GameObject behaves. Note, you can also enable
or disable
script components, and some types of built-in component, via script without destroying them.
The best way to add a component at runtime is to use AddComponent<Type>
, specifying the type of component within angle brackets as shown. To remove a component, you must use Object.Destroy
method on the component itself.
The simplest case is where a script on a GameObject needs to access another Component attached to the same GameObject (remember, other scripts attached to a GameObject are also Components themselves). To do this, the first step is to get a reference to the Component instance you want to work with. This is done with the GetComponent method. Typically, you want to assign the Component object to a variable, which is done in using the following code. In this example the script is getting a reference to a Rigidbody component on the same GameObject:
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
}
Как только у вас есть ссылка на экземпляр компонента, вы можете устанавливать значения его свойств, тех же, которые вы можете изменить в окне Inspector:
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
// Change the mass of the object's Rigidbody.
rb.mass = 10f;
}
You can also call methods on the Component reference, for example:
void Start ()
{
Rigidbody rb = GetComponent<Rigidbody>();
// Add a force to the Rigidbody.
rb.AddForce(Vector3.up * 10f);
}
Note: you can have multiple custom scripts attached to the same GameObject. If you need to access one script from another, you can use GetComponent as usual and just use the name of the script class (or the filename) to specify the Component type you want.
If you attempt to retrieve a Component type that hasn’t actually been added to the GameObject then GetComponent will return null; you will get a null reference error at runtime if you try to change any values on a null object.
Although they sometimes operate in isolation, it is common for scripts to keep track of other GameObjects, or more commonly, components on other GameObjects. For example, in a cooking game, a chef might need to know the position of the stove. Unity provides a number of different ways to retrieve other objects, each appropriate to certain situations.
Самый простой способ найти нужный игровой объект - добавить в скрипт переменную типа GameObject с уровнем доступа public:
public class Chef : MonoBehaviour
{
public GameObject stove;
// Other variables and functions...
}
This variable will be visible in the Inspector, as a GameObject field.
You can now drag an object from the scene or Hierarchy panel onto this variable to assign it.
The GetComponent function and Component access variables are available for this object as with any other, so you can use code like the following:
public class Chef : MonoBehaviour {
public GameObject stove;
void Start() {
// Start the chef 2 units in front of the stove.
transform.position = stove.transform.position + Vector3.forward * 2f;
}
}
Additionally, if you declare a public variable of a Component type in your script, you can drag any GameObject that has that Component attached onto it. This accesses the Component directly rather than the GameObject itself.
public Transform playerTransform;
Соединение объектов через переменные наиболее полезно, когда вы имеете дело с отдельными объектами, имеющими постоянную связь. Вы можете использовать массив для хранения связи с несколькими объектами одного типа, но связи все равно должны быть заданы в редакторе Unity, а не во время выполнения. Часто удобно находить объекты во время выполнения, и Unity предоставляет два основных способа сделать это, описанных ниже.
Sometimes, a game Scene makes use of a number of GameObjects of the same type, such as collectibles, waypoints and obstacles. These may need to be tracked by a particular script that supervises or reacts to them (for example, all waypoints might need to be available to a pathfinding script). Using variables to link these GameObjects is a possibility but it makes the design process tedious if each new waypoint has to be dragged to a variable on a script. Likewise, if a waypoint is deleted, then it is a nuisance to have to remove the variable reference to the missing GameObject. In cases like this, it is often better to manage a set of GameObjects by making them all children of one parent GameObject. The child GameObjects can be retrieved using the parent’s Transform component (because all GameObjects implicitly have a Transform):
using UnityEngine;
public class WaypointManager : MonoBehaviour {
public Transform[] waypoints;
void Start()
{
waypoints = new Transform[transform.childCount];
int i = 0;
foreach (Transform t in transform)
{
waypoints[i++] = t;
}
}
}
You can also locate a specific child object by name using the Transform.Find method:
transform.Find("Frying Pan");
This can be useful when a GameObject has a child GameObject that can be added and removed during gameplay. A tool or utensil that can be picked up and put down during gameplay is a good example of this.
While editing your project you can set up references between GameObjects in the Inspector. However, sometimes it is impossible to set up these in advance (for example, finding the nearest item to a character in your game, or making references to GameObjects that were instantiated after the Scene loaded). In these cases, you can find references and send messages between GameObjects at runtime.
BroadcastMessage
allows you to send out a call to a named method, without being specific about where that method should be implemented. You can use it to call a named method on every MonoBehaviour on a particular GameObject or any of its children. You can optionally choose to enforce that there must be at least one receiver (or an error is generated).
SendMessage
is a little more specific, and only sends the call to a named method on the GameObject itself, and not its children.
SendMessageUpwards
is similar, but sends out the call to a named method on the GameObject and all its parents.
It is always possible to locate GameObjects anywhere in the Scene hierarchy as long as you have some information to identify them. Individual objects can be retrieved by name using the GameObject.Find function:
GameObject player;
void Start()
{
player = GameObject.Find("MainHeroCharacter");
}
An object or a collection of objects can also be located by their tag using the GameObject.FindWithTag and GameObject.FindGameObjectsWithTag methods.
For example, in a cooking game with one chef character, and multiple stoves in the kitchen (each tagged “Stove”):
GameObject chef;
GameObject[] stoves;
void Start()
{
chef = GameObject.FindWithTag("Chef");
stoves = GameObject.FindGameObjectsWithTag("Stove");
}
You can create and destroy GameObjects while your project is running. In Unity, a GameObject can be created using the Instantiate method which makes a new copy of an existing object.
For a full description and examples of how to instantiate GameObjects, see Instantiating Prefabs at Runtime.
There is also a Destroy method that will destroy an object after the frame update has finished or optionally after a short time delay:
void OnCollisionEnter(Collision otherObj) {
if (otherObj.gameObject.tag == "Garbage can") {
Destroy(gameObject, 0.5f);
}
}
Note that the Destroy function can destroy individual components without affecting the GameObject itself. A common mistake is to write this, assuming it will destroy the GameObject the script it’s attached to…
Destroy(this);
…whereas, because “this” represents the script, and not the GameObject, it will actually just destroy the script component that calls it, leaving the GameObject behind, with the script component removed.
The GameObject class offers script-based alternatives to the options available in Unity’s GameObject menu that allows you to create primitive objects.
To create instances of Unity’s built-in primitives, use GameObject.CreatePrimitive, which instantiates a primitive of the type that you specify. The available primitive types are Sphere, Capsule, Cylinder, Cube, Plane and Quad.