Y3編輯器文檔4:觸發器1(對話、裝備、特效、行為樹、排行榜、不同步問題)

文章目錄

    • 一、觸發器簡介
      • 1.1 觸發器界面
      • 1.2 ECA語句編輯及快捷鍵
      • 1.3 參數設置
      • 1.4 變量設置
      • 1.5 實體觸發器
      • 1.6 函數庫與觸發器復用
    • 二、觸發器的多層結構
      • 2.1 子觸發器(在游戲內對新的事件進行注冊)
      • 2.2 觸發器變量作用域
      • 2.3 復合條件
      • 2.4 循環
      • 2.5 計時器
      • 2.6 單位組
      • 2.7 玩家組
      • 2.8 運動器
    • 三、案例
      • 3.1 NPC對話
      • 3.2 裝備限制
        • 3.2.1 裝備拾取
        • 3.2.2 物品丟棄
      • 3.3 特效
        • 3.3.1 特效生成
        • 3.3.2 特效銷毀
      • 3.4 行為樹
      • 3.5 使用排行榜
      • 3.6 特效可見性
      • 3.7 不同步問題
        • 3.7.1 本地配置不同步日志環境
        • 3.7.2 線上游戲不同步定位
        • 3.7.2 定位不同步問題
        • 3.7.3 游戲不同步的原因

  • Y3編輯器文檔1:編輯器簡介及菜單欄詳解(文件、編輯、窗口、細節、調試)
  • Y3編輯器文檔2:場景編輯(地形編輯、物件放置)
  • Y3編輯器文檔3:物體編輯器
  • Y3編輯器文檔4:觸發器1(對話、裝備、特效、行為樹、排行榜、不同步問題)

一、觸發器簡介

參考官方文檔《觸發器》

??觸發器是Y3編輯器中實現游戲邏輯的核心組件,它通過“事件-條件-動作”(Event-Condition-Action,簡稱ECA)的模式來實現各種效果。

  • 事件(Event):觸發器的導火索,當設定的事件發生時觸發器才會執行。
  • 條件(Condition):觸發執行必須滿足的條件。
  • 動作(Action):觸發執行的結果。
    在這里插入圖片描述

1.1 觸發器界面

??通過主界面頂部功能欄或使用快捷鍵F4可進入觸發器。進入觸發器窗口后,你可以添加或刪除文件夾和觸發器,并使用搜索功能快速找到你想找的觸發器;還可以對選定的觸發器進行以下操作: 復制, 剪切, 粘貼, 刪除, 重命名, 禁用, 和轉化成Lua代碼。
在這里插入圖片描述
右鍵單擊觸發器并選擇禁用使其無效。單擊啟用以重新激活無效的觸發器

在這里插入圖片描述

??你可以在變量管理事件管理中提前寫入常用的變量和事件,以便在游戲中隨時調用,從而減少開發項目的記憶成本和后期維護成本。比如可以提前設置事件并添加事件中需要的參數,然后在觸發器-自定義事件中進行調用。
在這里插入圖片描述
在這里插入圖片描述
??在主界面-編輯-通用設置-編輯設置中勾選“縮略圖滾動條”,可以顯示ECA縮略圖滾動條。左鍵點擊可以定位到想要的行數,長按左鍵可以拖動滾動條。錯誤、點選與搜索結果也會以色塊形式顯示到普通滾動條上。縮略圖可以收起,收起后需要重新在“主界面-編輯-通用設置-編輯設置”打開。
在這里插入圖片描述
在這里插入圖片描述

1.2 ECA語句編輯及快捷鍵

??點擊事件/條件/動作后面的"+"為當前部分新建語句,也可以在空白處點擊鼠標右鍵,新建事件,條件,動作,子觸發器與注釋。如果想要更改已有的事件,條件或者動作,雙擊對應語句即可彈出選項窗口,選擇新的內容后即可進行覆蓋。

功能快捷鍵說明
新建觸發器Ctrl + T
新生子觸發器Ctrl + Q
新建事件Ctrl + E
新建條件Ctrl + D
新建動作Ctrl + R
新建注釋Ctrl + N
ECA注釋開關Ctrl + M將當前語句轉為注釋
設為無效Ctrl + W使觸發器文件或eca條目無效(被跳過)
條目下移Ctrl + ↓快速將當前選中的eca下移一行
條目上移Ctrl + ↑快速將當前選中的eca上移一行
新建收納盒Ctrl + P
添加至收納盒Ctrl + O添加當前選中eca到收納盒
變量引用查看A
全局元素引用查看S
跳轉到函數D

在這里插入圖片描述

功能快捷鍵說明
查看上一個觸發器Ctrl + ←
查看下一個觸發器Ctrl + →
搜索框Ctrl + F
跳轉到物編器Ctrl + J
切換到觸發器Ctrl + 1
切換到函數庫Ctrl + 2
切換到觸發總覽Ctrl + 3
跳轉F3
復制參數Shift + C右鍵單擊參數使用。復制時,整個參數的值和類型都將被復制到剪貼板上
粘貼參數Shift + V右鍵單擊參數使用,復制的參數類型與目標參數類型必須相同

在這里插入圖片描述

1.3 參數設置

??未賦值的參數會以紅色顯示,已賦值的參數會以填入的數據類型分配顏色,可選的參數則在次級菜單中選用,額外的選項會以藍色顯示,文本信息說明了當前觸發器語句的含義。需要指定所有的必選參數,本條動作以及所在的觸發器才能正常運行。
在這里插入圖片描述
參數有以下幾種類型:

  • 預設對象:當參數類型為可以放置在場景中的對象時( 單位,裝飾,物體,特效等),可以直接選擇該預設對象作為參數。
    在這里插入圖片描述
  • 數值:你可以直接將一個固定的數字、文本或布爾值賦給一個參數
  • 變量:包括全局變量和局部變量
  • 函數:一組官方打包的獲取數據的動作,可以直接提供對應的返回值。
    在這里插入圖片描述
  • 通用:用于設置 自定義值 和調用表格編輯器。
    在這里插入圖片描述
    ??當您單擊轉換為變量時,會在當前語句之前創建一個變量賦值語句,將當前語句結果賦值給一個變量。轉換為變量后,您可以單擊取消變量轉換以恢復到之前的狀態。

在這里插入圖片描述

1.4 變量設置

你可以通過觸發器界面設置變量,或通過ECA選擇界面設置變量。

在這里插入圖片描述
變量在創建時,需要聲明其類型,部分變量類型必須設置默認值。

  • 非對象型變量:字符串、浮點數、整數、布爾值
  • 對象型變量:單位、單位組、玩家組、單位命令

變量根據作用域類型分為全局變量和局部變量。

  • 全局變量:可以在本項目內的任何觸發器中讀取和寫入。
  • 局部變量:只能在當前觸發器中生效。

??數組是相同數據類型的集合,數組中的每個元素都在其基本值上添加了一個索引,使我們在數組中更容易找到和訪問它們。整數、單位、實體、單位名字、物品實體等變量都可以設置為數組。比如下面代碼設為按下H鍵之后,在Boss周圍召喚6個黑暗守衛(使用數組guards實現)。

在這里插入圖片描述

??變量只能用于儲存數據的媒介,并不會實時更新,任何對變量的操作都需要使用賦值動作進行實現。請不要忘記在觸發器中編寫更新變量的語句。例如,在游戲運行的時候設置變量“玩家人數”為6,5分鐘后有一位玩家退出游戲,此時游戲中玩家人數為5,如果沒有編寫變量更新語句,那么變量“玩家人數”依然為6。你需要編寫能表達“在玩家退出游戲的時候玩家人數減1”的邏輯。

在這里插入圖片描述

1.5 實體觸發器

??在物體編輯器->觸發器中可進行實體的邏輯編寫,即為實體觸發器,其優勢在于它可以更簡單地將邏輯和目標物體綁定,而與其他擺件無關,所以可以減少性能的消耗。實體觸發器的編輯與上述觸發器操作一致,一個擺件也可以設置多條觸發。

1.6 函數庫與觸發器復用

??你可以將自己常用的觸發器語句/功能模塊添加到函數庫,接著就可以在觸發器中找到該函數語句進行重用。與觸發器的操作邏輯相同,在左側創建函數后,在右側編輯功能庫函數。

在這里插入圖片描述

初始化玩家技能槽位

函數描述定義了函數在操作列表中的顯示方式。 函數描述包括以下內容:

  • 名稱:要生成的觸發器語句的名稱。
  • 說明:要生成的觸發器語句的內容和格式。
  • 注意事項:當前函數的說明。

在這里插入圖片描述

函數體包括以下內容:

  • 參數:定義了該函數的輸入數據,可設置參數類型,如定時器、單位和整數。
  • 返回值:定義了函數執行后返回的結果(輸出數據)。你可以點擊 "+"來設置返回值的名稱和類型,以方便觸發器的后續調用。
  • 動作:顯示了函數的具體行動邏輯

??在觸發器中選擇想要復制的觸發進行復制,這條觸發器的源代碼內容會寫入到粘貼板中,此時可以在記事本等文本文件中進行本地粘貼保存,或者在新項目的觸發器界面選擇右鍵粘貼(Ctrl+V)。
在這里插入圖片描述

二、觸發器的多層結構

2.1 子觸發器(在游戲內對新的事件進行注冊)

??觸發器具有一個事件,這個事件是通過一個注冊來實現的,即對一個事件進行注冊,從而讓系統在對應的事件觸發時能繼續按照條件與動作順序執行。全局觸發器是在游戲初始化時就注冊完成的,如果要在游戲內對新的事件進行注冊,實現更復雜的游戲邏輯,就需要通過子觸發器來實現。

??子觸發器是在觸發器的“動作”中創建的,用于在游戲進程中對新的事件進行注冊,注冊后會獨立運行(按ECA的邏輯執行)。子觸發器是一種變量類型,可以返回這個觸發器實例,以方便在使用完畢后銷毀它(如果需要的話)。因為是游戲進程中注冊,所以我們可以把變量中的數據傳遞給子觸發器進行注冊。

下面是一個簡單的示例,使用子觸發器將單位(關羽)移動到相應的點。
在這里插入圖片描述

2.2 觸發器變量作用域

??作用域是指變量在程序中被定義后可以被訪問的范圍,它決定了變量的可見性和生命周期。全局變量可以在任何觸發器及其子觸發器的范圍內有效,局部變量可以在當前觸發器及其子觸發器的范圍內有效,子觸發器局部變量只能在當前子觸發器的范圍內有效。作用域的存在可以防止變量命名沖突,提供封裝和隔離性,提高程序的可靠性和可維護性。

??局部作用域中的變量優先級更高。比如在子觸發器中定義了一個局部變量,這個變量與全局變量或者外部作用域中的變量(另外一個觸發器中定義的變量)同名時,子觸發器內部只能訪問和修改這個局部變量,其余兩個同名變量被隱藏,無法直接訪問或修改。所以說,作用域機制提供了一定程度的隔離,可以防止子觸發器意外修改外部變量,從而避免潛在的錯誤和不可預測的行為,保持代碼的清晰和可維護性。

??根據作用域劃分,觸發器中的變量可以分為全局變量、函數局部變量、觸發局部變量、子觸發器局部變量和組變量。根據類型劃分,可以分為對象型變量(如單位、單位組、玩家組、單位命令)和非對象型變量(如字符串、實數、整數、布爾值)。

??子觸發器內部對于賦值運算(非單位類型局部變量的修改)只會在子觸發器內部生效,不會影響外部;但是對對象型變量(如單位組、玩家組等)的操作以及對單位屬性的修改會同步影響到外部。這種設計有助于在保持局部變量隔離性的同時,允許對共享資源進行必要的修改(單位對象是一個全局可訪問的對象)。

??下面使用全局字符串、全局單位類型、局部字符串、局部單位類型;全局單位組、局部單位組這6個變量進行測試。

  1. 先打印每個類型的初始值

    [Info]: 全局字符串AAA
    [Info]: 全局單位類型UnitName:134219749張飛)
    [Info]: 局部字符串BBB
    [Info]: 局部單位類型UnitName:134274912(關羽)[Info]: 全局單位組中單位數量1
    [Info]: 局部單位組中單位數量1
    
  2. 通過子觸發器修改這4個變量的值并打印
    在這里插入圖片描述
    在這里插入圖片描述

    [Info]: 全局字符串CCC
    [Info]: 全局單位類型UnitName:134220068(大喬)
    [Info]: 局部字符串DDD
    [Info]: 局部單位類型UnitName:134257382(小喬)[Info]: 全局單位組中單位數量2
    [Info]: 局部單位組中單位數量2
    
  3. 通過其他子觸發器再次打印變量的值:

    [Info): 全局字符串CCC
    [Info): 全局單位類型UnitName:134220068(大喬)
    [Info]: 局部字符串BBB
    [Info): 局部單位類型UnitName:134274912(關羽)[Info]: 全局單位組中單位數量2
    [Info]: 局部單位組中單位數量2
    

2.3 復合條件

??if流程語句的結構如下,條件可以是取反(not語句)、所有條件成立(and語句)、任意條件語句(or語句)或者所有條件不成立。
在這里插入圖片描述
所有條件成立:A和B都等于1 ,則單位會移動到指定的點
在這里插入圖片描述
任意條件成立:A和B有一個等于1,則單位會移動到指定的點。
在這里插入圖片描述
所有條件不成立:整數A 和整數B 都不等于 1,則單位會移動到指定的點。
在這里插入圖片描述
如果A等于1,則單位會移動到指定的點A;否則,會移動到點B。
在這里插入圖片描述

2.4 循環

在這里插入圖片描述
循環是指重復執行某項動作。在Y3編輯器中,循環有三種類型:

  1. 指定次數或指定整數變量重復執行:這是最常用的循環觸發方式,例如,設定NPC敲門三次,動作會重復三次后自動停止。

  2. 條件成立,重復執行:在條件滿足的情況下,進行無限次的循環,直到條件不再滿足。例如,如果條件是門關著就敲門,那么敲門動作會一直重復,直到門開了才會停止。

  3. 遍歷數組變量循環:根據數組的索引數字,對數組中的每個單位重復執行動作。例如,有一個不同門的列表,NPC會按照順序敲門,直到所有門都被敲過。

下面是《觸發器2:循環》中的例子,通過第一種循環實現在BOSS周圍出現6個次元種子的效果。

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

2.5 計時器

在這里插入圖片描述

??計時器就好比一個沙漏,在計時結束后開始執行某項動作。我們可以用計時器來處理和時間有關的游戲邏輯。在編輯器中,計時器一共有三種:

  1. 運行單次計時器:計時器運行一次后開始執行動作。例如,倒數三秒后約翰的門就會打開。
  2. 運行循環計時器:計時器循環運行,每次運行后都會執行動作。例如,每隔一秒約翰的門就會打開一次。
  3. 運行固定次數的計時器:計時器中間停留固定時間,固定次數的計時器。例如,每隔一秒約翰的門就會打開一次,一共打開三次。

??下面是《觸發器:計時器》中,使用計時器實現一只只次元入侵者每隔2s在“裂縫”處爬出的效果。

在這里插入圖片描述

注意:你可以選擇True并立即執行動作,或者選擇False在2秒后執行第一個動作。

在這里插入圖片描述

2.6 單位組

在這里插入圖片描述

??單位組是由一個或多個單位組成的集合,在單位組中,我們能同時對所有的單位或選擇某些單位發布命令。合理利用單位組,我們可以在游戲制作中節省大量的時間。下面是在《觸發器:單位組》中,使用單位組實現主人公發送特技“次元入侵”,入侵者瞬間死傷殆盡的效果。

在這里插入圖片描述

在這里插入圖片描述

2.7 玩家組

在這里插入圖片描述
??玩家組是一個包含一個或多個玩家的集合。您可以直接對玩家組中的所有玩家執行操作。例如,下面的語句表示在點A創建一個關羽單位,并將該單位分配給玩家組BB中的每個玩家,單位面向180°角度。
在這里插入圖片描述

2.8 運動器

在這里插入圖片描述

??運動器可以為單位或者特效等添加運動效果,比如沿著直線運動或追蹤某一個單位等,是制作技能、特效等場景中十分常用的功能。

??在Y3編輯器中,運動器分為追蹤運動器、曲線運動器、直線運動器、環繞運動器(對單位)、環繞運動器(對點)。您可以設置運動器的 方向、距離、初始速度和加速度,以及一些可選參數。
在這里插入圖片描述
下面是《觸發器:運動器》中,使用環繞運動器(對單位),實現電球的環繞和爆炸效果。
在這里插入圖片描述

  • 在物編器中創建一個自定義投射物"Electric ball"(球形藍色電流攻擊)作為環繞的球體,設置縮放0.4倍大小,勾選循環播放,讓特效一直播放。
  • 設置自定義投射物"Explosion"(藍色電流沖擊波,0.3倍縮放)作為結束時的爆炸效果。
  • 新建電球投射物:創建一個投射物變量"Electric ball",投射物類型選擇預設的投射物"Electric ball",選擇在點創建,創建的位置點,選擇探險者所在的點。
  • 新建運動器:選擇運動器->環繞運動器對單位,兩個參數分別設為變量"Electric ball"和探險者,環繞半徑為200,角速度為100。在可選參數中,添加環繞時間5s和環繞高度100
  • 新建投射物爆破動作:在運動完成動作列表下添加動作,在探險者所在的點創建投射物"Explosion",持續時間1s
  • 優化游戲內存:銷毀投射物"Electric ball"并移除運動器(為單位移除運動器,單位選擇探險者)。

在這里插入圖片描述

三、案例

3.1 NPC對話

  1. 添加“Talk”屬性:通過物體編輯器給NPC添加自定義屬性“Talk”來存儲對話內容。
    在這里插入圖片描述

  2. UI設計:通過界面編輯器設計聊天UI,這包括背景、NPC頭像、文本和退出按鈕。
    在這里插入圖片描述

在這里插入圖片描述
3. 顯示聊天內容:創建一個顯示函數,參數為“NPC”單位。在函數里創建兩個本地變量存儲NPC頭像的ID和自定義屬性“Talk”。然后再創建界面組件“Icon”和“Talk text”并讀取這兩個變量。這樣當你具體調用與某個NPC的對話函數時,玩家UI就會出現其頭像和文字內容。
在這里插入圖片描述

  1. 統一NPC對話入口
    • 當玩家靠近并點擊NPC時,程序通過自定義函數統一處理觸發事件,傳遞玩家角色和NPC作為參數。
    • 函數獲取對應NPC的一系列信息參數,并顯示在聊天界面。
    • 設計退出按鈕,當玩家點擊時,設置一個布爾值標記為‘true’以關閉界面。另外使用循環計時器檢測玩家與NPC的距離,如果超過500也會關閉界面。和前面的統一入口的實現邏輯是類似的,我們需要把不同的退出方式進行單獨處理,并最后通知在同一個出口上。

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

  1. 功能優化:為了保持界面關閉和顯示功能在同一模塊下,選擇一種相對消耗性能的方式,即使用一個布爾值類型的變量Switch來控制界面的開啟和關閉狀態。界面在啟動時會循環檢測Swich的狀態,默認狀態下,Swich為false,當玩家點擊退出按鈕時,我們在事件的動作中設置Swich為True
    在這里插入圖片描述

  2. 整體實現:當玩家在地圖上選擇一個單位時,如果檢測到是NPC,則調用函數Z02.一次NPC對話事件,并讓玩家重新選中玩家角色。只有當玩家與NPC的距離小于400時,才啟動對話功能,否則提示距離過遠。
    在這里插入圖片描述

在這里插入圖片描述

3.2 裝備限制

??對裝備的品類或者數量做限制是RPG類游戲中一個常見的機制,例如一個玩家覺得只能攜帶一把武器和一件裝甲,比如在FPS游戲中,玩家同時只能持有一把槍,想要切換到另一把槍就會把當前持有的武器移除掉,這些實際上的游戲效果都是裝備限制。

3.2.1 裝備拾取

??當玩家拾取裝備時,如果玩家單位上沒有該類型的裝備,則會直接進行裝備。否則拾取的裝備將被直接丟棄(系統丟棄,不會通知玩家,也不會觸發任何與玩家丟棄裝備相關的游戲事件或流程)。

  1. 裝備數據存儲:使用自定義值功能為每個裝備添加一個type屬性,用于標識裝備的類型。設置一個SystemDiscard標記,用于指示某個裝備的丟棄是由系統自動處理的,而不是玩家的操作。

  2. 拾取物品:當玩家拾取一個物品時,系統會創建兩個局部變量,分別存儲玩家單位和拾取的物品。

  3. 邏輯判斷

    • 如果玩家單位已經裝備了相同type的裝備,那么新拾取的裝備將被系統丟棄。
    • 如果玩家單位沒有裝備相同type的裝備,玩家將成功獲得新裝備,同時,系統會更新玩家持有物品的狀態,以便后續可以顯示相應的特效或其他游戲效果。
      在這里插入圖片描述

以上代碼邏輯為:

  1. 初始化變量:設置變量unit為獲得物品的單位,item為單位獲得的物品。

  2. 檢查物品類型:如果item存在自定義鍵值"type",則繼續執行。

  3. 檢查玩家是否已裝備相同類型的物品

    • 如果玩家單位unit已經存在自定義鍵值type,并且與itemtype相同,則執行系統丟棄邏輯。
    • 如果unit不存在自定義鍵值type,或者typeitemtype不同,則執行裝備邏輯。
  4. 系統丟棄邏輯

    • 設置item的自定義鍵值"SystemDiscard"True,表示這是一個系統自動處理的丟棄。
    • itemunit所在位置移除。
  5. 裝備邏輯

    • 向玩家發送消息,告知玩家已經獲得了新的物品。
    • 更新玩家單位的自定義鍵值typeitemtype
    • 發送自定義事件ProjectCreation,參數為unititem,用于可能的特效或其他邏輯的觸發。
3.2.2 物品丟棄

與拾取物品類似,當一個單位丟棄物品時,先使用局部變量對參數進行緩存,然后執行判斷:

  • 玩家丟棄:如果物品被判斷是玩家手動拋棄,獲取物品type,清空單位對應自定義值項,這個清空的動作會導致特效結構檢測到數據清空,從而觸發特效的銷毀。
  • 系統丟棄:如果該物品被檢測為系統丟棄,則跳過整個流程,當做無事發生(系統丟棄是靜默的,不會通知玩家,不更新玩家狀態,因此不會有新的特效或其他游戲效果被激活)。
    在這里插入圖片描述

以上代碼邏輯為:

  1. 初始化變量:設置變量unit為失去物品的單位,item為單位失去的物品。

  2. 檢查物品類型:如果item存在自定義鍵值"type",則繼續執行。否則發送調試信息“丟棄的物品無類型”

  3. 檢查是否為系統丟棄

    • 如果item的自定義鍵值"SystemDiscard"False,則執行玩家丟棄邏輯。
    • 如果為True,則表示這是一個系統自動處理的丟棄,不執行任何操作。
  4. 玩家丟棄邏輯

    • 設置typeitem的自定義鍵值type(在玩家丟棄裝備的過程中,臨時存儲裝備的類型信息,以便在后續的邏輯中使用這個信息來更新玩家狀態、觸發相關邏輯或發送消息等)
    • 刪除unit的自定義鍵值type,表示玩家已經失去了這個類型的裝備。
    • 向玩家發送消息,告知玩家已經丟棄了物品。
  5. 系統丟棄邏輯

    • 刪除item的自定義鍵值"SystemDiscard",重置物品的狀態,這樣,如果物品再次被拾取或處理,系統可以重新判斷其狀態,而不是基于之前的標記。
    • 向玩家發送調試消息“丟棄的物品為系統丟棄”

3.3 特效

??想要為一個已有的事件附加另一個效果,可以使用自定義事件功能,比如在獲得新裝備后,可以發送一個自定義事件,來激活對應的特效功能。

3.3.1 特效生成

通過發送和接收自定義事件來傳輸信息,實現特效的激活:

  • 武器特效:武器特效是直接綁定在角色手部的拖尾,所以我們只需要直接將對應的特效路徑以自定義值的形式保存在物品上,就可以用同一個函數啟用所有的武器特效。

  • 護甲特效:由多個特效組合而成,需要一個函數來不斷生成和銷毀這些特效。
    在這里插入圖片描述

  • 特效分斂:根據自定義事件傳遞的物品和type參數,分斂到不同類型的特效創建函數,執行對應的效果。
    在這里插入圖片描述

如果自定義事件ProjectCreation被觸發,則根據物品類型通知不同的特效生成機制:

  • 如果自定義事件參數item的物品類型等于“寒冰劍”或“閃電發生器”,則設置變量projectType為物品的projectType,并為事件單位unit的物品item生成特效projectType
  • 如果item的物品類型等于“冰霜斗篷”,則為事件單位unit的物品item生成盔甲01特效
  • 如果item的物品類型等于“地精的護服”,則為事件單位unit的物品item生成盔甲02特效
3.3.2 特效銷毀

??在函數庫中,我們新建三個函數,分別是武器,盔甲1和盔甲2,來分別執行武器和盔甲的特效創建和銷毀過程。

??對于武器特效功能,是在單位的節點添加一個拖尾特效projectType,同時啟動一個循環計時器,定期檢查玩家是否仍然持有該武器。如果玩家更換或丟棄了武器,特效將被移除,并對所有結構進行銷毀。
在這里插入圖片描述

  • 定義了一個名為“X01: 生成武器特效”的函數,該函數接收三個參數:unit(單位),item(物品),projectType(特效類型)。
  • 為單位添加魔法效果projectType,并將此創建魔法效果賦值給變量project,方便后續刪除
  • 設置變量typeitemtype
  • 啟動循環計時器,每隔一秒檢測一次,檢測unittype是否等于item。是則繼續,否則刪除計時器和project

??盔甲1的特效顯示邏輯和武器特效類似,也是每秒檢測一次。不同的是,盔甲的特效將在每秒計時器到時后立即生成,并在兩秒后將其銷毀。
在這里插入圖片描述

為了顯示盔甲2的特殊效果,我們為單位創建了兩個投射物,并使用局部變量進行儲存。

  • 角度:為了實現球體的環繞效果,我們需要定義一個角度,這個角度將會每幀進行遞增,以實現幀疊加以后的球體圓周運動。
    在這里插入圖片描述
  • 檢測:使用一個幀計時器(0.03秒)來檢測裝備是否還在被裝備,如果它被丟棄,對所有結構進行銷毀;否則繼續執行
  • 循環:當程序一直持續循環運行,球體的角度會在每一幀減去6,并根據一個固定的距離,以角色位置為圓心,通過極坐標系確定本幀投射物該在的位置。
    在這里插入圖片描述
  1. 函數定義:定義了一個名為X03: 生成護甲2特效的函數,接收兩個參數:unit(單位)和item(物品)。

  2. 變量初始化

    • type變量被設置為itemtype屬性,用于區分不同類型的裝備。
    • int變量被初始化為0,可能用于控制特效的生成或更新。
    • angle01angle02變量被初始化為90.0和270.0,用于確定特效的初始位置。
    • 在單位的位置創建兩個護甲特效,分別命名為project[1]project[2]
  3. 循環計時器:創建一個循環計時器,每0.03秒執行一次,用于更新特效的位置。 如果單位裝備了“地精的護服”,則繼續執行循環,否則銷毀所有特效。

  4. 更新特效位置

    • angle01angle02變量用于控制特效的旋轉角度,每幀都會變化。根據旋轉角度,更新兩個特效project[1]project[2]的位置point1point2.。
    • 設置變量int每幀加1,然后進行條件判斷:
      • 如果int = 1,在point2創建特效project[3]
      • 如果2 ≤ int ≤ 13,持續更新特效project[3]的位置(點point2)。
      • 如果int = 60,重置int = 0

??總的邏輯是每幀檢測一次,如果依舊裝備“地精的護服”,創建兩個特效project[1]project[2]環繞其持有角色,然后每一秒的前13幀,在project[2]的位置同時創建和更新特效project[3]

3.4 行為樹

??行為樹即是用樹狀結構分支使AI能根據條件執行不同行為(如走、跑、跳、攻擊),讓單位通過模擬真實玩家的行動而擁有“智能”行為,增強玩家的參與感,例如PVE的敵人,BOSS的戰斗模式,玩家召喚物等。

  1. 初始化行為樹:初始化前,需要創建一個全局變量(比如unitPlayer)來存儲玩家角色,創建一個全局變量單位組來存儲敵方單位。通過動作:“玩家-選擇單位”,讓玩家選中自己的主控單位。為了更沉浸的游玩體驗,使用“鏡頭 - 跟隨單位”功能讓玩家的視角能始終跟隨在自己的英雄上。
    在這里插入圖片描述

  2. 行為樹分斂

    • 游戲初始化結束(游戲開始0.1秒后),每隔1秒遍歷一次地方單位組,每次遍歷所有單位,根據地方單位類型(近衛和治療者),對其應用對應的行為樹。
    • 判斷完單位類型后,通過自定義事件傳遞單位參數來實現行為樹的分發。參數必須是變量,不支持數組。比如行為樹是針對某單位執行,那么就需要將單位作為參數傳遞出去。
      在這里插入圖片描述
      在這里插入圖片描述
  3. 實現守衛AI

    • 新建一個單位類型局部變量unit,存儲通過“自定義事件:AI_Guard”發送過來的單位。
    • 新建一個實數類型局部變量distance,用于儲存敵人和治療者之間的距離,通過判斷distance是否小于300來判斷治療者是否安全。
      • 如果治療者不安全(距離小于300),則給單位unit向玩家角色unitPlayer發出一個攻擊指令。
      • 如果治療者安全,判斷守衛自身HP,低于50%則移動至治療者(給單位unit向unitHealer發出一個移動指令)。
      • 如果守衛安全,檢查警戒區域內是否有敵人,有則攻擊,無則巡邏。

在這里插入圖片描述

  1. 實現治療者AI:新建一個單位類型局部變量unit,存儲通過“自定義事件:AI_Healer”發送過來的單位。優先保障自身安全,滿HP(自己的HP是否等于其MaxHP)則治療友軍中HP最低的單位(如果有的話),沒有需要治療的單位則進行攻擊。
    • 使用一個函數獲取當前最需要治療的友軍。
      • 新建局部變量Temp(百分比格式,初始化為1)和unit(單位類型)分別存儲單位組中最低的HP百分比及遍歷到的單位。
      • 逐一將unit血量和Temp對比,如果unit血量更低則將Temp更新為這個值。當遍歷完全以后,我們就獲取到了單位組中HP百分比最低的那一個單位。
      • 返回HP百分比最低的那一個單位

在這里插入圖片描述

  • 如果HP百分比最低單位為空(友軍都是滿血),判斷自己身邊是否有敵人,如果有,就使用飛彈攻擊它;沒有則在警戒區域的中心不動,以方便巡邏的守衛保護自己。
  • 如果有HP百分比最低的單位,則停止當前的動作(這里并非使用‘技能’來實現治療,所以為了防止治療者邊攻擊邊治療,需要先停止攻擊動作)并對其進行治療。為了讓這種動作更具真實感,我們可以播放對應的動畫動作,并為治療效果添加一個特效。

在這里插入圖片描述

3.5 使用排行榜

  1. 點擊主界面【細節】-【存檔設置】打開存檔槽設置

  2. 點擊加號創建一個新的存檔槽并修改存檔槽數據類型為整數
    在這里插入圖片描述

  3. 選擇確認計入排行榜,這個存檔槽位就變成了排行榜存檔。可以選擇排行榜排序規則(升序降序)與排行榜最大人數。
    在這里插入圖片描述

  4. 使用以下eca可以獲取排行榜上所有玩家的存檔值,配合界面eca讓排行榜在界面顯示。玩家->整數型增量存檔eca可以讓整數類型存檔保持只增效果。
    在這里插入圖片描述

排行榜數據在游戲啟動后不會再刷新,使用雙槽位可以實現周排行榜

  • 創建兩個整數類型存檔槽位:A與B,A存儲第一周所有玩家的排行榜數據

  • 當一周結束時(通過時間戳判斷),使用B榜存儲玩家在第二周的排行數據

  • 在第二周開始時通過ECA清除玩家A槽位數據,以備第三周存儲玩家排行數據。需通過在作者之家清除A榜數據(權限需找運營申請)。
    在這里插入圖片描述

  • 當第二周結束時,將玩家排行榜數據存儲在A榜并清除B槽位數據,循環往復

3.6 特效可見性

特效默認為全玩家可見,可通過ECA控制特效可見性。

  • 通過“玩家”列表操作,實現對某個玩家的特效顯示/屏蔽
  • 通過“玩家組”列表操作,實現對某個玩家組的特效顯示/屏蔽,比如某玩家的所有同盟玩家,某玩家的所有敵對玩家等等

在這里插入圖片描述
在這里插入圖片描述

3.7 不同步問題

參考《不同步相關》

3.7.1 本地配置不同步日志環境

??用戶由于使用ECA不當,頻繁出現游戲邏輯不同步的問題,會影響游戲正常運行。此時可通過在本地多開測試來進行調試。在【通用設置-調試】打開本地多開同步檢測。

在這里插入圖片描述
??使用Lua文件配置更詳細的不同步日志:打開地圖路徑下Script文件夾下的main.lua文件,在lua文件中配置不同步日志相關API
在這里插入圖片描述

GameAPI.api_set_enable_detail_snapshot(true)
GameAPI.api_set_detail_snapshot_enable_tag(0xfffffff)
GameAPI.api_set_enable_eca_snapshot(true)
GameAPI.api_set_snapshot_traceback_level(2)

??配置完畢后,本地多開運行游戲。如遇游戲邏輯不同步,會有彈窗提示,并在本地生成不同步日志以供用戶定位不同步問題。
在這里插入圖片描述
在這里插入圖片描述

不同步日志Lua配置API說明:

API描述參數返回值
api_set_enable_detail_snapshot控制不同步日志記錄的總開關。關閉后,其他設置接口將不生效,但可以提升性能。enable(bool):是否開啟,默認為false
api_set_snapshot_traceback_level設置日志堆棧記錄詳細等級,默認0不記錄
1:僅記錄最近一層堆棧
2:記錄完整堆棧(數據壓縮)
3:記錄完整日志(不壓縮,數據量稍大)
記錄越完整越有利于定位問題,但開銷增大
level(int32):堆棧記錄等級,默認值為0
api_set_enable_timer_snapshot開啟或關閉計時器不同步檢測日志(檢測額外創建的ECA計時器),但計時器不一致并不一定意味著游戲內容不同步。enable(bool):默認值為false
api_set_enable_eca_snapshot開啟或關閉ECA不同步檢測日志,開銷較高。可通過參數過濾掉一些安全的API以防止誤報,例如創建特效、UI操作等enable(bool):默認值為false
filter_mode(int32):過濾模式,默認為1
1:剔除模式,不記錄filter_set中指定的api;
0:包含模式,僅記錄filter_set中指定的api;
filter_set(table):過濾集合,默認為"client_only","client_possible"
可傳入想要剔除/包含的API(取決于上個參數)
如"GameAPI:print_to_dialog",“GameAPI:get_function_return_value。”
api_set_detail_snapshot_enable_tag設置不同步詳細日志級別。越詳細越利于定位不同步產生點,但性能消耗會增高tag(UInt64):控制開啟哪些日志的mask
1運動器tick;2運動器碰撞檢測
4尋路回調;8尋路坐標更新
16血量變化;32坐標瞬變
0xFFFFFFFF全部開啟;默認開啟16+32
add_detail_log記錄自定義日志log(string):日志內容bool,值恒定為true
3.7.2 線上游戲不同步定位
  1. 在本地配置不同步日志環境
    打開地圖路徑下Script文件夾下的main.lua文件,在lua文件中配置不同步日志相關API,這樣線上游戲發生不同步時,根據配置API玩家客戶端會自動上傳日志。例如:
GameAPI.api_set_enable_detail_snapshot(true)
GameAPI.api_set_detail_snapshot_enable_tag(0xfffffff)
GameAPI.api_set_enable_eca_snapshot(true)
GameAPI.api_set_snapshot_traceback_level(2)
  1. 下載不同步日志
    使用KK賬號登錄編輯器,打開任意地圖,點擊【菜單欄】【調試】【查看不同步日志】查看線上游戲的不同步日志。
    在這里插入圖片描述
    查找需要定位問題的對局,下載不同步日志,不同步日志包含對局中所有玩家的對戰信息。
    在這里插入圖片描述
3.7.2 定位不同步問題

??不同步日志文件中包含的是出現不同步情況的幀信息,通過對比玩家日志差異,可以大致定位到問題所在。打開不同步日志文件夾,使用第三方文本對比工具進行對比(推薦使用BeyondCompare)。比如在main.lua文件中進行了如下配置:

GameAPI.api_set_enable_detail_snapshot(true);
GameAPI.api_set_enable_timer_snapshot(true);

打開不同步日志,查看逐幀信息:

在這里插入圖片描述
將多名玩家日志成對拖放到beyondcompare中進行對比,發現玩家2比玩家1多了一個timer:
在這里插入圖片描述
??通過對不同步信息附近的幀信息進行理解,可大致定位問題為某個客戶端上多了一個循環計時器,在項目中進行查找可能的問題所在。
在這里插入圖片描述

3.7.3 游戲不同步的原因
  • 本地值
    • 在單個客戶端(即單個玩家的設備)上有效的數據,比如界面顯示、特效、鏡頭位置、聲音等,這些數據在不同的客戶端之間不需要同步,因為它們只影響單個玩家的體驗。
    • 任意值與【本地值】進行邏輯運算后得到的值等價于【本地值】
    • 動作類ECA中,修改【本地值】,不會影響游戲的全局邏輯,因此不會影響游戲的同步性。
  • 本地操作:針對本地值的操作,如【獲取本地玩家】、【獲取本地控件坐標】、【獲取鏡頭焦點】、【獲取滑動條當前值】等,這些獲取本地值的ECA函數,在不同客戶端得到的結果也是不同的。
  • 全局值:在所有客戶端之間需要保持一致的值,比如單位、技能、物品等。這些值的一致性對于游戲的公平性和邏輯一致性至關重要。
  • 全局操作:針對全局值的操作,比如修改單位的狀態、技能的效果、物品的數量等。這些操作會影響游戲的全局邏輯,因此需要確保在所有客戶端上都能正確同步。

??導致游戲邏輯不同步的一個重要原因就是將【本地值】作為參數,傳遞到【全局操作】中,或者是使用【本地值】進行邏輯判斷后,進行【全局操作】。這會導致不同客戶端執行不同的邏輯,最終導致不同客戶端上【全局值】不同,即游戲邏輯不同步。更多內容詳見文檔多人聯機同步機制。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62730.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62730.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62730.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端WebSocket應用——聊天實時通信的基本配置

使用 WebSocket 實現實時通信的 Vue 應用 前言1. WebSocketService 類 1.1 類屬性1.2 構造函數和連接初始化1.3 WebSocket 連接1.4 事件處理方法1.5 發送和關閉 WebSocket 消息1.6 狀態查詢與回調注冊1.7 完整代碼 2. 在 Vue 組件中使用 WebSocketService 2.1 定義 WebSocket …

【開源】A065—基于SpringBoot的庫存管理系統的設計與實現

🙊作者簡介:在校研究生,擁有計算機專業的研究生開發團隊,分享技術代碼幫助學生學習,獨立完成自己的網站項目。 代碼可以查看項目鏈接獲取??,記得注明來意哦~🌹 贈送計算機畢業設計600個選題ex…

基于python實現自動化的驗證碼識別:探索與實踐

基于python實現自動化的驗證碼識別:探索與實踐 一、驗證碼的類型及特點(一)圖像驗證碼(二)短信驗證碼(三)語音驗證碼 二、驗證碼識別的方法*(一)傳統圖像處理方法&#x…

Vue vs. React:兩大前端框架的深度對比與分析(一)

前言 在當今快速發展的前端領域中,Vue和React作為兩個備受矚目的前端框架,已經成為許多開發者的首選。這兩個框架憑借其出色的設計和強大的功能,在構建現代化、高效性能的Web應用方面扮演著重要角色。 Vue和React都以其獨特的特點吸引了眾多開…

windows安裝使用conda

在Windows系統上安裝和使用Conda的詳細步驟如下: 一、下載Conda安裝包 訪問Conda的官方網站Anaconda | The Operating System for AI,點擊“Downloads”按鈕。在下載頁面,選擇適合您系統的安裝包。通常,對于Windows系統&#xf…

websocket 服務 pinia 全局配置

websocket 方法類 // stores/webSocketStore.ts import { defineStore } from "pinia";interface WebSocketStoreState {ws: WebSocket | null; // WebSocket 實例callbacks: ((message: string) > void)[]; // 消息回調函數列表connected: boolean; // 連接狀態…

Ariba Procurement: Administration_Cloud Basics

# SAP Ariba Procurement: Administration_Cloud Basics 認識Ariba Cloud SAP Ariba Procurement 是一個云計算平臺… The Ariba Cloud 平臺需要簡單理解的概念: Datacenter數據中心:SAP Ariba在世界各地有許多數據中心。這些數據中心構成了Ariba云的基本物理基礎設施。 …

vulnhub靶場【shenron】--1

前言 靶機:shenron-1 攻擊:kali 都采用虛擬機,網卡為橋接模式 主機發現 使用arp-scan -l或netdiscover -r 192.168.1.1/24掃描 信息收集 使用nmap掃描端口 網站信息探測 查看頁面,發現是apache2的默認界面,查看…

等保2.0數據庫測評之SQL server數據庫測評

一、SQL server數據庫介紹 SQL server美國Microsoft公司推出的一種關系型數據庫系統。SQL Server是一個可擴展的、高性能的、為分布式客戶機/服務器計算所設計的數據庫管理系統。 本次安裝環境為Windows10專業版操作系統,數據庫版本為Microsoft SQL Server 2019 (…

無人機之報警器的工作原理!

一、電量監測技術 電量監測是無人機電量指示和報警功能的基礎。通過實時監測無人機的電池電量,系統能夠準確判斷電池的剩余使用時間,并在電量不足時發出報警。電量監測技術通常包括以下幾個方面: 電壓檢測:無人機電池內部通常配…

【pyspark學習從入門到精通23】機器學習庫_6

目錄 分割連續變量 標準化連續變量 分類 分割連續變量 我們經常處理高度非線性的連續特征,而且只用一個系數很難擬合到我們的模型中。 在這種情況下,可能很難只通過一個系數來解釋這樣一個特征與目標之間的關系。有時,將值劃分到離散的桶中…

解密時序數據庫的未來:TDengine Open Day技術沙龍精彩回顧

在數字化時代,開源已成為推動技術創新和知識共享的核心力量,尤其在數據領域,開源技術的涌現不僅促進了行業的快速發展,也讓更多的開發者和技術愛好者得以參與其中。隨著物聯網、工業互聯網等技術的廣泛應用,時序數據庫…

QT 使用共享內存 實現進程間通訊

QSharedMemory:如果兩個進程運行在同一臺機器上,且對性能要求非常高(如實時數據共享、圖像渲染等),建議使用共享內存。 優點: 高性能: 共享內存是進程間通信的最快方式之一,因為數…

在Scala中對隱式轉換格式與作用

隱式對象 格式:implicit object 作用:給函數的默認參數提供隱式值 object Scala12______10 { // case class DataBase(driver: String, url: String) // // implicit object mySql extends DataBase("mysql", "localhost:300") //…

go build command

文章目錄 1.簡介2.格式3.選項4.示例5.小結參考文獻 1.簡介 go build 是 Go 語言工具鏈中的一個命令,它用于編譯 Go 源代碼并生成可執行文件。 2.格式 go build [-o output] [build flags] [packages]可選的 -o 選項強制 build 將生成的可執行文件或對象寫入指定的…

OpenCV實驗:圖片加水印

第二篇:圖片添加水印(加 logo) 1. 實驗原理 水印原理: 圖片添加水印是圖像疊加的一種應用,分為透明水印和不透明水印。水印的實現通常依賴于像素值操作,將水印圖片融合到目標圖片中,常用的方法…

WinDbg 中使用 !process 命令

PROCESS 81a979d0 SessionId: 0 Cid: 0210 Peb: 7ffda000 ParentCid: 063cDirBase: 145b9000 ObjectTable: e12fed70 HandleCount: 53.Image: Dbgview.exe 1. PROCESS 81a979d0 意義:PROCESS 是該進程對象的內核地址。用途:可以使用這個地址獲…

深入解析下oracle的number底層存儲格式

oracle數據庫中,number數據類型用來存儲數值數據,它既可以存儲負數數值,也可以存儲正數數值。相對于其他類型數據,number格式的數據底層存儲格式要復雜得多。今天我們就詳細探究下oracle的number底層存儲格式。 一、環境搭建 1.…

SparkSQL與Hive的整合

文章目錄 SparkSQL與Hive的整合1.1. Spark On Hive1.1.1. Hive的準備工作1.1.2. Spark的準備工作1.1.3. Spark代碼開發1.1.4. Spark On Hive案例 1.2. Hive On Spark1.3. SparkSQL命令行1.4. SparkSQL分布式查詢引擎1.4.1. 開啟ThriftServer服務1.4.2. beeline連接ThriftServer…

(持續更新)linux網絡編程中需要注意的內核參數與網絡機制

目錄 零、基本說明 一、內核參數 二、相關機制 1、GRO (1)適用場景 (2)優缺點 (3)相關操作 2、Nagle 算法 (1)基本規則 (2)優缺點 (3&…