最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Minecraft 生物 AI 機(jī)制詳解(一)

2023-01-13 13:42 作者:Nickid2018  | 我要投稿

在 MC 中生物有多種多樣的行為,這些行為都是通過(guò)其 AI 系統(tǒng)計(jì)算得到的。這篇專(zhuān)欄就來(lái)講一講生物 AI 是如何計(jì)算的。

一. 生物 AI 的分類(lèi)

目前 MC 中擁有兩套獨(dú)立的 AI 計(jì)算系統(tǒng),每個(gè)生物有且僅有一種計(jì)算系統(tǒng)。為了方便講述,我們?cè)谶@里將這兩種系統(tǒng)取名為目標(biāo)系統(tǒng)(Goal System)和記憶行為系統(tǒng)(Memory-Behavior System),這兩套系統(tǒng)除了尋路系統(tǒng)、基礎(chǔ)探測(cè)系統(tǒng)和控制器外使用的代碼完全不同。

目前使用記憶行為系統(tǒng)的生物只有村民、豬靈、豬靈蠻兵、疣豬獸、僵尸疣豬獸、山羊、悅靈、青蛙、蝌蚪、監(jiān)守者和駱駝,剩余的所有生物都使用目標(biāo)系統(tǒng)。目標(biāo)系統(tǒng)能實(shí)現(xiàn)的行為比較少,而記憶行為系統(tǒng)實(shí)現(xiàn)的行為可以更加復(fù)雜,可以實(shí)現(xiàn)生物不同“活動(dòng)”狀態(tài)和實(shí)現(xiàn)村民的時(shí)間表。

二. 控制器

生物的 AI 系統(tǒng)有兩種,而控制器只用了一套系統(tǒng)。生物能做到的基礎(chǔ)動(dòng)作都由控制器決定,由控制器控制的動(dòng)作都會(huì)按照時(shí)間平滑地運(yùn)行,而不是讓生物立刻到達(dá) AI 行為想到達(dá)的狀態(tài)。生物的控制器具體有:

  • LookControl:視線(xiàn)控制器。可以輸入一個(gè)向量或一個(gè)實(shí)體作為看向的位置。如果看向了生物,就會(huì)選擇去看生物的眼睛,否則看實(shí)體的中心。

  • MoveControl:移動(dòng)控制器。移動(dòng)有四個(gè)狀態(tài),分別是 WAIT(等待)、MOVE_TO(移動(dòng)到指定位置)、STRAFE(沿指定方向行進(jìn))和 JUMPING(跳躍)。AI 系統(tǒng)通常不是直接調(diào)用這個(gè)控制器,而是使用尋路系統(tǒng)調(diào)用 MOVE_TO 從而間接調(diào)用這個(gè)控制器。移動(dòng)控制器每刻計(jì)算一次,執(zhí)行移動(dòng)后立刻設(shè)置為等待狀態(tài)(除非在移動(dòng)到目標(biāo)位置時(shí)需要跳躍,進(jìn)入跳躍狀態(tài)),并等待下一刻尋路系統(tǒng)的指令。

  • JumpControl:跳躍控制器。這個(gè)控制器也可以被移動(dòng)控制器在決定跳躍時(shí)調(diào)用。

  • BodyRotationControl:旋轉(zhuǎn)控制器。主要用于頭和身體的旋轉(zhuǎn),用于平衡視線(xiàn)控制器和移動(dòng)控制器對(duì)生物的旋轉(zhuǎn)方向。AI 系統(tǒng)不會(huì)對(duì)這個(gè)控制器直接調(diào)用,下文也不會(huì)涉及這個(gè)。

控制器可以被繼承并被增加行為,比如說(shuō)繼承于 MoveControl 的 FlyingMoveControl,它的內(nèi)部是可飛行生物的移動(dòng)控制器。在下文中我們基本上只使用各個(gè)控制器的基類(lèi)作為說(shuō)明。

三. 探測(cè)系統(tǒng)

生物可以探測(cè)到其他實(shí)體的存在。探測(cè)實(shí)體是否在視線(xiàn)內(nèi)并記錄的類(lèi)就是 Sensing(不是 Sensor,Sensor 是記憶行為系統(tǒng)使用的)。而檢查生物是否能看到某個(gè)實(shí)體的具體方法位于 Mob 類(lèi)的 hasLineOfSight,具體代碼如下:

從這段代碼中,我們可以看出生物能被探測(cè)到的實(shí)體需要符合下面的條件:

  • 生物與能被探測(cè)到的實(shí)體在同一個(gè)維度。

  • 生物與能被探測(cè)到的實(shí)體距離 128 格以?xún)?nèi)。

  • 生物與能被探測(cè)到的實(shí)體的眼睛連線(xiàn)中間不能被方塊的碰撞箱阻擋。

這個(gè)視角下苦力怕的視線(xiàn)會(huì)被柵欄的 1.5 格高的碰撞箱阻擋導(dǎo)致看不到玩家

在 1.17 Pre-release 1 之前,這個(gè)方法并沒(méi)有前兩條限制,導(dǎo)致了 MC-202249 這個(gè)漏洞。具體辦法就是:在可憤怒生物針對(duì)你的時(shí)候傳送到別的維度,如果坐標(biāo)太大會(huì)導(dǎo)致嘗試加載大量的區(qū)塊做碰撞計(jì)算,進(jìn)而使服務(wù)器崩潰。

生物根據(jù)方塊的碰撞箱計(jì)算是否能看到別的實(shí)體,所以生物是不能通過(guò)玻璃等透明方塊“看到”玩家的。

除了視線(xiàn)判定外,生物探測(cè)還需要檢查生物與實(shí)體之間的距離,這部分代碼是 TargetingConditions 負(fù)責(zé)的,它的重要代碼如下:

從這段代碼中,我們可以看出:

  • 生物不會(huì)探測(cè)自己。

  • 如果被探測(cè)實(shí)體不能被任何生物看到,生物就沒(méi)法探測(cè)這個(gè)實(shí)體。只有三種情況滿(mǎn)足這個(gè)條件:玩家處于旁觀(guān)者模式、實(shí)體已經(jīng)死亡和當(dāng)作標(biāo)記的盔甲架。

  • 如果這個(gè)探測(cè)條件用于攻擊,而被探測(cè)實(shí)體不會(huì)被視作攻擊對(duì)象或世界處于和平難度,那么生物無(wú)法探測(cè)到這個(gè)實(shí)體。實(shí)體不會(huì)被視作攻擊對(duì)象有兩種情況:實(shí)體是無(wú)敵的和美西螈正在裝死。

  • 如果這個(gè)探測(cè)條件用于攻擊,而生物本身不會(huì)攻擊被探測(cè)實(shí)體或與被探測(cè)實(shí)體屬于同一隊(duì),就不會(huì)探測(cè)到這個(gè)實(shí)體。

  • 如果生物具有探測(cè)范圍,則檢查被探測(cè)實(shí)體是否在探測(cè)范圍內(nèi)。根據(jù)被探測(cè)實(shí)體的狀態(tài)效果、盔甲數(shù)量和是否潛行判斷最小探測(cè)范圍的半徑,此半徑不會(huì)小于 2,詳細(xì)的算法可以參考 Wiki。有些生物在某些情況下不會(huì)因?yàn)楸惶綔y(cè)實(shí)體的狀態(tài)而縮小探測(cè)半徑,比如喚魔者在探測(cè)周?chē)鷲拦頃r(shí)就不會(huì)因?yàn)閻拦黼[身而受到影響。

  • 如果生物要求看到被探測(cè)實(shí)體但實(shí)際上沒(méi)有看到,探測(cè)也會(huì)失敗。有些生物在某些情況下不要求看到被探測(cè)實(shí)體,比如說(shuō)生物遭受被探測(cè)實(shí)體攻擊時(shí)就不需要看到那個(gè)實(shí)體。

探測(cè)系統(tǒng)在很多方面都有應(yīng)用,比如生物攻擊對(duì)象的選擇,尋找可以繁殖的生物等。

四. 目標(biāo)系統(tǒng)

現(xiàn)在我們來(lái)介紹第一套 AI 系統(tǒng),目標(biāo)系統(tǒng)。它主要由兩個(gè)重要組件構(gòu)成:Goal 和 GoalSelector。

1. Goal

目標(biāo)系統(tǒng)中的目標(biāo)指的就是這個(gè)類(lèi)和它的子類(lèi),它定義了實(shí)體的某一項(xiàng)具體動(dòng)作。它含有的方法如下:

  • canUse:這個(gè)目標(biāo)是否可以執(zhí)行,也就是對(duì)應(yīng)生物某項(xiàng)動(dòng)作的前提。

  • start:目標(biāo)開(kāi)始執(zhí)行時(shí)需要運(yùn)行的代碼。

  • requiresUpdateEveryTick:這個(gè)目標(biāo)在執(zhí)行時(shí)是不是需要每刻都要運(yùn)行。如果不是,每 2 刻才會(huì)執(zhí)行一次 tick。

  • tick:目標(biāo)正在執(zhí)行時(shí)運(yùn)行的代碼。

  • isInterruptable:這個(gè)目標(biāo)執(zhí)行過(guò)程中是否可以被打斷并被其他更高優(yōu)先級(jí)的目標(biāo)替代。

  • canContinueToUse:這個(gè)目標(biāo)是否仍然滿(mǎn)足條件,通常情況下和 canUse 是一樣的。

  • stop:目標(biāo)停止時(shí)需要運(yùn)行的代碼,停止包括條件不滿(mǎn)足而停止和被替代而停止。

每個(gè) Goal 都有一個(gè)標(biāo)志集合,代表它們要占用什么控制器。標(biāo)志有 4 種:MOVE(占用移動(dòng)控制器)、LOOK(占用視線(xiàn)控制器)、JUMP(占用跳躍控制器)和 TARGET(占用攻擊對(duì)象)。有些目標(biāo)不占用任何標(biāo)志,這些目標(biāo)會(huì)在條件滿(mǎn)足時(shí)執(zhí)行,條件不滿(mǎn)足時(shí)停止。

TARGET 是比較特殊的標(biāo)志,使用這個(gè)標(biāo)志的 Goal 都繼承于 TargetGoal,這是一類(lèi)用于選擇攻擊對(duì)象的目標(biāo),而不是用來(lái)描述動(dòng)作的。TargetGoal 都包含兩個(gè)屬性,是否需要看到和是否需要到達(dá)。如果一個(gè) TargetGoal 要求看到而實(shí)體在視線(xiàn)中超過(guò)了一定時(shí)間,那么它就不會(huì)繼續(xù)運(yùn)作。如果 TargetGoal 要求到達(dá)而生物與實(shí)體間沒(méi)有可到達(dá)的路徑,它的條件也就不滿(mǎn)足而終止。

2. GoalSelector

下面就要介紹目標(biāo)系統(tǒng)最重要的部分:目標(biāo)選擇器。

生物可以有多種目標(biāo),而在某一時(shí)刻使用的目標(biāo)并沒(méi)有那么多,并且目標(biāo)之間是有沖突的,所以需要一個(gè)調(diào)配目標(biāo)的代碼。目標(biāo)選擇器就充當(dāng)著這個(gè)作用,它的具體原理是這樣的:

首先,每個(gè)目標(biāo)都有它們的優(yōu)先級(jí),數(shù)字越小,優(yōu)先級(jí)就越高。下面使用史萊姆的 AI 做簡(jiǎn)單介紹:

registerGoals 是生物注冊(cè)目標(biāo)使用的方法。這個(gè)方法內(nèi)分別給 goalSelector 和 targetSelector 注冊(cè)了不同的目標(biāo),而這兩個(gè)選擇器沒(méi)有什么本質(zhì)上的區(qū)別,都是 GoalSelector,只是為了在時(shí)間上分開(kāi)這兩種計(jì)算。GoalSelector 的 addGoal 方法第一個(gè)參數(shù)是優(yōu)先級(jí),第二個(gè)是對(duì)應(yīng)的目標(biāo)。按照這部分代碼的描述,可以做出下方的表格:

不同目標(biāo)的優(yōu)先級(jí)

按照不同目標(biāo)的標(biāo)志,我們可以將這個(gè)表繼續(xù)拆開(kāi)細(xì)化:

根據(jù)不同標(biāo)志拆開(kāi)目標(biāo)的優(yōu)先級(jí),每個(gè)相同名字的目標(biāo)都是一個(gè)對(duì)象,而不是拆成了多個(gè)

目標(biāo)選擇器每 2 刻更新一次,會(huì)選擇每個(gè)標(biāo)志優(yōu)先級(jí)最高可執(zhí)行目標(biāo)作為執(zhí)行的目標(biāo),如果一個(gè)標(biāo)志中的所有目標(biāo)都不滿(mǎn)足它們自身的條件,那么這個(gè)標(biāo)志內(nèi)就沒(méi)有目標(biāo)要執(zhí)行。如果有一個(gè)目標(biāo)滿(mǎn)足條件且優(yōu)先級(jí)高于所有目前它所占用標(biāo)志中正在活躍的目標(biāo),則會(huì)嘗試打斷每個(gè)標(biāo)志中優(yōu)先級(jí)低的目標(biāo)并設(shè)置這個(gè)新的目標(biāo)為對(duì)應(yīng)標(biāo)志的活躍目標(biāo)。如果一個(gè)標(biāo)志被禁用,那么使用這個(gè)標(biāo)志的所有目標(biāo)都不能執(zhí)行。

下面使用史萊姆的 AI 進(jìn)行舉例。假設(shè)史萊姆不在水中且沒(méi)有攻擊對(duì)象,那么 SlimeFloat 和 SlimeAttack 的條件就不滿(mǎn)足,而 SlimeKeepOnJumping 和 SlimeRandomDirection 條件滿(mǎn)足,TARGET 標(biāo)志中沒(méi)有條件被滿(mǎn)足,所以沒(méi)有活躍的目標(biāo)。

如果此時(shí)史萊姆進(jìn)入了水中,這時(shí) SlimeFloat 的條件滿(mǎn)足,打斷 SlimeKeepOnJumping 并調(diào)用其 stop 方法,并將活躍目標(biāo)設(shè)置為 SlimeFloat。

如果史萊姆察覺(jué)到了鐵傀儡,那么優(yōu)先級(jí)為 3 的 NearestAttackable 目標(biāo)條件滿(mǎn)足,并將史萊姆的攻擊對(duì)象設(shè)置為鐵傀儡。在下一次 AI 計(jì)算時(shí),SlimeAttack 因?yàn)橛泄魧?duì)象而滿(mǎn)足條件,SlimeRandomDirection 不滿(mǎn)足條件被停止,所以 LOOK 標(biāo)志中 SlimeAttack 成為活躍目標(biāo)。

這個(gè)例子非常的簡(jiǎn)單,因?yàn)槭啡R姆是 AI 最簡(jiǎn)單的生物之一。接下來(lái)我們換一個(gè)生物進(jìn)行討論,使用 AI 比較復(fù)雜的僵尸。

僵尸目標(biāo)表

從這張表中我們可以看到目標(biāo)可以有相同的優(yōu)先級(jí),有相同優(yōu)先級(jí)的目標(biāo)不會(huì)互相覆蓋,在同時(shí)滿(mǎn)足條件時(shí)將選擇隨機(jī)的一個(gè)(主要和哈希碼大小有關(guān))。

以僵尸攻擊和踩海龜?shù)暗哪繕?biāo)舉例。如果僵尸沒(méi)有攻擊對(duì)象且發(fā)現(xiàn)了海龜?shù)?,此時(shí) ZombieAttackTurtleEgg 滿(mǎn)足條件運(yùn)行。在 LOOK 標(biāo)志中,RandomLookAround 不能執(zhí)行,因?yàn)樵?MOVE 標(biāo)志中它的優(yōu)先級(jí)低于正在活躍的目標(biāo),如果要選擇執(zhí)行只能選擇 LookAtPlayer。這代表了僵尸在踩海龜?shù)皶r(shí)只有可能看向行進(jìn)方向或看向玩家,而不可能隨機(jī)旋轉(zhuǎn)頭去看別的地方。

這時(shí)僵尸發(fā)現(xiàn)了生存模式下的玩家,優(yōu)先級(jí)為 2 的 NearestAttackable 滿(mǎn)足條件,將玩家作為攻擊對(duì)象置位。在下一次 AI 計(jì)算時(shí),ZombieAttack 的條件滿(mǎn)足,打斷 ZombieAttackTurtleEgg。此時(shí) JUMP 標(biāo)志上沒(méi)有活躍的目標(biāo),因?yàn)樵?MOVE 標(biāo)志中 ZombieAttackTurtleEgg 優(yōu)先級(jí)低于 ZombieAttack,不能進(jìn)行替代,所以這個(gè)目標(biāo)也無(wú)法啟動(dòng)。在表面上來(lái)看,就是僵尸放棄去踩海龜?shù)岸侨プ汾s玩家。

從 TARGET 的優(yōu)先級(jí)排序可以看出,僵尸攻擊對(duì)象的排序是:攻擊僵尸的實(shí)體 > 玩家 > 村民或流浪商人 = 鐵傀儡 > 小海龜。這個(gè)排序?qū)е铝斯治镩g可以?xún)?nèi)訌:如果一只骷髏擊中了僵尸,那么僵尸的攻擊對(duì)象就從其他實(shí)體轉(zhuǎn)移到攻擊它的骷髏身上,引發(fā)怪物間的攻擊。

通過(guò)對(duì)這張表的分析,我們也可以看出僵尸不會(huì)自發(fā)的躲避太陽(yáng),它的尋路不會(huì)考慮路徑上是否會(huì)被太陽(yáng)照到。

下面讓我們講一下目標(biāo)系統(tǒng)最后一個(gè)例子,這次我們使用骷髏分析。

骷髏的目標(biāo)表

骷髏含有一個(gè)無(wú)標(biāo)志的目標(biāo),這個(gè)目標(biāo)決定骷髏是否躲避陽(yáng)光,也就是使尋路系統(tǒng)盡量不走向露天的地方。當(dāng)白天且骷髏沒(méi)有頭部盔甲時(shí)此目標(biāo)條件滿(mǎn)足被執(zhí)行,在夜晚或骷髏頭部穿戴上盔甲時(shí)條件不滿(mǎn)足停止。

骷髏的 AI 有一個(gè)特殊的地方,它的攻擊與手上的物品有關(guān)。當(dāng)手上拿弓時(shí)使用?RangedBowAttack 目標(biāo),這使得骷髏可以用弓射擊;如果手上沒(méi)有拿弓,就會(huì)使用?MeleeAttack 目標(biāo)進(jìn)行近戰(zhàn)攻擊。

由于 FleeSun 目標(biāo)(白天躲到不會(huì)使自己著火的位置)和 AvoidEntity 目標(biāo)(躲避狼)處于同一優(yōu)先級(jí),所以這兩個(gè)目標(biāo)互斥,只有其中一個(gè)目標(biāo)結(jié)束后另一個(gè)目標(biāo)才可能執(zhí)行。這就導(dǎo)致了骷髏在躲避狼的時(shí)候不會(huì)主動(dòng)找不會(huì)使自己著火的位置防止燃燒,而在走向不會(huì)使自己著火的位置時(shí)不會(huì)主動(dòng)躲避狼。并且由于這兩項(xiàng)目標(biāo)優(yōu)先級(jí)高于兩個(gè)攻擊目標(biāo),所以骷髏即使被狼傷害并將狼視為攻擊對(duì)象,也很少能向狼發(fā)起攻擊,除非骷髏已經(jīng)離狼足夠遠(yuǎn)并不用擔(dān)心被太陽(yáng)照到時(shí)骷髏才會(huì)開(kāi)始攻擊狼。

五. 常見(jiàn)目標(biāo)

在下面我們列出了一些常見(jiàn)的目標(biāo),有很多生物都使用了這些目標(biāo)。

1. RandomStrollGoal 隨機(jī)游走

許多生物在沒(méi)有攻擊對(duì)象的情況下會(huì)進(jìn)行隨機(jī)的走動(dòng),而實(shí)現(xiàn)這個(gè)隨機(jī)走動(dòng)的就是這個(gè)目標(biāo)和它的子類(lèi)。

這個(gè)目標(biāo)的執(zhí)行條件是:生物不是坐騎,絕大多數(shù)生物還要求隨機(jī)走動(dòng)與上次進(jìn)行動(dòng)作要間隔 100 刻以上。在開(kāi)始執(zhí)行這個(gè)目標(biāo)時(shí)會(huì)計(jì)算一個(gè)隨機(jī)的位置作為游走終點(diǎn),如果這個(gè)終點(diǎn)不存在這個(gè)目標(biāo)也會(huì)執(zhí)行失敗。接下來(lái)將尋路系統(tǒng)設(shè)置到指定的終點(diǎn)上,操縱生物向終點(diǎn)前進(jìn),就達(dá)到了隨機(jī)游走的效果。目標(biāo)結(jié)束有三種情況:生物已經(jīng)到達(dá)終點(diǎn)、生物無(wú)法到達(dá)終點(diǎn)但走到了離得最近的位置或生物成為了坐騎。由于生物尋路系統(tǒng)會(huì)進(jìn)行路徑的更新,所以即使路徑被破壞,尋路系統(tǒng)也會(huì)找到一個(gè)新的路徑走動(dòng),除非尋路系統(tǒng)找不到任何可行路徑到達(dá)終點(diǎn),這時(shí)尋路系統(tǒng)會(huì)找到一個(gè)離終點(diǎn)最近的路徑,嘗試到達(dá)這個(gè)最近的位置。

生物隨機(jī)游走

隨機(jī)游走的終點(diǎn)雖然是隨機(jī)選取的,但是也有一定的規(guī)律。

生物使用上面的代碼生成一個(gè)隨機(jī)的終點(diǎn)。這段代碼中,radius 是水平搜索半徑,使用切比雪夫距離;vertical 是垂直搜索半徑。通過(guò)這兩個(gè)值可以計(jì)算出生物走的方向 direction。restricted 代表生物是否被限制了行動(dòng),比如被拴繩拴住時(shí)生物就不能自發(fā)離開(kāi)拴繩位置5格遠(yuǎn)。這些參數(shù)再傳入到下面的方法中判斷這個(gè)位置是否是一個(gè)可以使用的位置。

這段代碼先將方向和生物的位置綜合計(jì)算出生物要到達(dá)的位置,然后檢查這個(gè)位置是否滿(mǎn)足條件:

  • 如果位置超出了世界的建筑高度,此位置無(wú)效。

  • 如果生物被限制行動(dòng)并且位置超過(guò)了限制半徑,此位置無(wú)效。

  • 如果位置的下方方塊是不穩(wěn)定的,此位置無(wú)效。穩(wěn)定的定義是:方塊可以遮擋光線(xiàn)并且遮擋包圍盒(Occlusion Shape)是完整的方塊大小。默認(rèn)情況下遮擋包圍盒是和方塊的輪廓箱是一樣的,只有幾個(gè)特殊方塊(滴水石錐、細(xì)雪、柵欄等)和輪廓箱不一樣。舉個(gè)例子,單層臺(tái)階就不是穩(wěn)定方塊,無(wú)論是上半臺(tái)階還是下半臺(tái)階,都屬于不穩(wěn)定方塊,因?yàn)檫@兩種方塊的遮擋包圍盒都不是完整的;而雙層臺(tái)階就是穩(wěn)定方塊,因?yàn)檩喞浜驼趽醢鼑卸际峭暾姆綁K。玻璃也不是穩(wěn)定方塊,因?yàn)樗粫?huì)遮擋光線(xiàn)。

  • 如果位置的下方方塊對(duì)于生物的尋路代價(jià)不為 0,此位置無(wú)效。

生物會(huì)計(jì)算出來(lái) 10 個(gè)位置(無(wú)論有效還是無(wú)效),找出有最大行走目標(biāo)值的有效位置作為隨機(jī)游走的終點(diǎn)。如果所有位置都無(wú)效,那么生物就不會(huì)隨機(jī)游走了。

有些子類(lèi)并不完全使用這種方法計(jì)算終點(diǎn),比如說(shuō) WaterAvoidingRandomStrollGoal 使用了 LandRandomPos.getPos,它與上面算法主要區(qū)別是盡量避免走到水里面,并且將隨機(jī)游走終點(diǎn)垂直向上移動(dòng)到表面上,其他部分大致相同。對(duì)于所有隨機(jī)游走終點(diǎn),上面 4 條對(duì)于終點(diǎn)的限制都是存在的。

利用上面的原理,我們可以完全的阻止生物的隨機(jī)游走。以在地面的僵尸舉例,它的水平搜索半徑是 10,垂直搜索半徑為 7,假如我們搞一個(gè)21x21的區(qū)域放上任意一種不穩(wěn)定方塊,比如上半臺(tái)階或者玻璃,把僵尸放到中央,垂直范圍 7 格內(nèi)沒(méi)有別的方塊,這樣即使這個(gè)平臺(tái)周?chē)荒嗤林?lèi)的方塊包圍,僵尸也不會(huì)嘗試隨機(jī)游走到那里。

僵尸在此處不會(huì)隨機(jī)游走,測(cè)試了 4x72000 刻

同時(shí)根據(jù)這個(gè)原理,我們也可以利用怪物的隨機(jī)游走讓它們走到我們想讓他們走的地方。(當(dāng)然這個(gè)速度是很慢的)

苦力怕隨機(jī)游走只能走到這個(gè)泥土的位置上,相當(dāng)于控制了苦力怕的行動(dòng)

使用這種辦法控制生物行動(dòng)的刷怪塔就是游走刷怪塔。它的生成平臺(tái)使用上半臺(tái)階,引誘平臺(tái)需要使用完整方塊并破壞生成位置,在生成平臺(tái)和引誘平臺(tái)中間加活版門(mén)欺騙尋路讓怪物掉下去。引誘平臺(tái)越大,隨機(jī)游走尋找到有效的終點(diǎn)的概率就越大,進(jìn)行隨機(jī)游走的次數(shù)就會(huì)增加,效率也會(huì)增加。生成平臺(tái)不能無(wú)限擴(kuò)大,由于絕大多數(shù)怪物不在水中時(shí)水平搜索半徑都是 10,所以生成平臺(tái)最遠(yuǎn)處與引誘平臺(tái)不能超過(guò) 8 到 9 格,否則會(huì)堆積怪物。同樣的,這種刷怪塔垂直 7 格半徑之內(nèi)除引誘平臺(tái)不能有任何完整方塊,否則隨機(jī)游走可能會(huì)使用其他的位置作為終點(diǎn)。

2. MeleeAttackGoal 近戰(zhàn)攻擊

許多怪物都有近戰(zhàn)攻擊的目標(biāo),用于攻擊玩家或是其他生物,而實(shí)現(xiàn)近戰(zhàn)攻擊的就是這個(gè)類(lèi)和它的子類(lèi)。

近戰(zhàn)攻擊目標(biāo)每 20 刻檢查一次是否滿(mǎn)足條件。當(dāng)生物沒(méi)有攻擊對(duì)象或攻擊對(duì)象已死亡時(shí),不會(huì)進(jìn)行近戰(zhàn)攻擊。如果生物與攻擊對(duì)象距離小于生物的攻擊距離,或生物找到了一條路徑可以通向攻擊對(duì)象時(shí),近戰(zhàn)攻擊目標(biāo)滿(mǎn)足條件。

這個(gè)目標(biāo)可以持續(xù)運(yùn)作的條件和開(kāi)始條件不一樣。持續(xù)運(yùn)作仍然要求攻擊對(duì)象存在并存活,但是如果攻擊對(duì)象超出了生物的限制活動(dòng)范圍,那么近戰(zhàn)攻擊目標(biāo)就不能繼續(xù)運(yùn)作。絕大多數(shù)生物都要求看到攻擊對(duì)象,如果尋路已經(jīng)停止,那么近戰(zhàn)攻擊也就結(jié)束了。如果攻擊對(duì)象變?yōu)榕杂^(guān)模式或創(chuàng)造模式,近戰(zhàn)攻擊目標(biāo)也會(huì)終止。

近戰(zhàn)攻擊目標(biāo)每刻都會(huì)執(zhí)行一次,檢查攻擊對(duì)象是否存在,并將頭轉(zhuǎn)向攻擊對(duì)象的位置。為防止跟丟攻擊對(duì)象,系統(tǒng)會(huì)嘗試重新計(jì)算路徑終點(diǎn)。重新計(jì)算路徑終點(diǎn)的條件是:

  • 重新計(jì)算路徑倒計(jì)時(shí) ticksUntilNextPathRecalculation 為 0。

  • 如果生物需要看到攻擊對(duì)象,則只能在能看到攻擊對(duì)象的時(shí)候重新計(jì)算終點(diǎn)。

  • 上次計(jì)算的位置和現(xiàn)在攻擊對(duì)象的位置距離大于 1 或有 5% 的概率忽略距離重新計(jì)算。

重計(jì)算路徑倒計(jì)時(shí)與生物和攻擊對(duì)象的距離有關(guān)。倒計(jì)時(shí)基礎(chǔ)時(shí)長(zhǎng)在 4 到 10 刻,如果距離大于 32 格時(shí)長(zhǎng)會(huì)加 10 刻,如果大于 16 加 5 刻,如果重新計(jì)算路徑后發(fā)現(xiàn)無(wú)法到達(dá)攻擊對(duì)象位置會(huì)再加 15 刻時(shí)間。也就是說(shuō),重計(jì)算倒計(jì)時(shí)最少 4 刻,最多 30 刻。

生物攻擊也有冷卻時(shí)間,為 20 刻。如果生物與攻擊對(duì)象的距離小于生物的攻擊距離,且冷卻為 0,生物就可以近戰(zhàn)攻擊。

3. NearestAttackableTargetGoal 選擇最近可攻擊對(duì)象

這個(gè)目標(biāo)是用來(lái)選擇攻擊對(duì)象的,許多怪物都使用這個(gè)類(lèi)檢查周?chē)纳铩?/p>

它有 5 個(gè)參數(shù):攻擊對(duì)象的類(lèi)型、平均檢查時(shí)間、是否必須看到、是否必須達(dá)到和一個(gè)檢查實(shí)體的謂詞。攻擊對(duì)象的類(lèi)型可以為玩家也可以為其他實(shí)體,平均檢查時(shí)間用于判斷是否進(jìn)行檢查。

攻擊對(duì)象檢查的間隔不是固定的,平均值是 randomInterval。如果找不到一個(gè)滿(mǎn)足條件的實(shí)體,那么這個(gè)目標(biāo)條件不滿(mǎn)足不會(huì)執(zhí)行。

尋找攻擊對(duì)象的范圍由生物的跟隨距離決定,跟隨距離越大,查找范圍也就越大。對(duì)于非玩家實(shí)體,查找范圍為生物碰撞箱水平擴(kuò)展跟隨距離,上下擴(kuò)展 4 格。也就是說(shuō),如果非玩家實(shí)體在生物頭上四格以上,生物就無(wú)法將這個(gè)實(shí)體認(rèn)定為攻擊對(duì)象。而玩家的查找范圍是跟隨距離為半徑的球,垂直方向上超出跟隨距離才能避免被生物探測(cè)到。

本專(zhuān)欄使用的源代碼為 1.19.3 Mojang Mapping。

反編譯器 CFR 0.152,反混淆器 Nickid2018/GitMCDecomp。

有錯(cuò)誤可以在評(píng)論區(qū)指出。

Minecraft 生物 AI 機(jī)制詳解(一)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
封丘县| 阿克陶县| 松潘县| 丰城市| 黑龙江省| 栾城县| 恩施市| 申扎县| 雷波县| 保靖县| 勃利县| 莎车县| 沐川县| 芜湖市| 吴忠市| 凤凰县| 罗甸县| 商河县| 北安市| 淮北市| 海原县| 远安县| 南涧| 云安县| 满洲里市| 新邵县| 皮山县| 嘉兴市| 万源市| 兴隆县| 德州市| 延川县| 富裕县| 商水县| 尖扎县| 兰西县| 彝良县| 科尔| 杭锦旗| 福州市| 潢川县|