---
title: 如何使用单例模式？
slug: world-sdk-guide-ch/B2aioSO7s_VQPR2t-WW1F
docTags: 
createdAt: 2024-09-02T08:34:13.136Z
---

单例是一种设计模式，确保在程序中只有一个特定类的实例。

单例模式提供了一个类的全局唯一实例，使其可以从其他需要它的脚本中轻松访问，例如管理逻辑、音频、用户界面和世界中的集中资源。

在ZEPETOScript中，您可以通过以下方式实现单例：

```typescript
private static _instance: ClassName = null;

public static get Instance(): ClassName {
	if (this._instance == null) {
		this._instance = GameObject.FindObjectOfType<ClassName>();
	}
	return this._instance;
}
```

:::hint{type="success"}
**👍 提示**

- 如果场景中已经有一个附加了单例脚本的GameObject，您可以使用这种格式。
- 如果没有，请添加代码以创建GameObject。
  - 示例： `new GameObject("ObjectName").AddComponent<ClassName>();`
:::

让我们实现一个用于管理用户界面的单例示例：

1\) 将UI > 文本和按钮添加到场景中。

- 设置逻辑，当按下“增加分数”按钮时增加分数
- 设置逻辑，当按下“减少分数”按钮时减少分数

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-WA4wOFac329w01mfJQcc3-20240904-102422.png)



2\) 创建一个名为 "ScoreManager" 的脚本，其中将应用单例模式。

- ScoreManager 脚本将负责增加/减少分数，并在从其他脚本调用时更新文本。

```typescript
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { GameObject } from 'UnityEngine';
import { Text } from 'UnityEngine.UI';
 
export default class ScoreManager extends ZepetoScriptBehaviour {
 
    // 单例声明
    private static _instance: ScoreManager = null;
 
    public static get Instance(): ScoreManager {
        if (this._instance == null) {
            this._instance = GameObject.FindObjectOfType<ScoreManager>();
        }
 
        return this._instance;
    }
 
    // 变量声明
    public scoreText: Text;
    private _currentScore : number;
 
    Start() {   
        // 将初始分数设置为 0 以进行测试
        this._currentScore = 0;
    }
 
    // 其他脚本可以调用 IncreaseScore
    public IncreaseScore(amount: number) {
        this._currentScore += amount;
        this.scoreText.text = `分数 : ${this._currentScore}`;
    }
 
    // 其他脚本可以调用 DecreaseScore
    public DecreaseScore(amount: number) {
        this._currentScore -= amount;
        this.scoreText.text = `分数 : ${this._currentScore}`;
    }
 
}

```



- 脚本描述
  - private static \_instance: 这是类中的一个私有静态变量，初始值为 null。
  - public static get Instance: 这个静态属性提供了一种方法，让外部代码可以访问这个类的唯一实例。
  - 检查 `if (this.\_instance == null)`. 如果它为 null，使用 GameObject.FindObjectOfType\<>() 查找并返回类型为 ClassName 的组件，并将其分配给静态变量。



3\) 编写脚本后，返回检查器并连接文本组件。

::Image[]{src="https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-ORrY57RIDdF3i0v1Rh0F9-20240904-102422.png" size="76" width="300" height="264" position="center" showCaption="false"}



4\) 接下来，创建一个名为 "ScoreLogicSample" 的脚本，以演示如何调用单例。确保 ScoreManager 和 ScoreLogicSample 在同一目录中。

::Image[]{src="https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-J04ZZYJgBRuWFp5mI6tJ2-20240904-102422.png" size="62" width="247" height="146" position="center" showCaption="false"}

- 像这样编写代码：

```typescript
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { GameObject } from 'UnityEngine';
import { Text, Button } from 'UnityEngine.UI';
// 导入单例脚本
import ScoreManager from './ScoreManager';
 
export default class ScoreLogicSample extends ZepetoScriptBehaviour {
 
    public increaseScoreButton: Button;
    public decreaseScoreButton: Button;
 
    // 声明 ScoreManager 类型的变量
    private ScoreManager : ScoreManager;
 
    Start() {   
 
        // 将 ScoreManager 分配给变量
        this.ScoreManager = GameObject.FindObjectOfType<ScoreManager>();
 
        this.increaseScoreButton.onClick.AddListener(()=> {
            // 调用单例中声明的函数
            this.ScoreManager.IncreaseScore(10);
        });
 
        this.decreaseScoreButton.onClick.AddListener(()=> {
            // 调用单例中声明的函数
            this.ScoreManager.DecreaseScore(10);
        });
    }
}
```



- 在获取单例脚本时，正确指定路径是很重要的。
- 您可以根据需要调整在您自己的脚本中调用 ScoreManager 的部分。



5\) 按下 \[▶︎(播放)] 按钮进行测试。

- 当您点击 ScoreLogicSample 中的按钮时，您应该观察到 ScoreManager 中的函数被调用，使其按预期工作。

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-nLqzRvwNUFM7TJ48BWbYl-20240904-102422.gif)

