A Singleton is a design pattern that ensures there is only one instance of a particular class within a program.
The Singleton pattern provides a single global instance of a class, making it easily accessible from other scripts that need it, such as managing logic, audio, UI, and centralized resources within the world.
In ZEPETOScript, you can implement a Singleton in the following way:
private static _instance: ClassName = null;
public static get Instance(): ClassName {
if (this._instance == null) {
this._instance = GameObject.FindObjectOfType<ClassName>();
}
return this._instance;
}
Tips
- If there is already a GameObject with a Singleton script attached in the Scene, you can use this format.
- If there isn't one, add code to create the GameObject.
- Example:
new GameObject("ObjectName").AddComponent<ClassName>();
Let's implement a Singleton for managing UI in an example:
- Add UI > Text and Button to the Scene.
- Set up the logic to increase the score when the "IncreaseScore" button is pressed
- Set up the logic to decrease the score when the "DecreaseScore" button is pressed
- Create a script called "ScoreManager," where the Singleton will be applied.
- The ScoreManager script will be responsible for increasing/decreasing the score and updating the Text when called from other scripts.
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { GameObject } from 'UnityEngine';
import { Text } from 'UnityEngine.UI';
export default class ScoreManager extends ZepetoScriptBehaviour {
// Singleton declaration
private static _instance: ScoreManager = null;
public static get Instance(): ScoreManager {
if (this._instance == null) {
this._instance = GameObject.FindObjectOfType<ScoreManager>();
}
return this._instance;
}
// Variable declaration
public scoreText: Text;
private _currentScore : number;
Start() {
// Set initial score to 0 for testing
this._currentScore = 0;
}
// Other scripts can call IncreaseScore
public IncreaseScore(amount: number) {
this._currentScore += amount;
this.scoreText.text = `Score : ${this._currentScore}`;
}
// Other scripts can call DecreaseScore
public DecreaseScore(amount: number) {
this._currentScore -= amount;
this.scoreText.text = `Score : ${this._currentScore}`;
}
}
- Script Description
- private static _instance: This is a private static variable within the class, initially set to null.
- public static get Instance: This static property provides a way for external code to access the unique instance of this class.
- Check
if (this.\_instance == null)
. If it’s null, use GameObject.FindObjectOfType<>() to find and return a component of type ClassName, and assign it to the static variable.
- After writing the script, return to the Inspector and connect the Text component.
- Next, create a script called "ScoreLogicSample" to demonstrate how to call the Singleton. Ensure that ScoreManager and ScoreLogicSample are in the same directory.
- Write code like this:
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { GameObject } from 'UnityEngine';
import { Text, Button } from 'UnityEngine.UI';
// Import Singleton script
import ScoreManager from './ScoreManager';
export default class ScoreLogicSample extends ZepetoScriptBehaviour {
public increaseScoreButton: Button;
public decreaseScoreButton: Button;
// Declare variable of type ScoreManager
private ScoreManager : ScoreManager;
Start() {
// Assign ScoreManager to the variable
this.ScoreManager = GameObject.FindObjectOfType<ScoreManager>();
this.increaseScoreButton.onClick.AddListener(()=> {
// Call the function declared in Singleton
this.ScoreManager.IncreaseScore(10);
});
this.decreaseScoreButton.onClick.AddListener(()=> {
// Call the function declared in Singleton
this.ScoreManager.DecreaseScore(10);
});
}
}
- It's important to specify the path correctly when getting the Singleton script.
- You can adapt the part where ScoreManager is called in your own script as needed.
- Press the [▶︎(play)] button to test.
- You should observe the functions in ScoreManager being called when you click the buttons in ScoreLogicSample, making it work as expected.