[Chip]Unity开发笔记--NavMesh实现敌人巡逻与警戒

1.地形搭建

1.创建平台(以Cube为例),缩放至所需大小,为其添加NavMeshSurface组件。

2.设定一个新的Agent Type命名为Enemy,Enemy参数均为默认(可根据实际需要进行调整)。

3.调整NavMeshSurface参数,在Object Collection中筛选所需烘焙的地形,默认为所有物体,因为我将多个敌人巡逻平台都设置为它的子物体,故将Collect Object修改为Current Object Hierarchy。

3.1在筛选过程中,将Collect Object修改为NavMeshModifier Conponent Only是只烘焙拥有该组件的物体,修改Include Layers用于根据层级筛选物体。

4.点击最下方的Bake即可。

配置完后如图所示

2.敌人设置

1.创建敌人(以Capsule为例),缩放至所需大小,为其添加NavMeshAgent组件,调整Agent Type为Enemy。

2.为敌人添加一个空物体命名为Warning,为其添加Sphere Collider,勾选Is Trigger并调整大小作为Enemy的警戒圈,此处Radius设置为20。

3.代码编写

1.敌人状态,其他状态根据需求添加,此处只介绍移动和警戒

public enum EnemyState
    {
        Moving, Warning
    }
EnemyState enemyState;
private void Start()
    {
        enemyState = EnemyState.Moving;
    }

2.巡逻参数相关

NavMeshAgent agent;
Vector3 spawnPoint; 
//出生点
public float movingRadius; 
//巡逻半径
float varX;
float varZ;
Vector3 varPosition; 
//随机位置
Vector3 presentPosition; 
//当前位置
float varDistance; 
//随机位置与当前位置的距离
float minDistance; 
//最近距离

private void Start()
    {
        agent = GetComponent<NavMeshAgent>();
        spawnPoint=transform.position;
    }

3.获取一个随机位置

private void RandomPosition()
    {
        varX = UnityEngine.Random.Range(spawnPoint.x - movingRadius, spawnPoint.x + movingRadius);
        varZ = UnityEngine.Random.Range(spawnPoint.z - movingRadius, spawnPoint.z + movingRadius);
        varPosition = new Vector3(varX,transform.position.y,varZ);
        在出生点周围半径为R的圆内获取一个随机位置
    }

4.向随机位置移动,并判断距离

private void MovingState()
    {
        agent.isStopped = false;
        varDistance = Vector3.Distance(varPosition, transform.position);
        if (varDistance <= minDistance)
        {
            RandomPosition(); 
            //随机新位置
            agent.SetDestination(varPosition); 
            //开始移动
        }
    }

5.为Warning添加脚本判定警戒范围内是否有Player

public GameObject player;
public bool findPlayer;
private void OnTriggerStay(Collider other)
    {
        if (other.tag == "player")
        {
            player = other.gameObject;
            findPlayer = true;
        }
    }
private void OnTriggerExit(Collider other)
    {
        if (other.tag == "player")
        {
            Debug.Log("没发现玩家");
            player = null;
            findPlayer = false;
        }
    }

6.状态判断

GameObject warning;
private void Update()
    {
        findPlayer = warning.GetComponent<Warning>().findPlayer;
        player = warning.GetComponent<Warning>().player;
        if (findPlayer)
        {
            enemyState = EnemyState.Warning;
        }
        else
        {
            enemyState = EnemyState.Moving;
        }
    }
private void FixedUpdate()
    {
        switch (enemyState)
        {
            case EnemyState.Moving:
                MovingState();
                break;
            case EnemyState.Warning:
                WarningState();
                break;
        }
    }
private void WarningState()
    {
        agent.isStopped = true;
        //发现Player后停止移动
        canShooting = true;
        //后续攻击代码根据需要编写
    }

7.设置好movingRadius保存并运行即可发现敌人在所设定的平台上移动。

4.完整项目视频预览

[Unity练习作]类幽灵行者跑酷小游戏

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值