Script Communication: Accessing Enemy Properties from Your PlayerController
In game architecture, scripts often need to "talk" to one another to trigger game states like stealth alerts or game-over screens. A common 2026 scenario involves your PlayerController script needing to know if an enemy's canSeePlayer boolean has been triggered. This creates a bridge between your player's logic and the enemy's AI vision system. To do this efficiently without tanking your frame rate, you must master component referencing and script caching. Whether you are dealing with a single boss or a horde of guards, the following methods ensure your player script remains responsive to the enemy's line-of-sight status.
Table of Content
- Purpose: Establishing Cross-Script Communication
- The Logic: How GetComponent Connects Objects
- Step-by-Step: Fetching and Reading Enemy Data
- Use Case: Stealth Detection UI
- Best Results: Performance and Caching
- FAQ
- Disclaimer
Purpose
Accessing an enemy variable from a player script is vital for several gameplay mechanics:
- Contextual Feedback: Changing the player's movement speed or animation when they are spotted.
- Game State Transitions: Triggering a "Busted" UI or restarting a level when an enemy's visibility check returns true.
- Adaptive AI: allowing the player to "sense" when they are being watched by querying the vision status of nearby NPCs.
The Logic: How GetComponent Connects Objects
Unity scripts are "Components" attached to GameObjects. To read a property like canSeePlayer from an enemy, your PlayerController needs two things:
A Reference to the Enemy GameObject: This is found via tagging, raycasting, or collision triggers.
A Reference to the Script Component: Using the GetComponent<EnemyAI>() method, you can effectively "reach into" the enemy object and pull out the values of its public variables.
Step-by-Step
1. Prepare the Enemy Script
Ensure the property you want to access is marked as public. If it is private, the PlayerController will not be able to "see" it.
public class EnemyAI : MonoBehaviour {
public bool canSeePlayer; // Must be public to be accessed externally
}
2. Finding the Enemy in PlayerController
In your PlayerController, use GameObject.FindWithTag to locate the enemy. Ensure your enemy prefab is tagged as "Enemy" in the Unity Inspector.
GameObject enemyObject = GameObject.FindWithTag("Enemy");
3. Accessing the Property
Once you have the object, use GetComponent to find the script and read the boolean.
- Check if
enemyObjectis not null to avoid errors. - Get the
EnemyAIcomponent. - Read the
canSeePlayervalue inside anifstatement.
if (enemyObject != null) {
EnemyAI enemyScript = enemyObject.GetComponent<EnemyAI>();
if (enemyScript.canSeePlayer) {
Debug.Log("The enemy sees me!");
}
}
4. Handling Multiple Enemies
If your scene has many enemies, use FindObjectsByType (formerly FindObjectsOfType) to check them all in a loop:
EnemyAI[] allEnemies = Object.FindObjectsByType<EnemyAI>(FindObjectsSortMode.None);
foreach (EnemyAI enemy in allEnemies) {
if (enemy.canSeePlayer) {
// Trigger Game Over
}
}
Use Case
An indie developer is making a top-down stealth game where the player turns red when an enemy sees them.
- The Action: The player's script queries the nearest enemy's
canSeePlayerevery frame. - The Implementation: The script uses a
foreachloop to check the vision status of all active guards. - The Result: The moment any guard's
canSeePlayerbecomes true, the player's sprite renderer color is swapped, providing immediate visual feedback.
Best Results
| Method | When to Use | Performance Impact |
|---|---|---|
| FindWithTag | Single, unique enemies | Low (if called in Start) |
| FindObjectsByType | Checking multiple guards | High (Avoid calling in Update) |
| Singleton Pattern | One global "Vision Manager" | Lowest |
| Trigger/Collision | When objects touch | Very Low |
FAQ
Why do I get a "NullReferenceException"?
This usually means GetComponent failed to find the script. Ensure the script name in the brackets <EnemyAI> exactly matches the class name of the script attached to your enemy object.
Can I access private variables this way?
No. To maintain security and encapsulation, only public variables are accessible. If you must keep the variable private, use a public "Getter" function in the enemy script instead.
Is calling GetComponent in Update() bad?
Yes. GetComponent is expensive. Best practice for 2026 is to "cache" the reference in Start() and only use the variable in Update().
Disclaimer
Directly accessing properties between scripts can lead to "tight coupling," making your code harder to debug as the project grows. For large-scale 2026 projects, consider using C# Events or a Delegate system to notify the player when they are seen, rather than constantly checking the enemy's variables. Always ensure your GameObjects are properly tagged to avoid "Object not found" errors. March 2026.
Tags: UnityTutorial, CSharpScripting, GameDevAI, ScriptCommunication
