Unity＋宴3で、アクションRPGで村人に近づいて話しかけて会話する　という状況を想定したシーンの実装

![image.png](https://qiita-image-store.s3.amazonaws.com/0/232287/22e78e10-aed2-d631-ddae-21cf8382ab4f.png)


#コメント
村人に近づいて話しかける、それでクエストを発生させたり、選択肢によって進行を分岐させたりと、非常によく使う実装をした時の話をまとめました。

（この記事は自分のブログの転載になります）
[開発日誌::Unity＋宴3で、アクションRPGで村人に近づいて話しかけて会話する　という状況を想定したシーンの実装 - まわ](http://k-mawa.hateblo.jp/entry/2018/02/27/164040)

#必要なものや実施環境

 - 宴3
[UTAGE3 Unity Text Adventure Game Engine Version3 - Asset Store](https://assetstore.unity.com/packages/templates/systems/utage3-unity-text-adventure-game-engine-version3-80727)   
    
 - 宴公式サイト 
http://madnesslabo.net/utage/

 - Unity 2017.2.1f1

 - Windows10Pro

__宴は一家に1アセットあると何かと捗ると思いました。__ 有料で80ドルですが十分その価値はあるアセットだと思いますのでめっちゃお勧めしておきます。ノベルゲームだけではなく今回のようなアクションPRGやSLGで活用も手軽にできそうです^^

#手順1:構成の概要
こんな感じです
![image.png](https://qiita-image-store.s3.amazonaws.com/0/232287/11c5c5f1-c4d8-f254-cc20-28069eec8ce2.png)
上記のようにまず、主人公とCubeの距離を測ります。
それで、ざっくりとした挙動としては

```
if (主人公とCubeの距離 < 一定　かつ クリック=True)
    { 会話呼び出し; } 
```
という感じの関数を実装していきたいと思います。

#手順2:主人公とCubeの距離を測るコードの実装
```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class conversation : MonoBehaviour {
    public GameObject objOne;
    public GameObject objTwo;
    bool One;
    bool Two;


    // Use this for initialization
    void Start () {
        //このOneとTwoを一回DebugLog呼び出したら
        //True,False切り替えるようにしておき、
        //1フレームごとに距離が出力されないようにしておきます
        //状態が変わったときだけDebugLogを吐き出すということです
        One = true;
        Two = true;

    }
	
	// Update is called once per frame
	void Update () {

        Vector3 OnePos = objOne.transform.position; //主人公キャラプレファブ
        Vector3 TwoPos = objTwo.transform.position;  //Cube（実践だとキャラクタープレファブ等を想定）
        float dis = Vector3.Distance(OnePos, TwoPos); //距離測定


        if (One)
        {
            if (dis >= 2) //主人公とCubeの距離が2以上なら
            {
                Debug.Log("Distance is over 2. far : " + dis); //more than でしたね。すみません。
                One = false;
                Two = true;
            }
        }

        if (Two)
        {
            if (dis < 2) //主人公とCubeの距離が2未満なら
            {
                Debug.Log("Distance is under 2. close : " + dis);
                Two = false;
                One = true;
            }
        }
 }
```
こんな感じですね。
挙動も見てみましょう。うまく思った通りの
挙動をしています。
[近づいたら話しかけられるようにするためのセンサー的コード実装 - YouTube](https://www.youtube.com/watch?v=x69SGUqMAMw)

#手順3:宴のセッティング
ここからは宴を利用しますので、宴自体のセッティング（購入、インポートなど）が先に必要です。インポートした後は、下記の公式マニュアルにしたがって、ヒエラルキーに配置されている状態にしておいてください  
[会話シーンとして宴を使う | Unity用ビジュアルノベルツール「宴」](http://madnesslabo.net/utage/?page_id=402)

#手順4:距離が近いときのクリックで会話ダイアログを呼ぶ
いよいよ核心部分の実装です。

```c#
//手順2と同じスクリプトです

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Utage; //宴を忘れずに付加します

public class conversation : MonoBehaviour {
    //ここで宴のコントローラー的なオブジェクトを
    //呼び出す必要あります
    AdvEngine Engine { get { return engine ?? (engine = FindObjectOfType<AdvEngine>()); } }
    public AdvEngine engine;

//・・・（中略）・・・・

	void Update () {

        Vector3 OnePos = objOne.transform.position;
        Vector3 TwoPos = objTwo.transform.position;
        float dis = Vector3.Distance(OnePos, TwoPos);

        //・・・（手順2と重なるので中略）・・・・


        if (dis< 2) //主人公とCubeの距離が2未満なら
        {
            if (Input.GetMouseButtonDown(0)) //さらにマウスクリックがあったなら
            {
                Debug.Log("conversation start");
                StartCoroutine(CoTalk());　//会話シナリオを呼び出します
            }

        }

    }

    IEnumerator CoTalk()
    {
        //「宴」のシナリオ「Start」タグの会話シーンを呼び出す
        //会話をどのように構成するか、条件分岐、フラグ設定などは
        //なんと１つのエクセルでできてしまいます・・・
        //なお「Start」はデフォルトで入っているタグなので
        //設定しなくとも下記コードは動きます
        Debug.Log("call co talk");
        Engine.JumpScenario("Start");

        //「宴」のシナリオ終了待ち
        while (!Engine.IsEndScenario)
        {
            yield return 0;
        }
    }
```
挙動を見てみましょう。おお！いい感じ！
[近づいて　かつ　マウスクリックされると会話ダイアログ表示のコード実装 - YouTube](https://www.youtube.com/watch?v=PEfKKeJBWho)

UIをしっかり構築したら、より良い感じになりそうですね^^

###参考文献
宴3の活用方法リファレンス 
[会話シーンとして宴を使う | Unity用ビジュアルノベルツール「宴」](http://madnesslabo.net/utage/?page_id=402)
  
2オブジェクト間の距離を測る 
[Unityで2つのオブジェクトの間の距離を取る : ブリブサー開発戦線　〜僕らはあの戦いを忘れない〜](http://blog.livedoor.jp/bribser_dev/archives/4230746.html)