---
title: คุณใช้ Singleton อย่างไร?
slug: world-sdk-guide-th/singleton
docTags: 
createdAt: 2024-09-02T08:34:13.136Z
---

ซิงเกิลตัน (Singleton) เป็นรูปแบบการออกแบบที่รับประกันว่ามีเพียงหนึ่งอินสแตนซ์ของคลาสเฉพาะในโปรแกรมเท่านั้น

รูปแบบซิงเกิลตันให้มีอินสแตนซ์เดียวทั่วโลกของคลาส ทำให้สามารถเข้าถึงได้ง่ายจากสคริปต์อื่น ๆ ที่ต้องการ เช่น การจัดการตรรกะ เสียง UI และทรัพยากรที่รวมศูนย์ภายในโลก

ใน 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>();`
:::

มานำซิงเกิลตันไปใช้ในการจัดการ UI ในตัวอย่างกันเถอะ:

1\) เพิ่ม UI > ข้อความ และปุ่มลงในฉาก

- ตั้งค่าตรรกะเพื่อเพิ่มคะแนนเมื่อกดปุ่ม "เพิ่มคะแนน"
- ตั้งค่าตรรกะเพื่อลดคะแนนเมื่อกดปุ่ม "ลดคะแนน"

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



2\) สร้างสคริปต์ชื่อ "ScoreManager" ซึ่งจะใช้ Singleton.

- สคริปต์ ScoreManager จะรับผิดชอบในการเพิ่ม/ลดคะแนนและอัปเดตข้อความเมื่อถูกเรียกจากสคริปต์อื่น ๆ.

```typescript
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { GameObject } from 'UnityEngine';
import { Text } from 'UnityEngine.UI';
 
export default class ScoreManager extends ZepetoScriptBehaviour {
 
    // การประกาศ Singleton
    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\) หลังจากเขียนสคริปต์แล้ว ให้กลับไปที่ Inspector และเชื่อมต่อกับคอมโพเนนต์ Text.

::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" เพื่อแสดงวิธีการเรียกใช้ Singleton ให้แน่ใจว่า 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';
// นำเข้าสคริปต์ Singleton
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(()=> {
            // เรียกใช้ฟังก์ชันที่ประกาศใน Singleton
            this.ScoreManager.IncreaseScore(10);
        });
 
        this.decreaseScoreButton.onClick.AddListener(()=> {
            // เรียกใช้ฟังก์ชันที่ประกาศใน Singleton
            this.ScoreManager.DecreaseScore(10);
        });
    }
}
```



- การระบุเส้นทางให้ถูกต้องเมื่อดึงสคริปต์ Singleton เป็นสิ่งสำคัญ
- คุณสามารถปรับส่วนที่เรียก ScoreManager ในสคริปต์ของคุณตามที่ต้องการ



5\) กดปุ่ม \[▶︎(เล่น)] เพื่อทดสอบ

- คุณควรสังเกตฟังก์ชันใน ScoreManager ที่ถูกเรียกเมื่อคุณคลิกปุ่มใน ScoreLogicSample ทำให้มันทำงานตามที่คาดหวัง

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

