---
# System prepended metadata

title: Dialogue System
tags: [Unity對話]

---

###### tags: `Unity對話`
# Dialogue System

[toc]

# 基礎設定
## import Dialogue System
Asset store登入下載

## Dialogue Manager
大部分跟對話有關的內容都靠Dialogue Manager來管理調整，所以先將此物件拉出來。
![](https://i.imgur.com/QPQ28JX.png)

## 建立DB

還沒建立前，可以在Dialogue Manager點這個位置建立
![](https://i.imgur.com/85rZhAw.png)

or 

直接在project建立
![](https://i.imgur.com/0BXo9UP.png)

P.S. 如果已經有舊DB，最好不要新創，因為兩者無法同時使用！！！


# 調整prefab UI

![](https://i.imgur.com/59oiUpo.png)

![](https://i.imgur.com/hEpWQWD.gif)

# 資料庫
進入資料庫，對DB按Edit，會跳出Dialogue Database的視窗。
![](https://i.imgur.com/anxOjyl.gif)

裡面有不同的標籤可以進行調整
![](https://i.imgur.com/HSJItR1.png)


## Conversations標籤

顧名思義就是用來建立聊天的，按下+可以新增新的對話
![](https://i.imgur.com/tmSFPfD.png)

- **Title**可以更改名稱

![](https://i.imgur.com/9htf2TC.png)


對著橘色按下去的子節點為一般對話

![](https://i.imgur.com/nW9yqQf.gif)

節點右邊Inspector的資訊個別為

- **Actor:** 演出這段對話的演員，即是說這句話的人
- **Conversant:** 聆聽這句話的人
- **Dialogue Text:** 這句話的內容 (台詞打在這)
- **Sequence:** 說這句台詞時會播放的動畫 (相機不同角度拍攝...etc)
- **Condictions:** 放入條件，條件為true才會執行這段對話。
- **Script:** 進行對話時會執行的程式碼

![](https://i.imgur.com/64ijDd8.png)

### sequence
#### 以對話時相機拍攝的角度為例

![](https://i.imgur.com/sFWEMpZ.png)

**Subject:** 放想觀察的對象
**Camera Angle Collection:** 產生出來的角度(空物件)存放在Hierachy的哪裡
![](https://i.imgur.com/exNYXS4.png)

按下「+」可以新增角度空物件
![](https://i.imgur.com/KExI8W8.png)

為了方便聊解目前的角度長怎樣，==我們將空物件新增一個子物件的相機給他==

![](https://i.imgur.com/nXoo6rx.png)

1. 先將相機的位置reset

2. 調整好角度

由於相機是空物件的子物件，因此我們直接調整空物件就可以讓相機跟著移動旋轉。而我們最主要是需要子物件的相機視角，這樣才知道目前的角度長怎樣

3. 將相機刪除

4. 打開對話，將合適的對話Node的sequence欄位打上

```csharp=
Camera(角度空物件名稱);
{{default}}
```
![](https://i.imgur.com/fiBmH1i.png)

#### 延遲幾秒鐘

```csharp=
Delay(3)
```

#### 播放Timeline

建立timeline時，一定要在Hierarchy建立一個空物件，並加上component `Playable Diretor`，並且把`.playable`檔放上該元件。

==必須注意的是，如果Dialogue System有設定「離NPC過遠就終止對話」可能會導致，NPC在播放動畫時離玩家太遠而讓動畫中斷。==

```csharp=
Timeline(play,Timeline在Hierarchy的物件名稱)
```
### condition - 以隨機對話內容為例
作用很像寫程式的if-else。

直接參考下方連結講得清楚明瞭，而且我懶惰。

[隨機對話內容](https://www.pixelcrushers.com/phpbb/viewtopic.php?t=374)

### Events - 達到類似ButtonClick的功能

1. 新增一空物件、以及一物件並將程式碼掛在底下

    ![](https://i.imgur.com/i0Vc7rx.png)
    
    **ScriptsTest:** 的作用是將程式碼掛在該物件底下
    
    ![](https://i.imgur.com/xhtGDEt.png)

    **Empyt:** 能否將此物件關閉，可以的話代表事件(event)觸發成功。
    
    就真的是空物件所以底下啥都沒有。
    ![](https://i.imgur.com/hHkh9NK.png)

2. 將寫好的程式碼掛在物件底下

    為了測試點選選項後是否有用，我們設定點了選項後可以將某個物件關閉
```csharp=
public GameObject Empty;

public void TTTTClick()
{
    Empty.SetActive(false);
}
```
![](https://i.imgur.com/0Zsj0le.png)

3. Dialogue Conversations新增事件

- 點選Add Scene Event

![](https://i.imgur.com/T0Oi95v.png)

- 新增事件

**On Execute(GameObject):** 如果有成功運行就會執行底下的內容。言下之意就是如果這個選項有被選才會去執行底下的內容。

OnExecute一定要選這個，不能選上面沒有GameObject的，上面的是直接掛著程式碼，但不知為何無法選擇Function。

On Execute(GameObject)則可以掛著物件，所以我將程式碼掛在物件下，再把該物件掛在On Execute(GameObject)。

![](https://i.imgur.com/pVc3yWN.png)

- 空格的欄位放入物件(ScriptTest)

    因為ScriptTest底下掛有程式碼。
    ![](https://i.imgur.com/QyNAbAC.png)

    ![](https://i.imgur.com/A14QeSd.png)

- 選擇我們剛剛寫的Function

    ![](https://i.imgur.com/AhyYbIA.png)

- 執行結果

![](https://i.imgur.com/PgE4UwQ.gif)

# 觸發對話

- 必須有Collider

- component新增Dialogue System Trigger

![](https://i.imgur.com/W1Fj40k.png)

根據不同的觸發對話需求有不同的trigger

![](https://i.imgur.com/Um6PjO2.png)

## OnUse trigger
Add Action > start conversaction
![](https://i.imgur.com/heWYmS5.png)

選擇conversaction
![](https://i.imgur.com/D2SiQT9.png)

將角色選擇好
![](https://i.imgur.com/fRBLxhE.png)

將可以「點及觸發對話」的物件掛上Usable component

Max Use Distance:為觸發的最大範圍
![](https://i.imgur.com/2Vz2TLG.png)

最後將player的物件掛上Selector Scripts
![](https://i.imgur.com/YpQlZtT.png)

可透過Selector Scripts 修改用哪個按鍵觸發
![](https://i.imgur.com/BYJgXpc.png)

# 以程式碼開啟對話

[以程式碼開啟對話(有效)](https://www.pixelcrushers.com/phpbb/viewtopic.php?t=1603)

```csharp=
using PixelCrushers.DialogueSystem;

[ConversationPopup] public string conversation;
 public Transform actor;
 public Transform conversant;
 ...
 void StartMyConversation()
 {
     DialogueManager.StartConversation(conversation, actor, conversant);
 }
```