unity学习:寻路算法(AStar算法)与简单AI(势能场估价算法)

本文介绍了在Unity中结合AStar算法和势能场估价算法实现游戏AI的过程。内容包括游戏玩法、AStar算法实现、AI行为设计以及为何同时使用AStar和势能场。开发者分享了项目经验,指出AStar在多线程中的问题,并讨论了势能场的优缺点及寻路优化策略。
摘要由CSDN通过智能技术生成

项目地址:https://github.com/kotomineshiki/AIFindPath
视频地址:多重寻路多重寻路

综合寻路——包括攻击考量的寻路算法

这里写图片描述

GamePlay

这是一个《文明》+皇室战争的组合。
UI层使用状态机来实现以下操作
1. 点击棋子再点击格子,棋子移动向格子(AStar算法)
2. 点击棋子会弹出该棋子的属性介绍面板,再点击一次取消
3. 点击格子会弹出该格子的属性介绍面板,再点击一次取消
4. 点击底部召唤板,再点击格子,会在该格子处召唤一个棋子
5. 点击召唤板未点击格子时,会在鼠标停留的格子上出现一个虚影
6. 点击棋子再点击另一个棋子的时候,该棋子移动向另一个棋子,如果他们处于敌对阵营,则该棋子列入攻击列表
一些bug:
AStar算法不要使用多线程,因为如果节点情况有变,则会产生线程合并的冲突导致抖动。
其实Astar算法和作为AI的势能场算法是有冲突的,下次重构的时候应该特别注意只使用势能场。因为势能场本身就已经包括了寻路算法,所以没必要特意写一个寻路算法增加代码复杂度,这是这次经验不足导致的。
两个核心难点

Astar算法

先是自己实现了一遍,后来找到了效率更高的插件就重构了

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MyAStar {



    public ArrayList openList;
    public ArrayList closeList;
    public int targetX;
    public int targetY;
    public Vector2Int start;
    public Vector2Int end;



    public Stack<string> parentList;//结果栈,存的格式是xy
    public List<Vector2Int> resultPath;//结果队列
    //public Transform plane;

    //public Transform obstacle;

    private float alpha = 0;
    private float incrementPer = 0;
    public void SetStartGrid(int x, int y)
    {
        start.x = x;
        start.y = y;
        GridMap.instance.grids[x, y].SetGridType(GridType.Start);
        openList.Add(GridMap.instance.grids[x, y]);
    }
    public void SetEndGrid(int x, int y)
    {
        end.x = x;
        end.y = y;

        GridMap.instance.grids[x, y].SetGridType(GridType.End);
    }
    public void Clear()
    {
        GridMap.instance.grids[start.x, start.y].SetGridType(GridType.Normal);
        GridMap.instance.grids[end.x, end.y].SetGridType(GridType.Normal);//恢复初始状态
        for(int i = 0; i < GridMap.instance.row; ++i)
        {
            for(int j = 0; j < GridMap.instance.column; ++j)
            {
                GridMap.instance.grids[i, j].parent = null;
                GridMap.instance.grids[i, j].f = 0;
                GridMap.instance.grids[i, j].g = 0;
                GridMap.instance.grids[i, j].h = 0;
            }
        }

        parentList.Clear();
        openList.Clear();
        closeList.Clear();
        resultPath.Clear();
    }
    public MyAStar()//初始化函数
    {
        parentList = new Stack<string>();
        openList = new ArrayList();
        closeList = new ArrayList();
        resultPath = new List<Vector2Int>();
        Debug.Log("初始化完成");
    }

    public void Calculate()
    {
        Debug.Log("开始寻找路径");
        //yield return new WaitForSeconds(0.1f);
        //openList.Add(grids[startX, startY]);
        MyGrid currentGrid = openList[0] as MyGrid;
        while (openList.Count > 0 && currentGrid.gridType != GridType.End)
        {
            currentGrid = openList[0] as MyGrid;
            if (currentGrid.gridType == GridType.End)
            {
                Debug.Log("找到路径");
                GenerateResult(currentGrid);
            }
            for(int i = -1; i <= 1; i++)
            {
                for(int j = -1; j <= 1; j++)
                {
                    if (i != 0 || j != 0)
                    {
                        in
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值