Ejemplo n.º 1
0
    //	Recursively build a tree by separating points at plane boundaries.
    static KDTreeFree MakeFromPointsInner(
        int depth,
        int stIndex, int enIndex,
        Vector3[] points,
        int[] inds
        )
    {
        KDTreeFree root = new KDTreeFree();

        root.axis = depth % numDims;
        int splitPoint = FindPivotIndex(points, inds, stIndex, enIndex, root.axis);

        root.pivotIndex = inds[splitPoint];
        root.pivot      = points[root.pivotIndex];

        int leftEndIndex = splitPoint - 1;

        if (leftEndIndex >= stIndex)
        {
            root.lr[0] = MakeFromPointsInner(depth + 1, stIndex, leftEndIndex, points, inds);
        }

        int rightStartIndex = splitPoint + 1;

        if (rightStartIndex <= enIndex)
        {
            root.lr[1] = MakeFromPointsInner(depth + 1, rightStartIndex, enIndex, points, inds);
        }

        return(root);
    }
Ejemplo n.º 2
0
    // The main coroutine, which starts to search for nearest enemies neighbours and set them for attack
    // NN search works with kdtree.cs NN search class, implemented by A. Stark at 2009.
    // Target candidates are put on kdtree, while attackers used to search for them.
    // NN searches are based on position coordinates in 3D.
    public IEnumerator SearchPhase()
    {
        float timeBegin, timeEnd;

        List <GameObject>[] attackers = new List <GameObject> [2];
        List <GameObject>[] defenders = new List <GameObject> [2];

        for (int i = 0; i < attackers.Length; i++)
        {
            attackers[i] = new List <GameObject>();
            defenders[i] = new List <GameObject>();
        }

        while (true)
        {
            timeBegin = Time.realtimeSinceStartup;

            for (int i = 0; i < attackers.Length; i++)
            {
                attackers[i].Clear();
                defenders[i].Clear();
            }

            // adding back units which becomes attackable (if they get less attackers than defined by critical number)
            var searchCounter = 0;
            for (int i = 0; i < aliveUnits.Count; i++)
            {
                var unit     = aliveUnits[i];
                var unitPars = unit.GetComponent <UnitParsFree>();
                int alliance = unitPars.alliance;

                if (unitPars.mode == Mode.SEARCH)
                {
                    attackers[alliance].Add(unit);
                    searchCounter++;
                }
                defenders[alliance].Add(unit);
            }

            var defenderPoints = new List <Vector3[]>();
            for (int i = 0; i < attackers.Length; i++)
            {
                var points = new Vector3[defenders[i].Count];
                for (int j = 0; j < defenders[i].Count; ++j)
                {
                    points[j] = defenders[i][j].transform.position;
                }
                defenderPoints.Add(points);
            }

            var kdTrees = new List <KDTreeFree>();
            for (int i = 0; i < attackers.Length; i++)
            {
                kdTrees.Add(KDTreeFree.MakeFromPoints(defenderPoints[i]));
            }

            timeEnd = Time.realtimeSinceStartup;
            yield return(new WaitForSeconds(0.5f));

            timeloops[1] = timeEnd - timeBegin;
            timeBegin    = Time.realtimeSinceStartup;

            for (int i = 0; i < attackers.Length; i++)
            {
                if (defenders[1 - i].Count == 0)
                {
                    continue;
                }

                for (int j = 0; j < attackers[i].Count; ++j)
                {
                    var att     = attackers[i][j];
                    var attPars = att.GetComponent <UnitParsFree>();
                    // Skipp all units which may have changed states during the yield
                    if (attPars.mode != Mode.SEARCH)
                    {
                        continue;
                    }

                    var defenderId = kdTrees[1 - i].FindNearest(att.transform.position);
                    var def        = defenders[1 - i][defenderId];

                    attPars.setApproach(def);
                }
            }
            timeEnd = Time.realtimeSinceStartup;
            yield return(new WaitForSeconds(0.5f));

            timeloops[1]  += timeEnd - timeBegin;
            timeall[1]     = timeloops[1] + 1.0f;
            performance[1] = timeloops[1] * 100.0f / timeall[1];

            message1 = "Search: " + searchCounter.ToString() + "; " + timeloops[1].ToString() + "; " + performance[1].ToString() + "%";
        }
    }
Ejemplo n.º 3
0
    public IEnumerator SearchPhase()
    {
// The main coroutine, which starts to search for nearest enemies neighbours and set them for attack
// NN search works with kdtree.cs NN search class, implemented by A. Stark at 2009.
// Target candidates are put on kdtree, while attackers used to search for them.
// NN searches are based on position coordinates in 3D.

        float t1      = 0.0f;
        float t2      = 0.0f;
        float twaiter = 0.0f;
        float t3      = Time.realtimeSinceStartup;



        int indmindisti = 0;



        yield return(new WaitForSeconds(1.0f));

        while (true)
        {
            t1      = Time.realtimeSinceStartup;
            twaiter = 0;



            KDTreeFree RTree1 = new KDTreeFree();
            KDTreeFree RTree2 = new KDTreeFree();



// adding back units which becomes attackable (if they get less attackers than defined by critical number)

            for (int i = 0; i < unitss.Count; i++)
            {
                GameObject go = unitss[i];
                if (go.GetComponent <UnitParsFree>().isReady)
                {
                    int alliance = go.GetComponent <UnitParsFree>().alliance;
                    if (go.GetComponent <UnitParsFree>().isAttackable == true)
                    {
                        if (go.GetComponent <UnitParsFree>().onTargetSearch == false)
                        {
                            runits[alliance].Add(go);
                            go.GetComponent <UnitParsFree>().onTargetSearch = true;
                        }
                    }

                    rfunits[alliance].Add(go);

                    go.GetComponent <UnitParsFree>().isReady = false;
                }
            }



// resetting copies arrays.

            cprunits[1].Clear();
            cprunits[2].Clear();

            cprfunits[1].Clear();
            cprfunits[2].Clear();


            for (int i = 1; i < runits[1].Count; i++)
            {
                cprunits[1].Add(runits[1][i]);
            }
            for (int i = 0; i < runits[2].Count; i++)
            {
                cprunits[2].Add(runits[2][i]);
            }

            for (int i = 1; i < rfunits[1].Count; i++)
            {
                cprfunits[1].Add(rfunits[1][i]);
            }
            for (int i = 1; i < rfunits[2].Count; i++)
            {
                cprfunits[2].Add(rfunits[2][i]);
            }

// finding counters for copies arrays

            countr1 = cprunits[1].Count;
            countr2 = cprunits[2].Count;

            countrf1 = cprfunits[1].Count;
            countrf2 = cprfunits[2].Count;



            // initialising vector arrays

            Vector3[] rtreePoints1 = new Vector3[countr1];
            Vector3[] rtreePoints2 = new Vector3[countr2];

            int [] iorig1 = new int[countr1];
            int [] iorig2 = new int[countr2];


            Vector3[] rftreePoints1 = new Vector3[countrf1];
            Vector3[] rftreePoints2 = new Vector3[countrf2];

            int [] iorigf1 = new int[countrf1];
            int [] iorigf2 = new int[countrf2];


// putting target candidates coordinates onto arrays and setting non attackable targets not to be used on search

            //	rtreePoints1[0] = new Vector3 (-999999999999.99f,-999999999999.99f,-999999999999.99f);
            //	iorig1[0]=0;
            //	rtreePoints2[0] = new Vector3 (-999999999999.99f,-999999999999.99f,-999999999999.99f);
            //	iorig2[0]=0;


            for (int i = 1; i < countr1; i++)
            {
                rtreePoints1[i] = cprunits[1][i].transform.position;
                iorig1[i]       = i;
                if (cprunits[1][i].GetComponent <UnitParsFree>().isAttackable == false)
                {
                    if (cprunits[1][i].GetComponent <UnitParsFree>().onTargetSearch == true)
                    {
                        cprunits[1][i].GetComponent <UnitParsFree>().onTargetSearch = false;
                        runits[1].Remove(cprunits[1][i]);
                    }
                }
                //
            }
            for (int i = 1; i < countr2; i++)
            {
                rtreePoints2[i] = cprunits[2][i].transform.position;
                iorig2[i]       = i;
                if (cprunits[2][i].GetComponent <UnitParsFree>().isAttackable == false)
                {
                    if (cprunits[2][i].GetComponent <UnitParsFree>().onTargetSearch == true)
                    {
                        cprunits[2][i].GetComponent <UnitParsFree>().onTargetSearch = false;
                        runits[2].Remove(cprunits[2][i]);
                    }
                }
            }

// putting attackers candidates coordinates onto arrays and removing them from original arrays,
// as they all will get targets

            for (int i = 1; i < countrf1; i++)
            {
                rftreePoints1[i] = cprfunits[1][i].transform.position;
                iorigf1[i]       = i;
                rfunits[1].Remove(cprfunits[1][i]);
            }
            for (int i = 1; i < countrf2; i++)
            {
                rftreePoints2[i] = cprfunits[2][i].transform.position;
                iorigf2[i]       = i;
                rfunits[2].Remove(cprfunits[2][i]);
            }

// sorting vector arrays for faster searches in kdtree

//		HeapSort(rtreePoints1, iorig1);
//		HeapSort(rtreePoints2, iorig2);

//		HeapSort(rftreePoints1, iorigf1);
//		HeapSort(rftreePoints2, iorigf2);

// putting target candidates onto kdtree



            RTree1 = KDTreeFree.MakeFromPoints(rtreePoints1);
            RTree2 = KDTreeFree.MakeFromPoints(rtreePoints2);



            GameObject tempObj1;
            GameObject tempObj2;

// first team attackers searching and setting their targets

            for (int i = 1; i < countrf1; i++)
            {
                indmindisti = RTree2.FindNearest(rftreePoints1[i]);

                int io     = iorigf1[i];
                int iomind = iorig2[indmindisti];

                tempObj1 = cprfunits[1][io];
                tempObj2 = cprunits[2][iomind];


                tempObj1.GetComponent <UnitParsFree>().target = tempObj2;

                // adding attacker to target attackers list
                tempObj2.GetComponent <UnitParsFree>().attackers.Add(tempObj1);
                tempObj2.GetComponent <UnitParsFree>().noAttackers = tempObj2.GetComponent <UnitParsFree>().noAttackers + 1;

                tempObj1.GetComponent <UnitParsFree>().isApproaching = true;



                if (Time.realtimeSinceStartup - t3 > 0.005f)
                {
                    twaiter = twaiter + 0.1f * (Time.realtimeSinceStartup - t3) + 0.05f;
                    yield return(new WaitForSeconds(0.1f * (Time.realtimeSinceStartup - t3) + 0.05f));

                    t3 = Time.realtimeSinceStartup;
                }
            }



// second team attackers searching and setting their targets

            for (int i = 1; i < countrf2; i++)
            {
                indmindisti = RTree1.FindNearest(rftreePoints2[i]);

                int io     = iorigf2[i];
                int iomind = iorig1[indmindisti];

                tempObj1 = cprfunits[2][io];
                tempObj2 = cprunits[1][iomind];


                tempObj1.GetComponent <UnitParsFree>().target = tempObj2;

                // adding attacker to target attackers list
                tempObj2.GetComponent <UnitParsFree>().attackers.Add(tempObj1);
                tempObj2.GetComponent <UnitParsFree>().noAttackers = tempObj2.GetComponent <UnitParsFree>().noAttackers + 1;

                tempObj1.GetComponent <UnitParsFree>().isApproaching = true;



                if (Time.realtimeSinceStartup - t3 > 0.005f)
                {
                    twaiter = twaiter + 0.1f * (Time.realtimeSinceStartup - t3) + 0.05f;
                    yield return(new WaitForSeconds(0.1f * (Time.realtimeSinceStartup - t3) + 0.05f));

                    t3 = Time.realtimeSinceStartup;
                }
            }



            t2 = Time.realtimeSinceStartup;


            displayMessage = true;



// main coroutine wait statement and performance information collection from search coroutine

            twaiter = twaiter + 0.5f + 1.0f * (t2 - t1);
            yield return(new WaitForSeconds(0.5f + 1.0f * (t2 - t1)));

            float curTime = Time.realtimeSinceStartup;

            timeloops[1]   = curTime - t1 - twaiter;
            timeall[1]     = curTime - t1;
            performance[1] = (curTime - t1 - twaiter) * 100.0f / (curTime - t1);

            message1 = ("Search: " + (countr1 + countr2).ToString() + "; " + countrf1 + "; " + countrf2 + "; " + (curTime - t1 - twaiter).ToString() + "; " + (performance[1]).ToString() + "% ");
        }
    }