国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

這篇具有很好參考價(jià)值的文章主要介紹了Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

前言

? 最近在自己寫一個(gè)比較小的項(xiàng)目,雖然自己是一個(gè)策劃,但是程序方面我覺得也是很有必要學(xué)一學(xué)的。

? 經(jīng)過了接近一年的學(xué)習(xí),也終于是可以獨(dú)自寫一些小的系統(tǒng)了。

? 這次自己寫了一個(gè)比較簡(jiǎn)單的NPC對(duì)話系統(tǒng),供大家參考。

效果展示

進(jìn)入對(duì)話區(qū)域

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

開始對(duì)話

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

Inspector面板可調(diào)選項(xiàng)

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

準(zhǔn)備工作

? 為了完成對(duì)話系統(tǒng),首先需要一個(gè)NPC以及一個(gè)UI界面。

? 這里為了節(jié)省篇幅,就直接上圖了。

NPC

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)
Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

UI

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

其中Panel用來控制整體顯示

NPCWord為文本

右側(cè)還有放頭像以及NPC名字的位置

代碼

完整代碼

這里就先上完整代碼

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

public class NPC_Talk : MonoBehaviour
{
    //公共參數(shù)
    [Header("NPC姓名")]
    public string npcName;
    [Header("是否是可對(duì)話NPC")]
    public bool allowTalk;
    [Header("是否循環(huán)對(duì)話")]
    public bool isLoop;
    [Header("對(duì)話文本")]
    public TextAsset[] talkTxt;
    [Header("對(duì)話提示")]
    public GameObject talkSign;

    //內(nèi)部參數(shù)
    [HideInInspector] public bool canTalk;
    private int txtOrder; //文本指針
    private GameObject player;
    private GameObject text;
    private int textRow;
    private bool isTalking;

    void Start()
    {
        canTalk = false;
        textRow = 0;

        player = GameObject.Find("Player");
    }


    void Update()
    {
        ShowSign();
        showText();
        CleanData();
    }

    private void ShowSign() //生成頭頂標(biāo)識(shí)
    {
        if (canTalk)
        {
            this.talkSign.SetActive(true);
        }
        else
        {
            this.talkSign.SetActive(false);
        }
    }

    private void OnMouseDown() //點(diǎn)擊NPC顯示對(duì)話UI 并重置Txt文本讀取位置
    {
        if (canTalk)
        {
            isTalking = true;

            GameObject canvas = GameObject.Find("Canvas");
            Transform panel = canvas.transform.Find("NPCTalk_Panel");
            panel.gameObject.SetActive(true);
            textRow = 0;
        }
    }

    private void showText() //鏈接txt文本與UI界面Text 并且逐行讀取顯示 讀取完畢隱藏UI
    {
        GameObject canvas = GameObject.Find("Canvas");
        Transform panel = canvas.transform.Find("NPCTalk_Panel");
        Text text = canvas.transform.Find("NPCTalk_Panel/NPCWord").gameObject.GetComponent<Text>();

        string[] str = talkTxt[txtOrder].text.Split('\n');       

        if (Input.GetMouseButtonDown(0) && isTalking)
        {
            canvas.transform.Find("NPCTalk_Panel/NPCName").gameObject.GetComponent<Text>().text = npcName;
            canvas.transform.Find("NPCTalk_Panel/Sprite").gameObject.GetComponent<Image>().sprite = this.GetComponent<SpriteRenderer>().sprite;
            text.text = str[textRow];
            textRow = textRow + 1;
        }

        if (textRow == str.Length)
        {
            panel.gameObject.SetActive(false);

            textRow = 0;
            txtOrder = txtOrder + 1; //第一個(gè)文本播完后 加載第二個(gè)文本
            if(txtOrder == talkTxt.Length)
            {
                txtOrder = 0; //全部文本播完后 重置文本指針
                if(!isLoop) //如果為不循環(huán)播放 則變?yōu)椴豢蒚alk的NPC
                {
                    allowTalk = false;
                    canTalk = false;
                }
            }
            isTalking = false;
        }
    }

    private void CleanData()    //走出對(duì)話區(qū)域重置當(dāng)前文本
    {
        if (!canTalk && isTalking)
        {
            GameObject canvas = GameObject.Find("Canvas");
            Transform panel = canvas.transform.Find("NPCTalk_Panel");

            textRow = 0;
            isTalking = false;
            panel.gameObject.SetActive(false);
        }
    }
}

詳細(xì)邏輯

開啟對(duì)話
private void OnMouseDown() //點(diǎn)擊NPC顯示對(duì)話UI 并重置Txt文本讀取位置
    {
        if (canTalk)
        {
            isTalking = true;

            GameObject canvas = GameObject.Find("Canvas");
            Transform panel = canvas.transform.Find("NPCTalk_Panel");
            panel.gameObject.SetActive(true);
            textRow = 0;
        }
    }

? 開啟對(duì)話我使用的是點(diǎn)擊NPC的碰撞體的方式。

? 并且通過canTalk判斷是否能夠?qū)υ?/p>

? canTalk是通過玩家是否在對(duì)話的區(qū)域內(nèi)(TalkArea)進(jìn)行判斷

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

此處在TalkArea上掛載了一個(gè)TalkCheck腳本

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

public class TalkCheck : MonoBehaviour
{
    public GameObject npc;

    private void OnTriggerEnter2D(Collider2D other)
    {
        if (npc.GetComponent<NPC_Talk>().allowTalk)
        {
            npc.GetComponent<NPC_Talk>().canTalk = true;
        }
    }

    private void OnTriggerExit2D(Collider2D other)
    {
        npc.GetComponent<NPC_Talk>().canTalk = false;
    }
}

我一開始在TalkCheck.cs腳本中使用的是事件的方式,進(jìn)出碰撞體都會(huì)發(fā)送一個(gè)事件給NPC_Talk.cs腳本,但是后期實(shí)踐的時(shí)候如果存在兩個(gè)以上的NPC,那使用事件就會(huì)造成錯(cuò)誤。所以還是用了比較繁瑣的辦法,將canTalk放到TalkCheck.cs中進(jìn)行判斷。

這里我還加了一個(gè)allowTalk來給玩家自行控制是否開啟NPC的對(duì)話功能,如果玩家關(guān)閉allowTalk,那canTalk會(huì)一直處于關(guān)閉狀態(tài)。

顯示對(duì)話

接著上文所述,玩家點(diǎn)擊NPC后開啟對(duì)話,為了顯示文本,所以下面寫了ShowText()函數(shù)

private void showText() //鏈接txt文本與UI界面Text 并且逐行讀取顯示 讀取完畢隱藏UI
    {
        GameObject canvas = GameObject.Find("Canvas");
        Transform panel = canvas.transform.Find("NPCTalk_Panel");
        Text text = canvas.transform.Find("NPCTalk_Panel/NPCWord").gameObject.GetComponent<Text>();

        string[] str = talkTxt[txtOrder].text.Split('\n');       

        if (Input.GetMouseButtonDown(0) && isTalking)
        {
            canvas.transform.Find("NPCTalk_Panel/NPCName").gameObject.GetComponent<Text>().text = npcName;
            canvas.transform.Find("NPCTalk_Panel/Sprite").gameObject.GetComponent<Image>().sprite = this.GetComponent<SpriteRenderer>().sprite;
            text.text = str[textRow];
            textRow = textRow + 1;
        }

        if (textRow == str.Length)
        {
            panel.gameObject.SetActive(false);

            textRow = 0;
            txtOrder = txtOrder + 1; //第一個(gè)文本播完后 加載第二個(gè)文本
            if(txtOrder == talkTxt.Length)
            {
                txtOrder = 0; //全部文本播完后 重置文本指針
                if(!isLoop) //如果為不循環(huán)播放 則變?yōu)椴豢蒚alk的NPC
                {
                    allowTalk = false;
                    canTalk = false;
                }
            }
            isTalking = false;
        }
    }

首先將獲取的第一個(gè)文本按行拆分,并且存入str[]中備用。

 string[] str = talkTxt[txtOrder].text.Split('\n');   

當(dāng)開始對(duì)話后,點(diǎn)擊左鍵即可按行顯示文本內(nèi)容,其中isTalking為之前定義的一個(gè)bool變量,其狀態(tài)代表玩家是否在對(duì)話中。

if (Input.GetMouseButtonDown(0) && isTalking)
        {
            canvas.transform.Find("NPCTalk_Panel/NPCName").gameObject.GetComponent<Text>().text = npcName;
            canvas.transform.Find("NPCTalk_Panel/Sprite").gameObject.GetComponent<Image>().sprite = this.GetComponent<SpriteRenderer>().sprite;
            text.text = str[textRow];
            textRow = textRow + 1;
        }

當(dāng)一個(gè)文本讀完之后,txtOrder會(huì)加一,也就是讀取的txt文件從talkTxt[i]變成了talkTxt[i+1]。也就是開始讀取下一個(gè)文件

當(dāng)txtOrder和txt文件數(shù)相等時(shí),也就是讀完了所有的文件,將會(huì)重置至第一個(gè)文件。

其中isLoop函數(shù)代表該NPC是否可以循環(huán)播放文本,玩家可以手動(dòng)設(shè)置。

如果不能循環(huán)播放,則在播放完后控制allowTalk,使NPC無法對(duì)話。

if (textRow == str.Length)
        {
            panel.gameObject.SetActive(false);

            textRow = 0;
            txtOrder = txtOrder + 1; //第一個(gè)文本播完后 加載第二個(gè)文本
            if(txtOrder == talkTxt.Length)
            {
                txtOrder = 0; //全部文本播完后 重置文本指針
                if(!isLoop) //如果為不循環(huán)播放 則變?yōu)椴豢蒚alk的NPC
                {
                    allowTalk = false;
                    canTalk = false;
                }
            }
            isTalking = false;
        }
頭頂標(biāo)識(shí)

頭頂標(biāo)識(shí)為一個(gè)表現(xiàn)向的元素,當(dāng)玩家進(jìn)入TalkArea時(shí)即開啟。

供大家參考。

Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)

private void ShowSign() //生成頭頂標(biāo)識(shí)
    {
        if (canTalk)
        {
            this.talkSign.SetActive(true);
        }
        else
        {
            this.talkSign.SetActive(false);
        }
    }
頭頂標(biāo)識(shí)

頭頂標(biāo)識(shí)為一個(gè)表現(xiàn)向的元素,當(dāng)玩家進(jìn)入TalkArea時(shí)即開啟。

供大家參考。

[外鏈圖片轉(zhuǎn)存中…(img-6kUZhC1w-1637120093347)]

private void ShowSign() //生成頭頂標(biāo)識(shí)
    {
        if (canTalk)
        {
            this.talkSign.SetActive(true);
        }
        else
        {
            this.talkSign.SetActive(false);
        }
    }

后話

由于本人不是程序員,本職工作是一個(gè)小策劃,所以希望大家不要介意我混亂的代碼邏輯。
其中還有很多優(yōu)化的地方,比如現(xiàn)在的txt文件需要在最后一行再加一個(gè)回車。如果大家有什么好的改進(jìn)方案,歡迎交流。文章來源地址http://www.zghlxwxcb.cn/news/detail-403268.html

到了這里,關(guān)于Unity3d 制作一個(gè)簡(jiǎn)單的NPC對(duì)話系統(tǒng)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Unity3D制作一個(gè)會(huì)移動(dòng)的方塊(還不會(huì)移動(dòng)照相機(jī))

    Unity3D制作一個(gè)會(huì)移動(dòng)的方塊(還不會(huì)移動(dòng)照相機(jī))

    學(xué)習(xí) Unity3D 這么久了,如果你還不會(huì)制作一個(gè)按下 WASD 就可以移動(dòng)的方塊的話,那么你的學(xué)習(xí)將沒有一點(diǎn)成就感,我學(xué)習(xí)的時(shí)候,我決定 先學(xué)習(xí)移動(dòng) ,這樣我就會(huì)對(duì) Unity 更加感興趣,學(xué)習(xí)起來的動(dòng)力會(huì)更為充足 先創(chuàng)建一個(gè)項(xiàng)目,名為move,如果你手頭有一個(gè)隨便亂用的項(xiàng)目

    2024年02月14日
    瀏覽(22)
  • Unity3D基礎(chǔ)入門之粒子系統(tǒng)(屬性介紹+火焰粒子系統(tǒng)案例制作)

    Unity3D基礎(chǔ)入門之粒子系統(tǒng)(屬性介紹+火焰粒子系統(tǒng)案例制作)

    一、屬性介紹 1、主面板Particle System (1)Duration:粒子發(fā)射周期 圖中,5.00即在發(fā)射5秒后進(jìn)入下一個(gè)粒子發(fā)射周期。若沒有勾選Looping,則5秒后粒子會(huì)停止發(fā)射。 (2)Looping:粒子按照周期循環(huán)發(fā)射 讓粒子發(fā)射時(shí)間循環(huán)起來,一直發(fā)射粒子。 (3)Prewarm:預(yù)熱系統(tǒng) 開始播放粒

    2024年02月04日
    瀏覽(25)
  • Unity3D學(xué)習(xí)之UI系統(tǒng)——用NGUI制作游戲登陸界面

    Unity3D學(xué)習(xí)之UI系統(tǒng)——用NGUI制作游戲登陸界面

    會(huì)省略一些東西,可以看我的NGUI的博客 設(shè)置UI分辨率自適應(yīng) 設(shè)置Root 的層級(jí) 和攝像機(jī)渲染的層級(jí)為UI 主攝像機(jī)不渲染UI 一般都是美術(shù)給一個(gè)示意圖,然后按示意圖上拼面板 3.1.1 制作圖集 制作兩個(gè)新圖集 3.1.2 拖面板 檢查DrawCall 3.1.3 面板基類 創(chuàng)建面板基類, 首先設(shè)置成單例

    2024年02月19日
    瀏覽(29)
  • Unity3D制作天空盒

    Unity3D制作天空盒

    1、下載并導(dǎo)入hdr高動(dòng)態(tài)范圍圖像資源到Project視圖中,然后將圖片的“Texture Shape”修改為“Cube”。 ?3、將步驟1的圖片拖入“Cubemap(HDR)”的框內(nèi)。 ?4、最后將制作好的材質(zhì),直接拖入Scene窗口中。 ???????? ?

    2024年02月15日
    瀏覽(24)
  • 使用Unity3D制作2D游戲的重點(diǎn)做法

    官網(wǎng)上有提供一個(gè) 2D游戲的教學(xué)范例 ,這個(gè)游戲只不過把鏡頭擺放在橫向位置跟隨角色移動(dòng),游戲內(nèi)物件運(yùn)動(dòng)時(shí)固定一個(gè)軸不動(dòng),使他像橫軸式的2D游戲來玩,本質(zhì)上其實(shí)還是個(gè)3D游戲,所以如果沒有3D建模的話不就沒辦法做2D游戲了?其實(shí)這些并沒有定論,就看制作者如何運(yùn)

    2024年02月11日
    瀏覽(88)
  • unity3d 制作開門動(dòng)畫以及收集鑰匙實(shí)現(xiàn)開門

    unity3d 制作開門動(dòng)畫以及收集鑰匙實(shí)現(xiàn)開門

    首先展示效果: unity3d 制作開門動(dòng)畫以及收集鑰匙實(shí)現(xiàn)開門 第一步,我們?cè)贖irarchy面板上新建三個(gè)cube,再按照一定的比例調(diào)整,制作完成一個(gè)門框,然后制作一個(gè)空物體并命名為Doorframe,將三個(gè)cube合并成門框一個(gè)整體: ?然后再創(chuàng)建一個(gè)cube調(diào)整大小,在將合適的門移動(dòng)至門框

    2023年04月13日
    瀏覽(40)
  • Unity3D項(xiàng)目之游戲場(chǎng)景小地圖制作

    Unity3D項(xiàng)目之游戲場(chǎng)景小地圖制作

    創(chuàng)建一個(gè)場(chǎng)景資源,可在asset store資源商店下載,選擇心儀場(chǎng)景。 鏈接:https://assetstore.unity.com/?locale=zh-CN 添加一個(gè)對(duì)象GameObject,命名為player,子物體包括:主攝像機(jī),角色,后面步驟會(huì)添加一個(gè)plane。 添加一個(gè)地圖攝像機(jī),命名為MapCamera。修改屬性projection為OrthoGraphic;Size為

    2024年02月11日
    瀏覽(285)
  • Unity3D制作注冊(cè)登錄界面,并實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn)

    Unity3D制作注冊(cè)登錄界面,并實(shí)現(xiàn)場(chǎng)景跳轉(zhuǎn)

    效果預(yù)覽圖片: 效果預(yù)覽視頻: 一、新建項(xiàng)目工程 1、打開Unity3D,新建一個(gè)項(xiàng)目,將其命名為“Login”。我這里用的版本是Unity2018.4.2f1,不同版本制作過程中的界面可能稍有不同,但是不影響具體功能的實(shí)現(xiàn)。 2、可以將樣例場(chǎng)景SampleScene重命名為Login,最好做到見名知意。

    2024年02月03日
    瀏覽(141)
  • 【Unity3D】程序紋理簡(jiǎn)單應(yīng)用

    【Unity3D】程序紋理簡(jiǎn)單應(yīng)用

    ? ? ? ? 本文所有案例的完整資源詳見→Unity3D程序紋理簡(jiǎn)單應(yīng)用。 1.1?邊框 ???????? 1)邊框子圖 ? ? ? ? Border.shadersubgraph ????????說明:Any 節(jié)點(diǎn)用于判斷輸入向量中是否存在一個(gè)分量非零,Branch 節(jié)點(diǎn)根據(jù)輸入的真假走不同的分支,詳見→Shader Graph節(jié)點(diǎn)。 ??????

    2024年02月12日
    瀏覽(20)
  • 如何在 Unity3D 制作一杯水 LiquidVolume插件 水杯 燒瓶液體

    如何在 Unity3D 制作一杯水 LiquidVolume插件 水杯 燒瓶液體

    這款插件功能非常強(qiáng)大,你可以做燒杯裝液體,啤酒,魚缸,甚至是制作一個(gè)池塘. Shader的類型與功能都很齊全,基本上可以滿足你想要大部分的效果. 這款插件我做了中文翻譯,對(duì)于英文不是很好的童鞋會(huì)有幫助,至少一目了然,大概知道這個(gè)參數(shù)是做什么的. 參數(shù)截圖 效果 與原版插件

    2024年02月02日
    瀏覽(70)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包