您现在的位置是:首页 > 经典句子

【制作100个unity游戏之24】unity制作一个3D动物AI生态系统游戏1(附项目源码)

作者:往北时间:2024-04-24 08:50:32分类:经典句子

简介  文章浏览阅读969次,点赞21次,收藏25次。欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第24篇中,我们将探索如何用unity制作一个3D动物AI生态系统游戏,我会附带项目源码,以便你们更好理

点击全文阅读

最终效果

在这里插入图片描述

文章目录

最终效果系列目录前言导入AI导航系统导航烘培添加羊源码完结

系列目录

【制作100个unity游戏之24】unity制作一个3D动物AI生态系统游戏1(附项目源码)
【制作100个unity游戏之24】unity制作一个3D动物AI生态系统游戏2(附项目源码)
【制作100个unity游戏之24】unity制作一个3D动物AI生态系统游戏3(附项目源码)

前言

欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第24篇中,我们将探索如何用unity制作一个3D动物AI生态系统游戏,我会附带项目源码,以便你们更好理解它。

导入AI导航系统

导航系统基础介绍可以看我之前的文章:【Unity游戏开发教程】零基础带你从小白到超神29——导航系统

如果你用的是unity2022及以上,可能需要先导入AI导航组件
在这里插入图片描述

导航烘培

配置地形为静态可行走导航
在这里插入图片描述
点击烘培
在这里插入图片描述
如果要添加动态障碍物,可以使给物体添加动态导航(NavMeshObstacle组件)
在这里插入图片描述

添加羊

代码简单控制羊的随机行为

// 定义动物状态的枚举类型public enum AnimalState{    Idle,   // 空闲状态    Moving  // 移动状态}// 必须附加到具有 NavMeshAgent 组件的游戏对象上[RequireComponent(typeof(NavMeshAgent))]public class Animal : MonoBehaviour{    [Header("Wander")]    public float wanderDistance = 50f;   // 动物一次移动的距离    public float walkSpeed = 5f;         // 动物的行走速度    public float maxWalkTime = 6f;       // 动物行走的最大时间    [Header("Idle")]    public float idleTime = 5f;          // 动物休息的时间    protected NavMeshAgent navMeshAgent;  // 存储 NavMeshAgent 组件的引用    protected AnimalState currentState = AnimalState.Idle;  // 存储当前动物的状态,默认为 Idle    private void Start()    {        InitialiseAnimal();  // 初始化动物    }    // 初始化动物    protected virtual void InitialiseAnimal()    {        navMeshAgent = GetComponent<NavMeshAgent>();  // 获取 NavMeshAgent 组件的引用        navMeshAgent.speed = walkSpeed;  // 设置动物的行走速度        currentState = AnimalState.Idle;  // 将当前状态设置为 Idle        UpdateState();  // 更新动物的状态    }    // 更新动物的状态    protected virtual void UpdateState()    {        switch (currentState)        {            case AnimalState.Idle:  // 如果当前状态是 Idle                HandleIdleState();  // 处理空闲状态                break;            case AnimalState.Moving:  // 如果当前状态是 Moving                HandleMovingState();  // 处理移动状态                break;        }    }    // 获取距离起点一定距离内的随机 NavMesh 位置    protected Vector3 GetRandomNavMeshPosition(Vector3 origin, float distance)    {        Vector3 randomDirection = Random.insideUnitSphere * distance;  // 在球形区域内生成一个随机方向        randomDirection += origin;  // 将随机方向与起点相加,计算出随机点的位置        NavMeshHit navMeshHit;        if (NavMesh.SamplePosition(randomDirection, out navMeshHit, distance, NavMesh.AllAreas))        {            // 如果找到了 NavMesh 上的可行走位置,返回该位置            return navMeshHit.position;        }        else        {            // 否则递归调用函数,继续查找新的随机位置            return GetRandomNavMeshPosition(origin, distance);        }    }    // 处理空闲状态    protected virtual void HandleIdleState()    {        StartCoroutine(WaitToMove());  // 等待一段时间后转换到移动状态    }    // 等待一段时间后转换到移动状态    private IEnumerator WaitToMove()    {        float waitTime = Random.Range(idleTime / 2, idleTime * 2);  // 随机生成等待时间        yield return new WaitForSeconds(waitTime);  // 等待一段时间        Vector3 randomDestination = GetRandomNavMeshPosition(transform.position, wanderDistance);  // 获取随机位置        navMeshAgent.SetDestination(randomDestination);  // 设置 NavMeshAgent 的目标位置        SetState(AnimalState.Moving);  // 将状态设置为 Moving    }    // 处理移动状态    protected virtual void HandleMovingState()    {        StartCoroutine(WaitToReachDestination());  // 等待到达目的地后转换到空闲状态    }    // 等待到达目的地后转换到空闲状态    private IEnumerator WaitToReachDestination()    {        float startTime = Time.time;  // 记录开始移动的时间        while (navMeshAgent.remainingDistance > navMeshAgent.stoppingDistance)  // 当还未到达目的地时循环        {            if (Time.time - startTime >= maxWalkTime)  // 如果超过了最大行走时间            {                navMeshAgent.ResetPath();  // 重置路径                SetState(AnimalState.Idle);  // 将状态设置为 Idle                yield break;  // 结束函数的执行            }            yield return null;  // 等待下一帧        }        // 到达目的地后将状态设置为 Idle        SetState(AnimalState.Idle);    }    // 将动物的状态设置为指定的状态    protected void SetState(AnimalState newState)    {        if (currentState == newState)  // 如果新状态与当前状态相同,直接返回        {            return;        }        currentState = newState;  // 更新当前状态        OnStateChanged(newState);  // 触发状态改变事件    }    // 状态改变事件的处理函数    protected virtual void OnStateChanged(AnimalState newState)    {        UpdateState();  // 更新动物的状态    }}

添加羊,配置参数
在这里插入图片描述

效果
在这里插入图片描述

源码

源码在最后一期

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~

在这里插入图片描述

点击全文阅读

郑重声明:

本站所有活动均为互联网所得,如有侵权请联系本站删除处理

上一篇:公司建议书模板汇编

下一篇:返回列表

我来说两句