Unity自學之旅05

Unity自學之旅05

  • Unity學習之旅⑤
  • 📝 AI基礎與敵人行為
    • 🥊 AI導航
      • 理論知識(基礎)
      • 開始實踐
    • 🎃 敵人游戲機制
      • 追蹤玩家
      • 攻擊玩家
      • 子彈碰撞
      • 完善游戲失敗條件
  • 🤗 總結歸納

Unity學習之旅⑤

📝 AI基礎與敵人行為

🥊 AI導航

理論知識(基礎)

一、導航系統的基本組件

  1. NavMesh(導航網格)
    • NavMesh 是 Unity 中 AI 導航的基礎,它是一個表示可行走區域的網格。它將場景中的可行走表面(如地面、樓梯等)進行三角剖分,形成一個平面的網格,用于代理(Agent)導航。
    • 生成 NavMesh 的步驟:
      • 首先,需要將場景中的幾何體標記為靜態(Static),以便 Unity 可以將它們納入 NavMesh 的計算。
      • 然后,打開 Navigation 窗口(Window -> AI -> Navigation),在 Bake 選項卡中調整設置,例如 Agent Radius(代理半徑)、Agent Height(代理高度)等,這些設置決定了代理在場景中占用的空間大小和形狀。
      • 點擊 Bake 按鈕,Unity 會生成 NavMesh,顯示為場景中的藍色網格。
  2. NavMeshAgent(導航網格代理)
    • 這是附加在游戲對象上的組件,用于讓對象在 NavMesh 上移動。
    • 主要屬性:
      • Speed:代理的移動速度。
      • Acceleration:代理的加速度。
      • Stopping Distance:距離目標多遠時停止移動。
      • Radius:代理的半徑,用于避障和計算可行走區域。
      • Height:代理的高度,決定了代理可以通過的最小空間高度。
  3. NavMeshObstacle(導航網格障礙物)
    • 該組件用于表示場景中的動態障礙物。當一個對象附加了 NavMeshObstacle 時,它會影響 NavMeshAgent 的導航路徑。
    • 可以設置為 Carve 模式,這會在 NavMesh 上動態地修改 NavMesh,使代理能夠繞開障礙物。

二、導航行為和邏輯

  1. 路徑規劃
    • NavMeshAgent 會自動根據 NavMesh 為代理規劃從當前位置到目標位置的最短路徑。它會考慮障礙物和可行走區域。
    • 可以使用 agent.remainingDistance 來檢查代理離目標的剩余距離,使用 agent.pathStatus 來查看路徑的狀態,如是否完成、正在計算或被阻塞。
  2. 避障
    • Unity 的導航系統會自動處理代理之間和代理與障礙物之間的避障。通過設置 NavMeshAgent 的屬性,如 RadiusAvoidance Priority,可以調整避障行為。
    • 代理之間會根據彼此的 Avoidance Priority 進行避障,較低優先級的代理會主動避讓較高優先級的代理。
  3. 動態導航
    • 當場景中的障礙物或目標位置發生變化時,NavMeshAgent 會自動重新計算路徑。
    • 例如,如果要在游戲運行時改變目標位置,可以調用 agent.SetDestination(newDestination); ,其中 newDestination 是一個 Vector3 類型的新位置。

開始實踐

window→package manager 選擇 Unity Registry 然后搜索 AI Navigation

在這里插入圖片描述

window→ai→navigation(obsolete) ,這里是因為我所使用的Unity版本那個AI Navigation static 已經棄用了,我更改了一種使用方式。

在這里插入圖片描述

選擇Environment,然后為點擊Inspector中的Static,接著將Environment的對象及其子對象都設置為Navigation Static.

在這里插入圖片描述

點擊Bake→bake

在這里插入圖片描述

為Enemy添加NavMeshAgent,讓敵人可以在NavMesh上面行走。

在這里插入圖片描述

繪制幾個路徑點,用于敵人的自動巡邏。

在這里插入圖片描述

在這里插入圖片描述

引用巡邏點,編輯EnemyBehavior腳本

   // 巡邏點的transformpublic Transform PatrolRoute;// 四個巡邏點的transform集合public List<Transform> Locations;void Start(){// 腳本運行時,初始化巡邏路徑InitializePatrolRoute();}void InitializePatrolRoute(){foreach (Transform t in PatrolRoute){Locations.Add(t);}}

在這里插入圖片描述

讓Enemy跟著巡邏點動起來,在此編輯腳本

// ... 
// 默認第一個索引為0,即先走第一個巡邏點
private int _locationIndex = 0;// NavMeshAgent的引用
private NavMeshAgent _agent;void Start()
{// 獲取Enemy對象上的NavMeshAgent組件的引用_agent = GetComponent<NavMeshAgent>();  // 腳本運行時,初始化巡邏路徑InitializePatrolRoute(); MoveToNextPatrolLocation();
}// 移動到下一個巡邏點
void MoveToNextPatrolLocation()
{_agent.destination = Locations[_locationIndex].position;
}
//....

在這里插入圖片描述

現在只會移動到第一個巡邏點,然后我們的目的是,在每個巡邏點,循環往復的進行移動,這個時候就需要在Update()中搞點事情了。

void Update()
{// 檢測當前對象與目標位置距離if(_agent.remainingDistance < 0.2f && !_agent.pathPending){MoveToNextPatrolLocation();}    
}// 移動到下一個巡邏點void MoveToNextPatrolLocation(){if(Locations.Count == 0) return;_agent.destination = Locations[_locationIndex].position;// 索引循環往復_locationIndex = (_locationIndex + 1) % Locations.Count;    }

在這里插入圖片描述

🎃 敵人游戲機制

敵人按照巡邏路線進行巡邏,當與玩家碰撞后,減少玩家生命值,然后敵人回到初始位置,玩家也可以攻擊敵人,減少其生命值。

追蹤玩家

當玩家進入敵人警戒范圍時,敵人會直接奔向玩家。

 // 玩家的Transform引用public Transform Player;void Start(){// ...// 獲取Player對象的引用Player = GameObject.Find("Player").transform;}// ...// 碰撞觸發器void OnTriggerEnter(Collider other){if(other.name == "Player"){// 玩家進入到警戒范圍后,敵人奔向玩家_agent.destination = Player.position;Debug.Log("玩家進入警戒范圍");}    }

攻擊玩家

攻擊玩家的邏輯很簡單,當玩家與敵人發生碰撞時,玩家減少生命值,并且在GUI上顯示

修改玩家的Playerbehavior腳本(敵人腳本也可以,因為碰撞是相互的)

// gameManager的引用,因為HP,收集道具數量都在該處存放
private GameBehavior _gameManager;void Start(){// 將當前player的剛體組件獲取并設置_rb = GetComponent<Rigidbody>();// 獲取當前角色的膠囊碰撞體_col = GetComponent<CapsuleCollider>();_gameManager = GameObject.Find("Game_Manager").GetComponent<GameBehavior>();}// 發生碰撞時void OnCollisionEnter(Collision collision){// 如果與敵人碰撞則HP-1if (collision.gameObject.name == "Enemy"){_gameManager.HP -= 1;}}

在這里插入圖片描述

這里的話需要注意一個問題,就是敵人身上的碰撞體為碰撞觸發器,勾選了Is Trigger,然后直接通過Player的OnCollisionEnter()并不會觸發,需要給敵人再加入一個碰撞體就可以了。

在這里插入圖片描述

子彈碰撞

為Player添加反擊手段,邏輯就是敵人有三滴血,當子彈射擊三次并且擊中敵人后,敵人自動銷毀。

編輯敵人Enemy的游戲腳本

// 敵人的HP=3
private int _lives = 3;
public int EnemyLives
{get { return _lives; }set{_lives = value;if (_lives <= 0){Destroy(this.gameObject);Debug.Log("敵人死亡");}}
}void OnCollisionEnter(Collision collision)
{// 當子彈碰撞到敵人時if(collision.gameObject.name == "Bullet(Clone)"){EnemyLives -= 1;Debug.Log("遭受子彈射擊");}
}

在這里插入圖片描述

完善游戲失敗條件

邏輯是,生命值為0時,游戲暫停,出現一個按鈕說:你輸了。

先繪制一個Button按鈕,和之前的一樣,默認禁用即可,當生命值為0時,在腳本內調用。

在這里插入圖片描述

編輯GameManager的腳本

public Button LossButton;
private int _playerHp = 10;
public int HP
{get { return _playerHp; }set{//...if (_playerHp <= 0){ProgressText.text = "You want another life with that?";LossButton.gameObject.SetActive(true);Time.timeScale = 0f;}else{ProgressText.text = "Ouch... that's got hurt.";}Debug.LogFormat("HP:{0}", _playerHp);}
}

在這里插入圖片描述

🤗 總結歸納

本文主要介紹了在 Unity 中實現 AI 導航以及構建敵人游戲機制的方法。包括導航系統的基本組件、導航行為和邏輯,以及敵人的巡邏、追蹤玩家、攻擊玩家、被子彈擊中和完善游戲失敗條件等功能。

重要亮點

  • 導航系統基本組件:Unity 中 AI 導航的基礎是 NavMesh,它將場景中的可行走表面進行三角剖分形成網格。NavMeshAgent 是附加在游戲對象上用于在 NavMesh 上移動的組件,NavMeshObstacle 用于表示動態障礙物。
  • 導航行為和邏輯:NavMeshAgent 能自動規劃從當前位置到目標位置的最短路徑,處理避障和動態導航。例如,當場景中的障礙物或目標位置變化時,會自動重新計算路徑。
  • 敵人巡邏機制:通過為敵人添加 NavMeshAgent,設置巡邏點,編寫腳本實現敵人在巡邏點之間循環往復移動。
  • 追蹤玩家:當玩家進入敵人警戒范圍時,敵人會奔向玩家。通過在敵人腳本中檢測玩家進入碰撞觸發器,設置敵人的目標位置為玩家位置。
  • 攻擊玩家:當玩家與敵人發生碰撞時,玩家減少生命值。在玩家腳本和敵人腳本中分別處理碰撞事件。
  • 完善游戲失敗條件:當玩家生命值為 0 時,游戲暫停,出現 “你輸了” 按鈕。在游戲管理器腳本中根據玩家生命值控制按鈕的顯示和游戲時間的暫停。

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

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

相關文章

我想通過python語言,學習數據結構和算法該如何入手?

學習數據結構和算法是編程中的重要基礎&#xff0c;Python 是一個非常適合入門的語言。以下是學習數據結構和算法的步驟和建議&#xff1a; 1. 掌握 Python 基礎 確保你對 Python 的基本語法、數據類型、控制結構&#xff08;如循環、條件語句&#xff09;、函數等有扎實的理…

淺談Unity中Canvas的三種渲染模式

Overview UGUI通過 Canvas 組件渲染和管理UI元素。Canvas 是 UI 元素的容器&#xff0c;它決定了 UI 元素的渲染方式以及它們在屏幕上的顯示效果。Canvas 有三種主要的渲染模式&#xff0c;每種模式有不同的用途和特點。本文將介紹這三種渲染模式 1. Screen Space - Overlay 模…

Unity中在UI上畫線

在UI中畫一條曲線 我封裝了一個組件,可以實現基本的畫線需求. 效果 按住鼠標左鍵隨手一畫. 用起來也很簡單,將組件掛到空物體上就行了,紅色的背景是Panel. 你可以將該組件理解為一個Image,只不過形狀更靈活一些罷了,所以它要放在下面的層級(不然可能會被擋住). 代碼 可以…

2024.1.22 安全周報

政策/標準/指南最新動態 01 工信部印發《關于加強互聯網數據中心客戶數據安全保護的通知》 原文: https://www.secrss.com/articles/74673 互聯網數據中心作為新一代信息基礎設施&#xff0c;承載著千行百業的海量客戶數據&#xff0c;是關系國民經濟命脈的重要戰略資源。…

探索 LLM:從基礎原理到 RAG 實現的深度解析

一.LLM基礎知識 1.1 大語言模型&#xff08;Large Language Model&#xff0c;LLM&#xff09; 他是模型&#xff0c;是 AI 能力的核心。他是語言模型&#xff0c;其核心能力在于語言能力。他是大語言模型&#xff0c;與傳統模型相比&#xff0c;它最大的特點就是“大”。 1…

Mac cursor設置jdk、Maven版本

基本配置 – Cursor 使用文檔 首先是系統用戶級別的設置參數&#xff0c;運行cursor&#xff0c;按下ctrlshiftp&#xff0c;輸入Open User Settings(JSON)&#xff0c;在彈出的下拉菜單中選中下面這樣的&#xff1a; 在打開的json編輯器中追加下面的內容&#xff1a; {"…

ARM64平臺Flutter環境搭建

ARM64平臺Flutter環境搭建 Flutter簡介問題背景搭建步驟1. 安裝ARM64 Android Studio2. 安裝Oracle的JDK3. 安裝 Dart和 Flutter 開發插件4. 安裝 Android SDK5. 安裝 Flutter SDK6. 同意 Android 條款7. 運行 Flutter 示例項目8. 修正 aapt2 報錯9. 修正 CMake 報錯10. 修正 N…

selenium clear()方法清除文本框內容

在使用Selenium進行Web自動化測試時&#xff0c;清除文本框內容是一個常見的需求。這可以通過多種方式實現&#xff0c;取決于你使用的是哪種編程語言&#xff08;如Python、Java等&#xff09;以及你的具體需求。以下是一些常見的方法&#xff1a; 1. 使用clear()方法 clear…

基于海思soc的智能產品開發(視頻的后續開發)

【 聲明&#xff1a;版權所有&#xff0c;歡迎轉載&#xff0c;請勿用于商業用途。 聯系信箱&#xff1a;feixiaoxing 163.com】 前面我們討論了camera&#xff0c;也討論了屏幕驅動&#xff0c;這些都是基礎的部分。關鍵是&#xff0c;我們拿到了這些視頻數據之后&#xff0c;…

vue3+webOffice合集

1、webOffice 初始化 1&#xff09;officeType: 文檔位置&#xff1a;https://solution.wps.cn/docs/web/quick-start.html#officetype 2&#xff09;appId: 前端使用appId 后端需要用到AppSecret 3&#xff09;fileId: 由后端返回&#xff0c;前端無法生成&#xff0c;與上傳文…

2025牛客寒假算法營2

A題 知識點&#xff1a;模擬 打卡。檢查給定的七個整數是否僅包含 1,2,3,5,6 即可。為了便于書寫&#xff0c;我們可以反過來&#xff0c;檢查這七個整數是否不為 4 和 7。 時間 O(1)&#xff1b;空間 O(1)。 #include <bits/stdc.h> using namespace std;signed main()…

記錄一次k8s起不來的排查過程

我在k8s集群&#xff0c;重啟了一個node宿主機&#xff0c;竟然發現kubelet起不來了&#xff01;報錯如下 這個報錯很模糊&#xff0c;怎么排查呢。這樣&#xff0c;開兩個界面&#xff0c;一個重啟kubelet&#xff0c;一個看系統日志(/var/log/message:centos&#xff0c;/va…

Docker Desktop 在Windows 環境中開發、測試和運行容器化的應用程序

Docker 為 Windows 提供了專門的桌面版工具&#xff0c;稱為 Docker Desktop&#xff0c;它允許你在 Windows 環境中開發、測試和運行容器化的應用程序。 如何在 Windows 上使用 Docker Docker Desktop Docker Desktop 是一個專為 Windows 設計的應用程序&#xff0c;它簡化了…

仿 RabbitMQ 的消息隊列3(實戰項目)

七. 消息存儲設計 上一篇博客已經將消息統計文件的讀寫代碼實現了&#xff0c;下一步我們將實現創建隊列文件和目錄。 實現創建隊列文件和目錄 初始化 0\t0 這樣的初始值. //創建隊列對應的文件和目錄&#xff1a;public void createQueueFile(String queueName) throws IO…

HTTP 配置與應用(局域網)

想做一個自己學習的有關的csdn賬號&#xff0c;努力奮斗......會更新我計算機網絡實驗課程的所有內容&#xff0c;還有其他的學習知識^_^&#xff0c;為自己鞏固一下所學知識&#xff0c;下次更新HTTP 配置與應用&#xff08;不同網段&#xff09;。 我是一個萌新小白&#xf…

root用戶Linux銀河麒麟服務器安裝vnc服務

安裝必要桌面環境組件 yum install mate-session-manager -y mate-session #確定是否安裝成功安裝vnc服務器 yum install tigervnc-server -y切換到root為root得vnc設置密碼 su root vncpasswd給root用戶設置vnc服務器文件 vi /etc/systemd/system/vncserver:1.service [Un…

理解深度學習pytorch框架中的線性層

文章目錄 1. 數學角度&#xff1a; y W x b \displaystyle y W\,x b yWxb示例 2. 編程實現角度&#xff1a; y x W T b \displaystyle y x\,W^T b yxWTb3. 常見錯誤與易混點解析4. 小結參考鏈接 在神經網絡或機器學習的線性層&#xff08;Linear Layer / Fully Connect…

C#Object類型的索引,序列化和反序列化

前言 最近在編寫一篇關于標準Mes接口框架的文章。其中有一個非常需要考究的內容時如果實現數據靈活和可使用性強。因為考慮數據靈活性&#xff0c;所以我一開始選取了Object類型作為數據類型&#xff0c;Object作為數據Value字段&#xff0c;String作為數據Key字段&#xff0c…

大模型應用與部署 技術方案

大模型應用與部署 技術方案 一、引言 人工智能蓬勃發展,Qwen 大模型在自然語言處理領域地位關鍵,其架構優勢盡顯,能處理文本創作等多類復雜任務,提供優質交互。Milvus 向量數據庫則是向量數據存儲檢索利器,有高效索引算法(如 IVF_FLAT、HNSWLIB 等)助力大規模數據集相似…

【Prometheus】Prometheus如何監控Haproxy

?? 歡迎大家來到景天科技苑?? &#x1f388;&#x1f388; 養成好習慣&#xff0c;先贊后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者簡介&#xff1a;景天科技苑 &#x1f3c6;《頭銜》&#xff1a;大廠架構師&#xff0c;華為云開發者社區專家博主&#xff0c;…