小怪绕圈围堵英雄

一开始的思想是:在英雄周围形成一个半径为r的圆圈,并设定向下即设定target.transform.forward为0度角的向量和每45度角有一个可以占的位置,用小怪的位置点与英雄的位置点做一条向量,这条向量与0度角向量之间产生一个夹角,判断这个夹角与哪个可以占的位置最近就把它设为一开始的目标去寻路:

public void FindDestination(float angle,Transform target)//敌人停留位置算法
    {
        r += (cout1 /8) * 15;//8个小怪一个圈,若超过8个就半径加大
        cout1++;//统计当前小怪的数目
        for (int i = 0; i < n / 2; i++)
        {
            if (angle < 0)
            {
                angle += 360;
            }
            FlagI = (int)(angle / (360 / n));//标识停留的位置范围   //n表示一个圈设几个点
            FlagL = (FlagI - i) * (360 / n);//取值范围的左边界
            FlagR = (FlagI + 1 + i) * (360 / n);//取值范围的右边界
            if (FlagL < 0)
            {
                FlagL += 360;
            }
            if (FlagR < 0)
            {
                FlagR += 360;
            }
            if (FlagR > 360)
            {
                FlagR -= 360;
            }
            if (FlagL > 360)
            {
                FlagL -= 360;
            }
            if ((FlagR-angle )<(angle-FlagL))//往右走
            {
                if (flag[FlagR + r ] == false)
                {
                x1 = target.transform.position.x+ r * Mathf.Cos(Convert.ToSingle(FlagR  * Mathf.PI / 180));//计算坐标x的增量
                z1 = target.transform.position.z+r * Mathf.Sin(Convert.ToSingle(FlagR * Mathf.PI / 180));//计算坐标x的增量
                 flag[FlagR + r ] = true;
                 dest = new Vector3(x1, target.transform.position.y, z1);//目标位置
                 break;
                    }
                }
                else if (flag[FlagL + r ] == false)
                {
                   x1 = target.transform.position.x+r * Mathf.Cos(Convert.ToSingle(FlagL * Mathf.PI / 180));//计算坐标x的增量
                   z1 = target.transform.position.z+ r * Mathf.Sin(Convert.ToSingle(FlagL * Mathf.PI / 180));//计算坐标x的增量
                   flag[FlagL + r] = true;
                    dest = new Vector3(x1, target.transform.position.y, z1);//目标位置
                    break;
                }
            }
            else if((FlagR - angle) >=(angle - FlagL))//往左走
            {
                //Debug.Log("flar:" + FlagR);
                if (flag[FlagL + r ] == false)
                {
                   x1 = target.transform.position.x+r * Mathf.Cos(Convert.ToSingle(FlagL * Mathf.PI / 180));//计算坐标x的增量
                   z1 = target.transform.position.z+ r * Mathf.Sin(Convert.ToSingle(FlagL * Mathf.PI / 180));//计算坐标x的增量
                   flag[FlagL + r] = true;
                    dest = new Vector3(x1, target.transform.position.y, z1);//目标位置
                    break;
                    }
                }
                
                else if (flag[FlagR + r ] == false)
                {
                 x1 = target.transform.position.x+ r * Mathf.Cos(Convert.ToSingle(FlagR * Mathf.PI / 180));//计算坐标x的增量
                 z1 = target.transform.position.z+r * Mathf.Sin(Convert.ToSingle(FlagR * Mathf.PI / 180));//计算坐标x的增量
                 flag[FlagR+r] = true;
                  dest = new Vector3(x1, target.transform.position.y, z1);//目标位置
                  break;
                }
            }
          }
       this.target = target;
       this.dest = dest;

    }

一开始产生一个小怪就算与英雄之间的距离,之后通过从小到大的排序结果对FindDestination()函数 进行调用

for (int i = 0; i < HeroCountEachRoom; i++)
        {
            //初始化敌人
            goHero = GameObject.Instantiate(HeroObj);
            //敌人放入数组里面
            AllHero.Add(goHero);
            //敌人的位置
            goHero.transform.position = GetNextPosition();
            //假设目标点6-5
              this.agent=GameObject.FindGameObjectWithTag("agent").GetComponent<NavMeshAgent>();//.GetComponent<NavMeshAgent>();
                                GameObject[] players = GameObject.FindGameObjectsWithTag("enemy");//找到tag为player的英雄                                                              // targetPosition = new Vector3[2];                                                                       //判断怪物与玩家的距离来选择目标
            foreach (GameObject player in players)//找到目标点
            {
                if (Vector3.Distance(player.GetComponent<Transform>().position, goHero.transform.position) < distance)
                {
                    distance = Vector3.Distance(player.GetComponent<Transform>().position, goHero.transform.position);
                    target = player.transform;//定义player就是目标玩家
                }
            }
            
            //存储敌人index与对应的目标
            list2[i] =target;
            number0 = list2[i].transform.forward;
            //目标点的位置
            targetPoSition = new Vector3(list2[i].position.x, list2[i].position.y, list2[i].position.z);
            //敌人的位置 Verctor3 hero
            //目标点与敌人的夹角
            hero = AllHero[i].GetComponent<Hero>();
            angle = Vector3.Angle(number0, hero.transform.position);
            //目标点与敌人的方向
            float dir = (Vector3.Dot(Vector3.up, Vector3.Cross(number0, targetPoSition - hero.transform.position)) < 0 ? -1 : 1);
            angle *= dir;
            //Debug.Log("angle:"+angle);
            if (angle < 0)
            {
                angle += 360;
            }
            list3[i] = angle;
            //target目标所在位置
            v1 = new Vector3(list2[i].transform.position.x, list2[i].transform.position.y, list2[i].transform.position.z);
        v = new Vector3(list2[i].transform.position.x + hero.r * Mathf.Cos(Convert.ToSingle(angle * Mathf.PI / 180)), list2[i].transform.position.y, list2[i].transform.position.z + hero.r * Mathf.Sin(Convert.ToSingle(angle * Mathf.PI / 180)));
            //6-5 存储敌人的index和距离
            list[i]= Vector3.Distance(new Vector3(goHero.transform.position.x, goHero.transform.position.y, goHero.transform.position.z),v);
        }
       
        //6-5 通过距离从小到大排序
        Dictionary<int, float> dic1Asc = list.OrderBy(p => p.Value).ToDictionary(o => o.Key, p => p.Value);
        foreach (KeyValuePair<int, float> k in dic1Asc)
        {
            hero = AllHero[k.Key].GetComponent<Hero>();
            hero.FindDestination(list3[k.Key], list2[k.Key]);

        }



猜你喜欢

转载自blog.csdn.net/qq_35307209/article/details/80670504