❤❤新課程需要你的寶貴意見❤❤

2017年3月24日 星期五

Unity+Fungus的3D遊戲對話應用

什麼是Fungus?
http://www.morningfungame.com/2016/05/unityfungus.html

此教學是用舊版Fungus製作的,當時還沒有支援3D物件觸發對話的功能,所以需要另寫C#腳本實作。但是新版的Fungus(3.7版以上)支援了3D物件觸發對話,不需要寫C#腳本了。

如果你安裝Fungus時,FungusExamples有打勾的話,Project視窗的FungusExamples \ MonoBehEvents底下有個Scene叫做PhysicsInteraction,裡面有各種Collider跟Trigger的範例可以參考


======以下教學是用舊版的Fungus製作,僅供有興趣寫成程式的人練習===
<Unity+Fungus的3D遊戲對話應用>

上:建立玩家角色與NPC
中:觸發對話且鎖定玩家行動
下:智慧型NPC的狗腿對話







Player.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {
    Rigidbody playerRigidbody;
    float moveX;
    float moveZ;
    public float speed;

    [Header("聲望")]
    public int prestige;

    void Awake () {
        playerRigidbody = GetComponent<Rigidbody>();
 }


 void Update () {
        MovementController();

    }

    void Move() {
        moveX = Input.GetAxis("Horizontal");
        moveZ = Input.GetAxis("Vertical");
        playerRigidbody.AddForce(new Vector3(speed * moveX, 0, speed * moveZ));
    }

    void MovementController() {
        if (!Talkable.isTalking)
        {
            Move();
        }
    }

    public void SendPrestigeToFungus() {
        Talkable.flowchartManager.SetIntegerVariable("取得玩家聲望", prestige);
    }
}

Talkable.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fungus;
using UnityEditor;

public class Talkable : MonoBehaviour {
    public static Flowchart flowchartManager;
    public Flowchart talkFlowchart;
    public string onCollosionEnter;
    public string onMouseDown="滑鼠點擊";
    public string onMouseEnter = "滑鼠進入";
    Rigidbody playerRigidbody;


    void Awake () {
        flowchartManager = GameObject.Find("對話管理器").GetComponent<Flowchart>();
        playerRigidbody = FindObjectOfType<Player>().GetComponent<Rigidbody>();
 }

 void Update () {

 }

    public static bool isTalking {
        get { return flowchartManager.GetBooleanVariable("對話中"); }
    }
    void PlayBlock(string targetBlockName) {
        Block targetBlock = talkFlowchart.FindBlock(targetBlockName);
        if (targetBlock!=null)
        {
            talkFlowchart.ExecuteBlock(targetBlock);
        }
        else
        {
            Debug.LogError("找不到在 "+talkFlowchart.name+"裡的"+targetBlockName+"Block");
            Selection.activeGameObject = talkFlowchart.gameObject;
        }
    }

     //Fungus 3.7版以後也內建了一個Collision
     //為了避免跟Unity內建的Collision混淆,這邊需要特別指明是Unity本身的Collision
    private void OnCollisionEnter(UnityEngine.Collision other)
    {
        if (!string.IsNullOrEmpty(onCollosionEnter)&&!isTalking)
        {
        if (other.gameObject.CompareTag("玩家"))
        {
            playerRigidbody.Sleep();
            PlayBlock(onCollosionEnter);
        }
        }
    }

    private void OnMouseDown()
    {
        if (!string.IsNullOrEmpty(onMouseDown)&&!isTalking)
        {
        PlayBlock(onMouseDown);
        }
    }
    private void OnMouseEnter()
    {
        if (!string.IsNullOrEmpty(onMouseEnter) && !isTalking)
        {
            PlayBlock(onMouseEnter);
        }
    }
}

NameChanging.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fungus;

public class NameChanging : MonoBehaviour {
    public Flowchart flowchart;
    public string SirName {
        get { return flowchart.GetStringVariable("sir"); }
        set { flowchart.SetStringVariable("sir", value); }
    }

    void Start () {
        Debug.Log("本來叫做"+SirName);
        SirName = "用腳本改名字為大爺";
        Debug.Log("現在叫做" + SirName);
    }
}



24 則留言:

  1. 請問不小心把block移到不見了...
    有什麼方法可以讓 flowchart出現呢
    我移來移去都沒找到ˊˋˊˋ

    回覆刪除
    回覆
    1. Flowchart視窗裡有個center按鈕可以看到全部的Block

      刪除
    2. 感謝您 太謝謝你了ˋ^0^ˊ

      刪除
  2. 作者已經移除這則留言。

    回覆刪除
  3. 不好意思~我想請問如果我要在手機上觸碰物件,然後跳出對話框要改成OnTouchDown就好嗎?還是需要做其他的更改?

    回覆刪除
    回覆
    1. 我記得是不用修改,unity會自動轉換單點觸控,除非你是要雙指縮放畫面之類的效果

      刪除
    2. private void OnTouchDown()
      {
      Block targetBlock = talkFlowchart.FindBlock(onTouchDown);
      talkFlowchart.ExecuteBlock(targetBlock);
      }
      像這樣就可以嗎?

      刪除
  4. 不好意思~上面的問題解決了,不過我發現對話框沒辦法在手機上自動調整比例,他會超出手機螢幕,請問哪裡可以更改對話框的大小。
    謝謝你~

    回覆刪除
  5. 你得用 narrative →SetSayDialog 自訂對話框喔,youtube搜尋一下 陳間時光 漫畫對話框

    回覆刪除
  6. 不好意思 我想請問只有碰撞時可以鎖定player移動嗎
    滑鼠點擊時有辦法可以鎖定嗎 謝謝

    回覆刪除
    回覆
    1. 可以啊,你把playerRigidbody.Sleep(); 這一行放到OnMouseDown()裡就可以了

      刪除
  7. 請問該如何將Flowchart Window中宣告的變數,直接或是用程式assign到Block中Say Dialog和Menu Dialog的Text上呢?

    回覆刪除
    回覆
    1. 以Say Dialog為例,你只要在對話欄裡面輸入{$變數名稱} 就可以了,比方你在Flowchart裡有個變數叫做 score,那麼在對話欄裡面輸入{$score} ,對話框就會顯示 score 變數的內容,也可以跟其他文字混合一起用。像是對話框裡輸入:你的分數是{$score},然後score的內容是99的話,顯示文字就是:你的分數是99

      刪除
    2. 已解決,謝謝。
      那如果我是從.csv匯入data做Split(切成中文部分和英文部分兩部分),然後用程式assign到Flowchart Window中宣告的變數,我在run的時候,匯入的中文部分是亂碼,在unity上打的中文並不會有亂碼顯示的問題,請問這種情況要怎麼處理?

      刪除
    3. 不知道是不是編碼問題,你可以朝這個方向查查看資料...
      你匯入data的程式碼應該有用到StringReader吧?
      試試把csv檔轉成 utf8 或 unicode 的編碼格式

      這個網頁可以參考一下
      https://ithelp.ithome.com.tw/articles/10030801

      刪除
  8. 請問我在實作的時候使用了2DRigidbody,但無法用sleep鎖定角色的移動。
    我有事先把所有的Rigidbody playerRigidbody;改成Rigidbody2D playerRigidbody2D;
    對話是可以顯示出來的唯有鎖定角色沒有辦法。

    並且在輸出遊戲的時候出現了許多因為using UnityEditor;而出現問題:
    1.The type or namespace name `UnityEditor' could not be found. Are you missing an assembly reference?
    2.Error building Player because scripts had compiler errors
    3.Build completed with a result of 'Failed'UnityEngine.GUIUtility:ProcessEvent(Int32, IntPtr)
    4.UnityEditor.BuildPlayerWindow+BuildMethodException: 2 errors
    分別是這四個問題
    暫時把UnityEditor與Selection那行分別註解是解決了,但不知道有什麼影響
    我使用的unity版本是2017.2.0p3;fungus是最新版本
    陳年時光的教學真的很仔細也精采豐富又有趣,
    讓人看到密密麻麻的程式語言不會無聊,
    希望未來可以多多推出更多關於fungus的教學影片!!!

    回覆刪除
    回覆
    1. 不好意思這麼久才回覆你,之前有一陣子系統都不會跳出新留言的通知...
      回到正題:用RigidBody2D鎖定移動的話可以試試看直接修改速度:Rigidbody2D.velocity

      UnityEditor相關的程式是在Unity編輯器裡才會有作用,所以不要把UnityEditor相關的東西寫到遊戲的主要邏輯裡面

      刪除
  9. 不好意思打擾了,我是剛接觸unity的初學者,想問您如何從flowchart對話轉到3d介面!!

    回覆刪除
    回覆
    1. 不好意思這麼久才回覆你,之前有一陣子系統都不會跳出新留言的通知...
      回到正題:你的"從flowchart對話轉到3d介面!!" 可以舉例子嗎?我看不太懂你的問題

      刪除
  10. 想問一下
    匯入fungus之後
    就算沒用插件的東西
    最後打包匯出的時候都會匯出失敗
    都會出現一樣的錯誤信息
    Assets\Fungus\Scripts\Components\EventHandler.cs(75,27): error CS1061: 'Flowchart' does not contain a definition for 'SelectedBlock' and no accessible extension method 'SelectedBlock' accepting a first argument of type 'Flowchart' could be found (are you missing a using directive or an assembly reference?)
    想問一下到底發生什麼事

    回覆刪除
    回覆
    1. 應該是版本相容性的問題,你Unity跟Fungus的詳細版本各是多少?

      刪除
    2. 墨克你好~我也是遇到這樣的問題 我在他官方那邊找到的3.11.1版本就沒那個問題了(我用asset store的3.11.1也不行),https://github.com/snozbot/fungus/releases/tag/v3.11.1 我用的是3.6的Unity哦 這是他官方的討論區http://fungusgames.com/forum/

      刪除
    3. 網址打到全形的了-.-這裡https://github.com/snozbot/fungus/releases/tag/v3.11.1

      刪除

留言給作者加油打氣