---
title: Menggunakan Fungsi Obrolan Suara
slug: world-sdk-guide-id/menggunakan-fungsi-obrolan-suara
docTags: 
createdAt: 2024-09-02T08:34:13.134Z
---

Paket versi prapengguna Zepeto.Voice.Chat memungkinkan obrolan suara di Dunia.



## Instal ZEPETO.Voice.Chat dan atur mode

1\) Instal Window → Package Manager → ZEPETO.Voice.Chat.

:::hint{type="danger"}
- Fitur ini tersedia di Dunia di mana elemen multiplayer diterapkan.
- Pengujian hanya tersedia di pengujian seluler, bukan pengujian editor.
- Karena kebijakan iOS, volume perangkat tidak turun menjadi nol ketika mikrofon dihidupkan di dunia dengan obrolan suara yang diaktifkan.
  Volume perangkat akan turun menjadi nol ketika mikrofon dimatikan.
:::



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

2\) Klik tombol \[▼] di menu tengah layar proyek Unity yang sedang dikembangkan.
Klik tombol \[Buka Pengaturan Dunia] di menu pop-up yang muncul.

::Image[]{src="https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-FKLyhsT_NpGSs69hIudps-20240904-102425.png" size="72" width="362" height="224" position="center" showCaption="false"}



3\) Jika paket ZEPETO.Voice.Chat terinstal dengan benar, Anda akan melihat opsi Mode Obrolan Suara ditambahkan.

::Image[]{src="https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-mT_dx8P_ZKL9pl4pcE7-X-20240904-102425.png" size="62" width="416" height="453" position="center" showCaption="false"}



4\) Dalam Mode Obrolan Suara, silakan atur mode yang diinginkan.

- Dasar: Gunakan fitur obrolan suara yang disediakan secara default.
- Skrip: Gunakan fitur obrolan suara dengan menerapkan API obrolan suara.
  - Anda dapat memproses akses masuk/keluar ruangan untuk obrolan suara saat runtime.
  - Terapkan obrolan suara untuk tim yang berbeda (misalnya, obrolan suara tim merah dan obrolan suara tim biru)
  - Mendeteksi pengguna yang sedang berbicara saat ini



## Mode Dasar: Menggunakan Fitur Obrolan Suara

Sebuah dunia dengan obrolan suara Mode Dasar terlihat seperti ini.

Anda juga dapat membuat obrolan suara yang lebih menghibur menggunakan fitur modifikasi suara.

Obrolan suara secara otomatis diaktifkan saat memasuki Dunia dengan fungsi obrolan suara.

:::hint{type="success"}
**👍&#x20;**&#x53;aat pertama kali Anda menggunakan fitur obrolan suara di ZEPETO, pop-up mengenai akses mikrofon akan muncul.
Anda harus mengizinkan akses untuk menggunakan fungsi obrolan suara.
:::

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-1uuwxj2Ex-naVmnnoFpi2-20240904-102426.png "Ketika Anda mengaktifkan fitur obrolan suara, sebuah tombol secara otomatis muncul di UI")

![Anda dapat menggunakannya dengan menyentuh tombol obrolan suara](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-vVNrp9SxpJYzvoAy8gXAg-20240904-102425.png "Anda dapat menggunakannya dengan menyentuh tombol obrolan suara")



:::hint{type="danger"}
- Di aplikasi ZEPETO 3.26.000 dan yang lebih baru, ikon pembicara obrolan suara tidak muncul.
- Jika Anda ingin membuat ikon pidato muncul, silakan ganti ke Mode Skrip dan ikuti panduan untuk menulis kode Anda sendiri.
:::



## Mode Skrip : Menggunakan API VoiceChat

Mode Skrip memungkinkan obrolan suara di saluran yang dipisahkan oleh tim.

Silakan merujuk ke deskripsi fungsi dan contoh di bawah ini untuk mengimplementasikan fitur tersebut.

| **API**                                 | **Deskripsi**                                                                                                                                                                                                          |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OnInitializedEvent                      | API obrolan suara tersedia setelah peristiwa True terjadi dalam peristiwa inisialisasi.<br />Jika peristiwa ini True, obrolan suara tersedia, dan jika False, obrolan suara tidak tersedia.                            |
| EnterRoom(RoomProperty roomProperty)    | Fungsi untuk masuk ke ruang obrolan suara<br />- Setelah berhasil masuk ke ruang obrolan suara, tombol obrolan suara akan muncul                                                                                       |
| ExitRoom()                              | Fungsi untuk meninggalkan ruang obrolan suara                                                                                                                                                                          |
| OnRoomConnectedEvent                    | Sebuah peristiwa untuk memeriksa status masuk ke ruang obrolan suara.<br />Jika peristiwa ini benar, pengguna telah masuk ke ruang obrolan suara; jika salah, pengguna telah meninggalkan ruang obrolan suara.         |
| OnSpeechDetectedEvent\<string, boolean> | Peristiwa untuk mendeteksi pengguna yang sedang berbicara dalam obrolan suara.<br />- string adalah userId dari pengguna yang berbicara<br />- boolean adalah true ketika ucapan dimulai, false ketika ucapan berakhir |
| ChangeTeamID(number teamid)             | Fungsi untuk mengubah TeamId yang digunakan dalam ruang obrolan suara<br />- Hanya dapat diatur ke nilai int 1 atau lebih                                                                                              |

### Kelas RoomProperty

| **API**      | **Deskripsi**                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| SetAudioMode | Mode audio yang digunakan dalam obrolan suara<br />- **AudioMode.Omnidirectional:** Mode obrolan suara tanpa pengurangan suara berdasarkan jarak<br />(Anda dapat menggunakannya dengan atau tanpa karakter ZEPETO)<br /><br /><br />- **AudioMode.Directional:** Mode obrolan suara dengan pengurangan suara berdasarkan jarak<br />(Karakter ZEPETO harus ada di Scene, karena mode ini bekerja berdasarkan lokasi karakter ZEPETO) |
| SetTeamID    | TeamId yang digunakan dalam obrolan suara untuk mengaktifkan obrolan suara antara pengguna dengan TeamId yang sama.<br />- Hanya dapat diatur ke nilai int 1 atau lebih                                                                                                                                                                                                                                                               |

### Contoh implementasi obrolan suara spesifik tim

Berikut adalah beberapa contoh kode untuk mencoba API Obrolan Suara.

1\) Tambahkan tombol dan catat teks ke kanvas seperti yang ditunjukkan pada gambar di bawah untuk masuk ke saluran tim Voice Chat dan menampilkan log status.

- Tombol
  - Button\_blueTeam : Tombol masuk voice chat tim biru
  - Button\_redTeam : Tombol masuk voice chat tim merah
  - Button\_exit : Tombol keluar dari voice chat
- Teks
  - Text\_log : Teks untuk menampilkan log chat
  - Text\_team : Teks untuk menampilkan daftar anggota saluran tim voice chat yang sama
  - Text\_currentSpeaking : Teks untuk menampilkan UserId yang sedang berbicara di voice chat.

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-euodAMUXM6E3-jg4tSzzL-20240904-102425.png)



2\) Buat Proyek > Buat > ZEPETO > TypeScript dan ganti namanya menjadi VoiceChatTest.

3\) Tulis skrip contoh seperti yang ditunjukkan di bawah ini.

:::CodeblockTabs
VoiceChatTest

```typescript
import { Button, InputField, Text } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { AudioMode, RoomProperty, VoiceChatController } from 'ZEPETO.Voice.Chat'
 
export default class VoiceChatTest extends ZepetoScriptBehaviour {
 
    // Deklarasikan komponen UI sebagai anggota publik
    public BlueTeamButton: Button;
    public RedTeamButton: Button;
    public exitRoomButton: Button;
    public logText: Text;
    public currentTeamIDText: Text;
    public currentSpeakingUserIDsText: Text;
     
    // Deklarasikan anggota privat untuk menyimpan ID pengguna yang berbicara dan kolom input ID tim
    private currentSpeakingUserIDs: string[];   
    private teamIDInputField: InputField;
 
    Start() {
        this.currentSpeakingUserIDs = new Array();
         
        // Tambahkan pendengar acara untuk klik tombol
        this.BlueTeamButton.onClick.AddListener(()=>{
            this.EnterBlueTeam();
        });
        this.RedTeamButton.onClick.AddListener(()=>{
            this.EnterRedTeam();
        });
        this.exitRoomButton.onClick.AddListener(()=>{
            this.ExitVoiceChatRoom();
        });
 
        // Tambahkan pendengar acara untuk Pengontrol Suara Chat
        VoiceChatController.OnInitializedEvent.AddListener(init => this.OnInitialized(init));
        VoiceChatController.OnRoomConnectedEvent.AddListener(connected => this.OnRoomConnected(connected));
        VoiceChatController.OnSpeechDetectedEvent.AddListener((userId, speechDetected) => this.OnSpeechDetected(userId, speechDetected));
         
        this.logText.text = "[VoiceChat] VoiceChatTest Mulai";
    }
 
    // Metode OnDestroy dipanggil saat skrip dihancurkan
    OnDestroy() {
        VoiceChatController.OnInitializedEvent.RemoveAllListeners();
        VoiceChatController.OnRoomConnectedEvent.RemoveAllListeners();
        VoiceChatController.OnSpeechDetectedEvent.RemoveAllListeners();
    }
 
    // Metode yang dipanggil saat sistem Suara Chat diinisialisasi
    private OnInitialized(initialized: boolean) {
        this.logText.text = "[VoiceChat] OnInitialized: " + initialized;
    }
 
     // Metode yang dipanggil saat ruang Suara Chat terhubung
    private OnRoomConnected(connected: boolean) {
        this.logText.text = "[VoiceChat] OnRoomConnected: " + connected;
    }
 
    // Metode yang dipanggil saat ucapan pengguna terdeteksi atau tidak terdeteksi
    private OnSpeechDetected(userId: string, speechDetected: boolean) {
        this.logText.text = "[VoiceChat] OnSpeechDetected: " + userId + ", " + speechDetected;
 
        if (speechDetected) {
            this.currentSpeakingUserIDs.push(userId);
        }
        else {
            let index = this.currentSpeakingUserIDs.indexOf(userId);
            this.currentSpeakingUserIDs.splice(index, 1);
        }
 
        let userIds = "[CurrentSpeakingUserIDs]\n";
        for (let i = 0; i < this.currentSpeakingUserIDs.length; i++) {
            userIds += this.currentSpeakingUserIDs[i];
            userIds += "\n";
        }
 
        this.currentSpeakingUserIDsText.text = userIds;
    }
 
    // Metode untuk masuk ke ruang Suara Chat tim biru
    public EnterBlueTeam(){
        this.EnterVoiceChatRoom(2);
    }
 
    // Metode untuk masuk ke ruang Suara Chat tim merah
    public EnterRedTeam(){
        this.EnterVoiceChatRoom(3);
    }
 
    // Metode untuk masuk ke ruang Suara Chat berdasarkan indeks tim yang diberikan
    private EnterVoiceChatRoom(teamIndex: number) {
        console.log("[VoiceChat] EnterVoiceChatRoom");
 
        // Buat objek RoomProperty baru dan atur propertinya
        let roomProperty = new RoomProperty();
        roomProperty.SetAudioMode(AudioMode.Omnidirectional);
        roomProperty.SetTeamID(teamIndex);
        VoiceChatController.EnterRoom(roomProperty);
        this.currentTeamIDText.text = "TeamID: " + roomProperty.TeamId.toString();
    }
 
    // Metode untuk keluar dari ruang Suara Chat
    public ExitVoiceChatRoom() {
        this.logText.text = "[VoiceChat] ExitVoiceChatRoom";
        VoiceChatController.ExitRoom();
    }
 
    // Metode untuk mengubah ID tim untuk pengguna saat ini
    public ChangeTeamID() {
        // Dapatkan ID tim baru dari kolom input dan parse sebagai integer
        let teamID = parseInt(this.teamIDInputField.text);
        this.logText.text = "[VoiceChat] ChangeTeamID: " + teamID;
        this.currentTeamIDText.text = "TeamID: " + teamID.toString();
        // Ubah ID tim dalam sistem Suara Chat
        VoiceChatController.ChangeTeamID(teamID);
    }
 
}
```
:::



- Deskripsi Kode
  - Ketika skrip dijalankan, itu akan mendaftarkan sebuah acara pada setiap tombol di fungsi Start() dan mendaftarkan acara OnInitialized, OnRoomConnected, dan OnSpeechDetected pada VoiceChatController.
  - Ketika tombol Tim Biru atau tombol Tim Merah diklik, fungsi EnterVoiceChatRoom() dieksekusi dan pengguna masuk ke ruang obrolan suara dengan memasukkan RoomProperty yang ditentukan. Properti ruangan dalam contoh adalah sebagai berikut.
    - **roomProperty.SetAudioMode :** AudioMode.Omnidirectional. Mode audio Omnidirectional adalah mode di mana volume terdengar sama terlepas dari posisi pemain. Sebaliknya, mode Directional adalah mode suara 3D, yang berarti bahwa volume akan terdengar berbeda tergantung pada posisi karakter, jadi semakin jauh karakter, semakin rendah volumenya.
    - **roomProperty.SetTeamID :** Saluran 2 untuk Tim Biru, Saluran 3 untuk Tim Merah. SetTeamID berfungsi seperti saluran dalam Obrolan Suara. Sebuah tim yang masuk ke saluran 2 hanya dapat obrolan suara dengan pemain di saluran 2, dan sebuah tim yang masuk ke saluran 3 hanya dapat obrolan suara dengan pemain di saluran 3.
  - ExitVoiceChatRoom() akan keluar dari saluran tim obrolan suara saat ini.
  - OnSpeechDetected() akan mengeluarkan ID pemain yang saat ini menggunakan obrolan suara di saluran tim ke teks log.



4\) Setelah menyelesaikan skrip, tetapkan tombol dan teks yang dibuat di Langkah 1 di inspector.

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



5\) Jalankan tes di ponsel melalui kode QR atau tautan tes, dan Anda dapat melihat bahwa tombol aktivasi obrolan suara dibuat ketika tombol Masuk Tim ditekan, dan setiap kali seorang pemain berbicara, log menunjukkan pemain mana yang sedang dalam obrolan suara, seperti yang ditunjukkan di layar berikut.

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



### Contoh menampilkan gambar gelembung ucapan obrolan suara

Di Aplikasi ZEPETO versi 3.26.000 dan yang lebih baru, ikon ucapan obrolan suara tidak muncul.
Jika Anda ingin menangani ikon ucapan agar muncul, silakan ikuti panduan dan tulis kode Anda sendiri.

1\) Untuk menampilkan gelembung ucapan di atas kepala karakter ketika pemain berada dalam obrolan suara, Anda perlu membuat prefab yang menggunakan gambar gelembung ucapan. Impor gambar PNG gelembung ucapan yang ingin Anda gunakan seperti yang ditunjukkan di bawah ini dan ubah Tipe Teksturnya menjadi Sprite.

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



2\) Proyek > Buat > Prefab dan ganti namanya menjadi ChatBubble.

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-FAeAB-SKLLJO2mSUsRMYI-20240904-102425.png)



3\) Klik dua kali prefab ChatBubble untuk masuk ke mode pengeditan prefab. Pilih prefab ChatBubble dan pilih Transform > Posisi > Ubah nilai Y menjadi 0.35.

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



4\) Buat Canvas di dalam objek prefab.

- Klik dua kali pada prefab ChatBubble untuk masuk ke mode Edit Prefab, dan kemudian tambahkan Hierarchy > UI > Canvas.
- Ubah nilai komponen RectTransform dari Canvas menjadi sebagai berikut
  - PosX: 0 , posY: 0
  - Lebar: 100, tinggi: 100
  - SkalaX: 0.005, SkalaY: 0.005, SkalaZ: 0.005
- Ubah RenderMove dari komponen Canvas menjadi World Space.

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



5\) Buat gambar gelembung ucapan di dalam Canvas.

- Tambahkan Hierarchy > UI > Image sebagai anak dari Canvas, dan ganti namanya menjadi ChatBubbleImage.
- Ubah nilai komponen RectTransform dari ChatBubbleImage menjadi sebagai berikut
  - Lebar 42, Tinggi:42
- Daftarkan Sprite Gambar yang Anda impor di langkah 1 sebagai Gambar Sumber di Komponen Gambar.

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



:::hint{type="success"}
👍 **TIP**

- Anda juga dapat menganimasi sprite gambar gelembung bicara.
- Anda juga dapat menggunakan gambar gelembung terpisah untuk tim yang berbeda.
:::



6\) Proyek > Buat > ZEPETO > Buat TypeScript dan ganti namanya menjadi VoiceChatBubbleController.

7\) Tulis skrip contoh seperti yang ditunjukkan di bawah ini.

:::CodeblockTabs
VoiceChatBubbleController

```typescript
import { GameObject, Object } from 'UnityEngine';
import { KnowSockets, ZepetoPlayers } from 'ZEPETO.Character.Controller'
import { ZepetoScriptBehaviour } from 'ZEPETO.Script'
import { AudioMode, RoomProperty, VoiceChatController } from 'ZEPETO.Voice.Chat';
 
export default class VoiceChatBubbleController extends ZepetoScriptBehaviour {
 
    // Variabel GameObject publik untuk menyimpan prefab gelembung obrolan suara
    public voiceChatPrefab: GameObject;
 
    // Peta privat untuk menyimpan GameObjects yang terkait dengan ID pengguna
    private _voiceBubbleMap: Map<string, GameObject> = new Map<string, GameObject>();
 
    Start() {
        // Tambahkan pendengar acara untuk Kontrol Obrolan Suara
        VoiceChatController.OnInitializedEvent.AddListener(init => this.OnInitialized(init));
        VoiceChatController.OnRoomConnectedEvent.AddListener(connected => this.OnRoomConnected(connected));
        VoiceChatController.OnSpeechDetectedEvent.AddListener((userId, speechDetected) => this.OnSpeechDetected(userId, speechDetected));
    }
 
    // Metode yang dipanggil ketika sistem Obrolan Suara diinisialisasi
    private OnInitialized(initialized: boolean) {
        console.log("[VoiceChat] OnInitialized: ");
        this.EnterVoiceChatRoom(1);
    }
 
    // Metode yang dipanggil ketika ruang Obrolan Suara terhubung
    private OnRoomConnected(connected: boolean) {
        console.log("[VoiceChat] OnRoomConnected: ");
    }
 
    // Metode untuk masuk ke ruang Obrolan Suara berdasarkan indeks tim yang diberikan
    private EnterVoiceChatRoom(teamIndex: number) {
        console.log("[VoiceChat] EnterVoiceChatRoom");
 
        // Buat objek RoomProperty baru dan atur propertinya
        let roomProperty = new RoomProperty();
        roomProperty.SetAudioMode(AudioMode.Omnidirectional);
        VoiceChatController.EnterRoom(roomProperty);
    }
 
    // Metode yang dipanggil ketika ucapan pengguna terdeteksi atau tidak terdeteksi
    private OnSpeechDetected(userId: string, speechDetected: boolean) {
        console.log("[VoiceChat] OnSpeechDetected: " + userId + ", " + speechDetected);
 
        // Periksa apakah ID pengguna tidak ada dalam peta gelembung suara dan buat gelembung suara jika tidak ada
        if (!this._voiceBubbleMap.has(userId)) {
            this.CreateVoiceBubble(userId);
        }
 
        this.SetVoiceBubble(userId, speechDetected);
    }
 
    // Metode untuk mengatur status aktif gelembung suara untuk ID pengguna tertentu
    private SetVoiceBubble(userId: string, speechDetected: boolean) {
        const chatBubble = this._voiceBubbleMap.get(userId);
        chatBubble.SetActive(speechDetected);
    }
 
    // Metode untuk membuat gelembung suara untuk ID pengguna tertentu
    private CreateVoiceBubble(userId: string) {
 
        // Dapatkan soket kepala karakter pengguna
        const headSocket = ZepetoPlayers.instance.GetPlayerWithUserId(userId).character.GetSocket(KnowSockets.HEAD_UPPER);
 
        // Instansiasi prefab gelembung obrolan suara di posisi soket kepala
        const instanceBubble = Object.Instantiate(this.voiceChatPrefab, headSocket) as GameObject;
 
        // Tambahkan gelembung yang diinstansiasi ke peta gelembung suara
        this._voiceBubbleMap.set(userId, instanceBubble);
        instanceBubble.SetActive(false);
    }
 
    LateUpdate() {

        // Periksa apakah peta gelembung suara kosong dan kembali jika kosong
        if (this._voiceBubbleMap.size === 0) {
            return;
        }

        // Iterasi melalui peta gelembung suara dan perbarui rotasi setiap objek gelembung GameObject
        this._voiceBubbleMap.forEach((bubbleObject: GameObject) => {
            // Atur rotasi objek gelembung agar sesuai dengan rotasi transformasi induk kamera
            bubbleObject.transform.rotation = ZepetoPlayers.instance.ZepetoCamera.cameraParent.transform.rotation;
        });

    }
 
}
```
:::



- Deskripsi Kode
  - Ketika skrip dijalankan, itu akan mendaftarkan peristiwa pada setiap tombol di fungsi Start() dan peristiwa OnInitialized, OnRoomConnected, dan OnSpeechDetected di VoiceChatController.
  - Setelah OnInitialized(), tombol Voice Chat akan ditampilkan di layar pemain ketika mereka memasuki dunia, dan ketika mereka menekan tombol, EnterVoiceChatRoom() akan dijalankan untuk masuk ke ruang Voice Chat.
  - Setiap kali pemain mengaktifkan VoiceChat dan berbicara, OnSpeechDetected() dijalankan, dan jika speechDetected adalah true, objek BubbleChat diaktifkan, dan jika false, dinonaktifkan.
  - Pertama kali fungsi OnSpeechDetected() diaktifkan, CreateVoiceBubble() akan menginstansiasi GameObject voiceChatPrefab untuk mengapung di atas kepala pemain dan mendaftarkannya sebagai data peta di \_voiceBubbleMap.
  - Kami menggunakan LateUpdate() untuk memperbarui rotasi gelembung obrolan suara setiap frame agar sesuai dengan CameraParent dari dunia ZEPETO. Ini memastikan bahwa gambar gelembung ucapan selalu menghadap kamera. Pertama, memeriksa apakah \_voiceBubbleMap kosong, jika tidak, memperbarui rotasi gambar gelembung ucapan prefab.



8\) Setelah selesai menulis skrip, tetapkan entri VoiceChatPrefab di inspector sebagai prefab gelembung ucapan yang Anda buat di LANGKAH 1.

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



9\) Jalankan di perangkat mobile melalui kode QR atau tautan uji dan Anda harus melihat gambar gelembung ucapan muncul di atas kepala karakter setiap kali pemain menggunakan obrolan suara.



## Modulasi Suara

Mulai dengan versi Voice Chat 0.2.1-preview, Anda dapat memodulasi suara Voice Chat dalam Mode Skrip.

::embed[[https://www.youtube.com/watch?v=yXfPuQyPbqk](https://www.youtube.com/watch?v=yXfPuQyPbqk)]{url="https://www.youtube.com/watch?v=yXfPuQyPbqk"}



Cobalah modifikasi suara menggunakan panduan API dan kode contoh.

| **TipeSuara (enum)** | **Nilai** | **Deskripsi** |
| -------------------- | --------- | ------------- |
| Tipe00               | 0         | Asli          |
| Tipe01               | 1         | Chipmunk      |
| Tipe02               | 2         | Paman         |
| Tipe03               | 3         | Echo          |
| Tipe04               | 4         | Suara Dalam   |
| Tipe05               | 5         | Robot         |
| Tipe06               | 6         | Dialek        |
| Tipe07               | 7         | Megafon       |
| Tipe08               | 8         | Binatang      |
| Tipe09               | 9         | Mesin         |
| Tipe10               | 10        | Arus Kuat     |
| Tipe11               | 11        | Anak          |
| Tipe12               | 12        | Landak        |



Berikut adalah contoh skrip modifikasi suara.

```javascript
import { Button } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { RoomProperty, VoiceChatController, VoiceType } from 'ZEPETO.Voice.Chat';

export default class VoiceModulationManager extends ZepetoScriptBehaviour {
 
    // Tombol untuk mengatur berbagai jenis suara
    public buttons: Button[];
 
    Start() {
        const voiceTypes = [
            VoiceType.Type00,
            VoiceType.Type01,
            VoiceType.Type05,
            VoiceType.Type03,
        ];
 
        for (const [index, button] of this.buttons.entries()) {
            button.onClick.AddListener(() => {
                // Atur jenis suara yang sesuai dengan indeks tombol yang diklik
                VoiceChatController.SetVoiceType(voiceTypes[index]);
            });
        };
 
        // Metode yang dipanggil ketika sistem Voice Chat diinisialisasi
        VoiceChatController.OnInitializedEvent.AddListener(
            init => {
                VoiceChatController.EnterRoom(new RoomProperty());;
            }
        );
 
        // Metode yang dipanggil ketika ruang Voice Chat terhubung
        VoiceChatController.OnRoomConnectedEvent.AddListener(
            connected => {
                // Atur jenis suara awal dan aktifkan loopback
                VoiceChatController.SetVoiceType(voiceTypes[0]);
                VoiceChatController.EnableLoopback(true);
            }
        );
    }
 
    // Metode untuk keluar dari ruang Voice Chat
    OnDestroy() {
        VoiceChatController.OnInitializedEvent.RemoveAllListeners();
        VoiceChatController.OnRoomConnectedEvent.RemoveAllListeners();
    }
}
```

- Deskripsi Kode:
  - Menambahkan pendengar onClick untuk setiap tombol untuk mengatur jenis modifikasi suara yang berbeda.
    - Elemen dengan indeks yang sama di dalam `tombol` array dan `jenisSuara` array dicocokkan.
  - Setelah memasuki dunia, `VoiceChatController` diinisialisasi, dan koneksi ruangan dibuat secara otomatis.
  - Jenis modifikasi suara awal diatur ke `Tipe00`, dan loopback diaktifkan untuk mendengar suara Anda sendiri.
    - Perhatikan bahwa untuk pemanggilan `SetVoiceType` dan `EnableLoopback`, koneksi ruangan diperlukan. Oleh karena itu, pengaturan awal ditangani dalam pendengar dari`OnRoomConnectedEvent`.



![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-gDF6X-7KgtHpythXUaKcU-20240904-102426.png)



## Ubah lokasi pemutaran audio pemain lokal



Anda dapat mengubah lokasi obrolan suara pemain lokal menggunakan `VoiceChatController.SetLocalPlayerTransform()`.

Menggunakan ini, Anda dapat membuat berbagai skenario dengan mengatur lokasi Anda ke lokasi ruang atau objek tertentu saat berbicara di obrolan suara.



:::hint{type="info"}
**📘 tips**
Transform Obrolan Suara terhubung dengan Transform karakter ZEPETO pemain lokal.

Oleh karena itu, jika karakter ZEPETO pemain lokal belum dibuat di dunia, suara Anda mungkin tidak ditransmisikan.

Dalam hal ini, Anda dapat menggunakan obrolan suara dengan mengatur lokasi pemutaran suara di dalam adegan saat ini menggunakan `SetLocalPlayerTransform()`.
:::



| **API**                                                                         | **Deskripsi**                                             |
| ------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `public static SetLocalPlayerTransform($transform: UnityEngine.Transform):void` | Fungsi untuk mengubah posisi pemutaran audio pemain lokal |



:::hint{type="danger"}
**❗️ Peringatan**
`SetLocalPlayerTransform()` harus dipanggil setelah `VoiceChatController.OnInitializedEvent(true)` saat obrolan suara diinisialisasi.
:::



1\) Di bawah ini adalah contoh skrip untuk fungsi perubahan posisi suara.

:::CodeblockTabs
VoiceTransformSample

```typescript
import { GameObject, Transform, Vector3 } from 'UnityEngine';
import { Button } from 'UnityEngine.UI';
import { ZepetoScriptBehaviour } from 'ZEPETO.Script';
import { AudioMode, RoomProperty, VoiceChatController } from 'ZEPETO.Voice.Chat';

export default class VoiceTransformSample extends ZepetoScriptBehaviour {

    // Tombol untuk mengatur transformasi suara dekat
    public buttonCloserTransform: Button;

    // Tombol untuk mengatur transformasi suara jauh
    public buttonFartherTransform: Button;

    // Transformasi untuk posisi suara
    private voiceTransform: Transform;

    Start() {

        // Buat GameObject baru dan tetapkan transformasi untuk menyimpan objek transformasi suara
        const voiceTransformObject = new GameObject;  
        this.voiceTransform = voiceTransformObject.transform;

        // Metode yang dipanggil ketika sistem Voice Chat diinisialisasi
        VoiceChatController.OnInitializedEvent.AddListener(
            init => {
                let roomProperty = new RoomProperty();

                // Atur mode audio ke audio ruang 3d arah
                roomProperty.SetAudioMode(AudioMode.Directional);
                VoiceChatController.EnterRoom(roomProperty);  

                // Atur transformasi suara untuk suara pemain lokal
                VoiceChatController.SetLocalPlayerTransform(this.voiceTransform);
            }
        );
        
        // Atur posisi transformasi suara ke (0,0,0) ketika 'buttonCloseTransform' diklik
        this.buttonCloserTransform.onClick.AddListener(()=>{
            this.voiceTransform.position = Vector3.zero;
        })
        
        // Atur posisi transformasi suara ke titik jauh ketika 'buttonFarTransform' diklik
        this.buttonFartherTransform.onClick.AddListener(()=>{
            this.voiceTransform.position = new Vector3(0,0,-10);
        })

    }

    // Metode untuk keluar dari ruang Voice Chat
    OnDestroy() {
        VoiceChatController.OnInitializedEvent.RemoveAllListeners();
        VoiceChatController.OnRoomConnectedEvent.RemoveAllListeners();
    }

}
```
:::

Deskripsi Kode

- Ketika adegan dimulai, buat objek permainan bernama voiceTransformObject di dalam `Start()` fungsi dan daftarkan Transform di voiceTransform.
- Ketika pendengar voice chat `OnInitialized` dipanggil, silakan terapkan pengaturan berikut:
- Atur voice chat ke mode audio spasial 3D melalui `SetAudioMode(AudioMode.Directional)`.
- Atur posisi voice chat pemain lokal ke voiceTransform melalui `VoiceChatController.SetLocalPlayerTransform()`.
- buttonCloserTransform mengatur posisi voiceTransform ke asal (0, 0, 0) ketika tombol diklik.
- buttonFartherTransform Mengatur posisi voiceTransform ke (10, 0, 0) ketika tombol diklik.



2\) Daftarkan tombol di Canvas dalam adegan ke buttonCloserTransform dan buttonFartherTransform dari komponen VoiceTransformSample.

![](https://api.archbee.com/api/optimize/fCt3n1oCa8rgNJ8fw9I2N-cr-0SWeexanSXeb-6NHj5-20240904-102426.png)



3\) Jika Anda menjalankannya di ponsel Anda menggunakan kode QR atau tautan uji, Anda dapat memeriksa hal-hal berikut.

- Ketika Anda menekan tombol Closer, suara Anda akan terdengar lebih dekat dengan orang lain.
- Ketika Anda menekan tombol Farther, suara Anda akan terdengar jauh dari orang lain.



::embed[[https://www.youtube.com/watch?v=Y_pj4RCshts](https://www.youtube.com/watch?v=Y_pj4RCshts)]{url="https://www.youtube.com/watch?v=Y_pj4RCshts"}

