[Unity3D]AI 視野

前言

但凡是涉及到怪物AI邏輯這一部分,無(wú)非是 索敵—>尋路—>戰(zhàn)斗嘛,這次是說(shuō)索敵這一塊

簡(jiǎn)單粗暴點(diǎn)的話,當(dāng)玩家離怪物一定的距離就令怪物走向玩家就好了,但這顯得有點(diǎn)蠢

我們希望怪物有一個(gè)先發(fā)現(xiàn)玩家、再進(jìn)行后續(xù)動(dòng)作的過(guò)程,這樣顯得更真實(shí),也可以為其他一些功能做準(zhǔn)備(比如我們的玩家可以偷偷繞到怪物背后,給他一錘子)

為了更真實(shí)地去做到“怪物發(fā)現(xiàn)入侵者”這一功能,我們可以換位思考一下,我們是如何發(fā)現(xiàn)怪物的?——怪物進(jìn)入了我們攝像機(jī)的視錐體,嗯,所以怪物也該有一個(gè)視野范圍,當(dāng)我們進(jìn)入它的視野范圍時(shí),它才會(huì)“看見(jiàn)”我們

所以我采用了以下思路:

一、用扇形區(qū)域模擬怪物的視野范圍

首先,設(shè)定最大可視距離maxVisionDistance和最大視野角度maxVisionAngle

當(dāng)玩家與怪物的 距離<maxVisionDistance, 角度<maxVisionAngle,那么玩家進(jìn)入怪物的視野范圍

 public float maxVisionDistance;//視野長(zhǎng)度
 public float maxVisionAngle;//視野角度
 bool isInMyVision(Collider c)
    {
        GameObject target = c.gameObject;
        //計(jì)算與目標(biāo)距離
        float distance = Vector3.Distance(transform.position, target.transform.position);
        
        Vector3 mVec = transform.rotation * Vector3.forward ;//當(dāng)前朝向
        Vector3 tVec = target.transform.position - transform.position;//與目標(biāo)連線的向量

        //計(jì)算兩個(gè)向量間的夾角
        float angle = Mathf.Acos(Vector3.Dot(mVec.normalized, tVec.normalized)) * Mathf.Rad2Deg;
        if (distance < maxVisionDistance)
        {
            if (angle <= maxVisionAngle)
            {
                if(canSee(c))
                  return true;
            }
        }
        return false;
    }

二、排除遮擋

如果我們的玩家想要不驚動(dòng)怪物,暗中觀察,或許會(huì)躲在一塊石頭后面。

直接用上述判斷距離和角度的方法顯然是不行的,我們需要追加一個(gè)判斷是否有障礙物遮擋視野,這里我想的辦法是用射線來(lái)解決。

從當(dāng)前點(diǎn)向目標(biāo)位置發(fā)射一條射線Ray,如果碰撞到的第一個(gè)物體是目標(biāo)物體,就判定沒(méi)有遮擋,這樣的話,最好將這個(gè)腳本綁定到怪物的“眼睛”這個(gè)地方,讓它有一定的高度。

我這里只是大致判斷了一下,當(dāng)然可以有更精確的判斷方式,請(qǐng)各位發(fā)揮想象力

bool canSee(Collider c)
{
  Ray DetectRay = new Ray(transform.position,temVec.normalized*maxVisionDistance);
  RaycastHit hitInfo;
  if (Physics.Raycast(DetectRay, out hitInfo, maxVisionDistance))
  {
    if (hitInfo.collider == c)
    {
         return true;
    }
  }
}

三、擴(kuò)展思考

在多人游戲中,可能有多個(gè)玩家,這個(gè)時(shí)候,只設(shè)定一個(gè) target是不夠的

我們可以先將視野中的可能目標(biāo)先找出來(lái),再進(jìn)行排除和選擇,用一個(gè)簡(jiǎn)單的球形掃描Physics.OverlapSphere就可以找出所有目標(biāo)了,可以設(shè)定個(gè)tag或者layer來(lái)進(jìn)行選擇

    void FindTarget()
    {
        Collider[] AllObejects = Physics.OverlapSphere(transform.position, maxVisionDistance);
        foreach( Collider c in AllObejects)
        {
            //僅對(duì)Player進(jìn)行檢測(cè)
            if (c.gameObject.tag == "Player")
            {
                if (isInMyVision(c))
                {
                    print("I see a target");
                    //在這里執(zhí)行你想要進(jìn)行的操作,比如設(shè)定尋路目標(biāo)之類的
                }
            }
        }
    }

如有建議或指正,歡迎交流。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • ----------------------- 頁(yè)面 1----------------------- 2013 ...
    長(zhǎng)春傳齊3閱讀 5,446評(píng)論 0 1
  • 我他媽又醉了! 這是昨天的事情,一直以來(lái),都不能與手機(jī)親密相處,不能在視頻里看到朝陽(yáng),缺失的不僅僅是自由與宅,還有...
  • 小區(qū)門口有一個(gè)賣熟食的店鋪,在我們這地界上,他們這個(gè)店鋪屬于連鎖?加盟?反正是小有名氣。 店鋪還折騰的不小,在小區(qū)...
    煩人的昵稱閱讀 330評(píng)論 0 0
  • 我知道你沒(méi)那么文藝,起碼沒(méi)我文藝 因?yàn)槟悴粫?huì)用文字表達(dá)想念 也不會(huì)一個(gè)人冒著冷風(fēng)看海 你只會(huì)說(shuō) 怎么才幾天沒(méi)見(jiàn),就...
    果舍先生閱讀 394評(píng)論 4 7
  • 我想回到小時(shí)候,迫切的
    樹(shù)年閱讀 224評(píng)論 0 0

友情鏈接更多精彩內(nèi)容