Accessing Components and Scripts
How to get components
As you know, the components are attached to the game object, therefore you need to have access to the GameObject which your intended component is attached to. This can be accomplished in multiple ways, the easiest being using the Serialized Fields, or maybe accessing it directly in game from collision, etc.
- To access components from a GameObject, use these methods from the Unity GameObject API:
GameObject
.GetComponent()
GameObject
.GetComponentInChildren()
GameObject
.GetComponentInParent()
GameObject
.GetComponents()
GameObject
.GetComponentsInChildren()
GameObject
.GetComponentsInParent()
GameObject
.TryGetComponent()
Components also have similar methods through the Component class.
For example, to access the Rigidbody component of an object objA
:
public Rigidbody rigidBody = objA.GetComponent<Rigidbody>();
C# Scripts As Components
C# scripts in Unity are components, so you can add or access them like any other component using these methods :
GameObject
.AddComponent()
GameObject
.GetComponent()
GameObject
.GetComponentInChildren()
GameObject
.GetComponentInParent()
GameObject
.TryGetComponent()
Component
.GetComponent()
Component
.GetComponentInChildren()
Component
.GetComponentInParent()
Component
.TryGetComponent()
Note that you will need to use the non-generic overload method in order to properly access custom C# script components. This is showcased in the following examples!
Example
Lets say that we have created a C# Script called ("Door.cs") and it is somewhere in our project. We also added this script to a game object A
.
using UnityEngine;
public class Door : MonoBehaviour
{
public string doorState = "open";
public void SayHello()
{
Debug.Log("Hello");
}
void Start()
{
}
void Update()
{
}
}
Now let's access this script from GameObject B
, using a SerializedField to reference A
:
using UnityEngine;
public class ExampleScript : MonoBehaviour
{
[SerializeField]
private GameObject objA;
void Start()
{
// Access the Door component on object A
Door doorScript = objA.GetComponent(typeof(Door)) as Door;
// Use the doorScript reference
Debug.Log(doorScript.doorState); // prints "open"
// Call the function
doorScript.SayHello(); // prints "Hello"
}
}
Adding Components Dynamically
You can add scripts as components at runtime:
// Add a new Door component to this GameObject
Door newDoor = gameObject.AddComponent(typeof(Door)) as Door;
When to use non-generic methods:
- When working with scripts that might not be available at compile time
- When dealing with type information that's only known at runtime
- When loading scripts dynamically
Important Notes
-
In C#, you use the actual class name (not filename) with the generic parameter syntax
<T>
-
All public fields and methods are accessible from other scripts
-
C# has proper namespaces, so you can have multiple classes with the same name in different namespaces
-
The script filename must match the class name (e.g.,
Door.cs
must contain classDoor
) -
Generic methods are generally faster as they're resolved at compile time
-
Non-generic methods involve type lookup at runtime
-
Cache component references whenever possible
Best Practices
-
Cache component references when possible (in Awake() or Start()) rather than calling GetComponent every frame
-
Use TryGetComponent when you're not sure if the component exists
-
Prefer [SerializeField] over public fields for better encapsulation
-
Use interfaces when you need to access components in a polymorphic way