Unity自学之旅05

news2025/1/24 20:54:28

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脚本

   // 巡逻点的transform
   public 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-1
      if (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.coloradmin.cn/o/2281621.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【分布式日志篇】从工具选型到实战部署:全面解析日志采集与管理路径

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

电子应用设计方案102:智能家庭AI鱼缸系统设计

智能家庭 AI 鱼缸系统设计 一、引言 智能家庭 AI 鱼缸系统旨在为鱼类提供一个健康、舒适的生活环境&#xff0c;同时为用户提供便捷的管理和观赏体验。 二、系统概述 1. 系统目标 - 自动维持水质稳定&#xff0c;包括水温、酸碱度、硬度和溶氧量等关键指标。 - 智能投食&…

【安当产品应用案例100集】034-安当KSP支持密评中存储数据的机密性和完整性

安当KSP是一套获得国密证书的专业的密钥管理系统。KSP的系统功能扩展图示如下&#xff1a; 我们知道商用密码应用安全性评估中&#xff0c;需要确保存储的数据不被篡改、删除或者破坏&#xff0c;必须采用合适的安全方案来确保存储数据的机密性和完整性。KSP能否满足这个需求呢…

linux系统下的磁盘扩容

背景&#xff1a;之前通过虚拟机装linux时硬盘空间设置的不够用&#xff0c;所以需要再加点容量。 1、首先通过虚拟机来扩展硬盘 注意&#xff1a;需要关闭linux系统&#xff1b;需要删除之前的快照&#xff1b; 我原来为27G&#xff0c;现在增加到了40G&#xff0c;如下图: …

【MySQL】 库的操作

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;【MySQL】 库的操作 发布时间&#xff1a;2025.1.23 隶属专栏&#xff1a;MySQL 目录 库的创建语法使用 编码规则认识编码集查看数据库默认的编码集和校验集查看数据库支持的编码集和校验集指定编码创建数据库验证不…

fpga学习入门 串口rs232回环

奇偶检验位这里是省略了 做好回环后可以使用上位机做回环测试&#xff0c;top文件写的方式就是将rx&#xff08;fpga端&#xff09;接受到的模块&#xff08;pc端&#xff09;tx发送出去&#xff0c;这两个端口用杜邦线连接&#xff0c;同理模块的rx连接fpga的tx&#xff0c;…

认识Django项目模版文件——Django学习日志(二)

1.默认文件介绍 └── djangoproject1/├── djangoproject1/│ ├── urls.py [URL和函数的对应关系]【常用文件】│ ├── settings.py [项目配置文件]【常用文件】│ ├── _init_.py│ ├── wsgi.py [接受网络请求] 【不要动】│ └──…

微信小程序中常见的 跳转方式 及其特点的表格总结(wx.navigateTo 适合需要返回上一页的场景)

文章目录 详细说明总结wx.navigateTo 的特点为什么 wx.navigateTo 最常用&#xff1f;其他跳转方式的使用频率总结 以下是微信小程序中常见的跳转方式及其特点的表格总结&#xff1a; 跳转方式API 方法特点适用场景wx.navigateTowx.navigateTo({ url: 路径 })保留当前页面&…

postgresql15的启动

PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统&#xff0c;且因为许可证的灵活&#xff0c;任何人都可以以任何目的免费使用、修改和分发PostgreSQL。现在国产数据库大力发展阶段&#xff0c;学习和熟悉postgresql的功能是非常有必要的&#x…

ChatGPT结合Excel辅助学术数据分析详细步骤分享!

目录 一.Excel在学术论文中的作用✔ 二.Excel的提示词✔ 三. 编写 Excel 命令 四. 编写宏 五. 执行复杂的任务 六. 将 ChatGPT 变成有用的 Excel 助手 一.Excel在学术论文中的作用✔ Excel作为一种广泛使用的电子表格软件&#xff0c;在学术论文中可以发挥多种重要作用&a…

大模型 / 智能体在智能运维领域的应用总结与发展趋势概述

智能体 智能运维 &#xff1f; 回顾大模型的发展 大模型的发展在过去两年间呈现出爆炸式的增长&#xff0c;成为推动人工智能领域快速进步的关键力量。 2023年3月&#xff1a;百度发布了其知识增强的大语言模型产品“文心一言”&#xff0c;这标志着国内AI大模型产业竞争的…

戴尔电脑设置u盘启动_戴尔电脑设置u盘启动多种方法

最近有很多网友问&#xff0c;戴尔台式机怎么设置u盘启动&#xff0c;特别是近两年的戴尔台式机比较复杂&#xff0c;有些网友不知道怎么设置&#xff0c;其实设置u盘启动有两种方法&#xff0c;下面小编教大家戴尔电脑设置u盘启动方法。 戴尔电脑设置u盘启动方法一、戴尔进入b…

【博客之星】年度总结:在云影与墨香中探寻成长的足迹

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、年度回顾 1、创作历程 2、个人成长 3、个人生活与博客事业 二、技术总结 1、赛道选择 2、技术工具 3、实战项目 三、前景与展望 1、云原生未来…

《安富莱嵌入式周报》第349期:VSCode正式支持Matlab调试,DIY录音室级麦克风,开源流体吊坠,物联网在军工领域的应用,Unicode字符压缩解压

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; 《安富莱嵌入式周报》第349期&#xff1a;VSCode正式支持Matlab调试&#xff0c;DIY录音室级麦克风…

cursor ide配置远程ssh qt c++开发环境过程记录

cursor是啥就不介绍了&#xff0c;好像是目前最好用的ai ide&#xff0c;下面主要是配置远程ssh连接linux机器进行qt5 c程序运行的配置过程记录。 一、c_cpp_properties.json 在项目根目录的.vscode目录里面新建c_cpp_properties.json文件&#xff0c;根据你的实际情况配置该文…

Langchain+文心一言调用

import osfrom langchain_community.llms import QianfanLLMEndpointos.environ["QIANFAN_AK"] "" os.environ["QIANFAN_SK"] ""llm_wenxin QianfanLLMEndpoint()res llm_wenxin.invoke("中国国庆日是哪一天?") print(…

lwIP——3 内存管理

目录 1.什么是内存管理 2.lwIP内存堆 3.lwIP内存堆程序代码解析 3.1 mem_init程序解析 3.2 mem_malloc程序解析 3.3 mem_free程序解析 4.lwIP内存池 5.lwIP内存池程序代码解析 5.1 实现lwIP内存池的文件 5.1.1 memp_priv.h 5.1.2 memp_std.h 5.1.3 memp.h memp_t 枚…

使用 Serilog 在 .NET Core 6.0 中日志记录

在本文中&#xff0c;我们将讨论日志记录的基础知识以及在 .NET Core 6 中使用 Serilog 的逐步实现。 先决条件 1、Visual Studio 2022。 2、C# 和 .NET Core 的基础知识。 3、.NET Core 6 SDK。 日志记录基础知识 从技术角度来说&#xff0c;日志记录是记录事件并捕获应用程…

当 Facebook 窥探隐私:用户的数字权利如何捍卫?

随着社交平台的普及&#xff0c;Facebook 已经成为全球用户日常生活的一部分。然而&#xff0c;伴随而来的隐私问题也愈发严峻。近年来&#xff0c;Facebook 频频被曝出泄露用户数据、滥用个人信息等事件&#xff0c;令公众对其隐私保护措施产生质疑。在这个信息化时代&#xf…

微信小程序隐藏右侧胶囊按钮,分享和关闭即右侧三个点和小圆圈按钮

在微信小程序开发过程中&#xff0c;可能需要将右侧的胶囊按钮、即右侧的三个点和小圆圈按钮关闭掉。如图&#xff1a; 这时&#xff0c;我们只需在该页面的json文件中进行相关配置即可 {"navigationBarTitleText": "商品详情页","navigationStyle&q…