Ejemplo n.º 1
0
    /// <summary>
    /// Update called in every frame.
    /// </summary>
    void OnGUI()
    {
        // Set up the GUI skin.
        GUI.skin = mSkinToApply;

        // Update the simulation controller script.
        mSimulationController = GameObject.FindWithTag("MainCamera").GetComponent<cSimulationController>();

        // Update the player controller script.
        mPlayerController = GameObject.FindWithTag("thePlayer").GetComponent<cPlayerController>();

        // If trace data is not set yet, set it up.
        if (traceSet == false)
        {
            for (int i = 0; i < mNPCmarkers.Length; i++)
            {

                GameObject tmpNPC = GameObject.FindWithTag("theNPC" + i);
                if (tmpNPC != null)
                {
                    mNPCController = tmpNPC.GetComponent<cNPCController>();

                    mNPCController.mTraceColor = new Color(1.0f/(i+1), 0.0f, 0.0f, 1.0f);
                    mNPCController.setLineTracer();
                }
            }
            traceSet = true;
        }

        // Set up the trace length.
        if (mTraceLength != "")
            mPlayerController.mTraceSize = int.Parse(mTraceLength);

        // Set current trace size of each NPC to the selected trace size.
        for (int i = 0; i < mSimulationController.numberOfnpcs; i++) {

            GameObject tmpNPC = GameObject.FindWithTag("theNPC" + i);

            if (tmpNPC != null)
            {
                mNPCController = tmpNPC.GetComponent<cNPCController>();
                if (mTraceLength != "")
                    mNPCController.mTraceSize = int.Parse(mTraceLength);
            }
        }

        // Construct the Simulation settings GUI element.
        if(mGUI_containers[4].expanded)
        {
            GUILayout.BeginArea(mGUI_containers[4].position, mBackground);
        }
        else
            GUILayout.BeginArea(mGUI_containers[4].position_not_expanded, mBackground);

            GUILayout.BeginVertical(GUI.skin.customStyles[0]);

            mGUI_containers[4].expanded = GUILayout.Toggle(mGUI_containers[4].expanded, new GUIContent ("Simulation settings", "tool tip"), GUILayout.Width(140));

            bool expand_overlap = false;
            for (int i = 1; i < 6; i++)
            {
                if (i != 4)
                {

                    if (mGUI_containers[i].expanded)
                    {
                        if (RectsOverap(mGUI_containers[4].position, mGUI_containers[i].position))
                        {
                            expand_overlap = true;
                        }
                    }
                    else
                    {
                        if (RectsOverap(mGUI_containers[4].position, mGUI_containers[i].position_not_expanded))
                        {
                            expand_overlap = true;
                        }
                    }
                }
            }

            if (expand_overlap)
            {
                mGUI_containers[4].expanded = false;
            }

            if (mGUI_containers[4].expanded)
            {

                GUILayout.Box(mLogoTexture, new GUIStyle());

                GUI.SetNextControlName("GUI_NoNPCs");
                mGUI_NumberOfNPCs = GUILayout.TextField(mGUI_NumberOfNPCs);

                if ((Event.current.type == EventType.KeyUp) && (Event.current.keyCode == KeyCode.Return))
                {
                    GUI.SetNextControlName("");
                    GUI.FocusControl("");
                }

                else if (!string.Equals(GUI.GetNameOfFocusedControl(), "GUI_NoNPCs"))
                {
                    if (int.TryParse(mGUI_NumberOfNPCs, out mNewNumberOfNPCs))
                    {
                        if(mNewNumberOfNPCs != mNumberOfNPCs && mNewNumberOfNPCs >= 0 && mNewNumberOfNPCs < MAXNUMOFNPCS)
                        {

                            mSimulationController.destroyActors();

                            mSimulationController.numberOfnpcs = mNewNumberOfNPCs;
                            mSimulationController.initSimulation();

                            mIndividualAIBehaviourMarkers = new int[mNewNumberOfNPCs];
                            for (int i = 0; i < mNewNumberOfNPCs; i++)
                            {
                                mIndividualAIBehaviourMarkers[i] = 0;
                            }

                            for (int i = 0; i < mNPCmarkers.Length; i++)
                            {
                                Destroy(mNPCmarkers[i]);
                            }

                            mNPCmarkers = new Texture2D[mNewNumberOfNPCs];

                            for (int i = 0; i < mNPCmarkers.Length; i++)
                            {
                                GameObject tmpNPC = GameObject.FindWithTag("theNPC" + i);
                                mNPCController = tmpNPC.GetComponent<cNPCController>();
                                mNPCmarkers[i] = new Texture2D(24, 24);
                                for (int j = 0; j < 24; j++)
                                    for (int k = 0; k < 24; k++)
                                        mNPCmarkers[i].SetPixel(j, k, new Color(1.0f/(i+1), 0.0f, 0.0f, 1.0f));
                                mNPCmarkers[i].Apply();
                            }
                            mNumberOfNPCs = mNewNumberOfNPCs;

                            mGUI_containers[5].position = new Rect (mGUI_containers[5].position.x, mGUI_containers[5].position.y, mGUI_containers[5].position.width,mNumberOfNPCs*0.06f*Screen.height);
                        }
                        mGUI_NumberOfNPCs = mNumberOfNPCs.ToString();
                    }
                }

                // Create the title for speed adjustment slider.
                GUILayout.Label ("Current simulation speed: " + mCurrentSpeed);

                // Create the slider for adjusting simulation speed.
                float lNewSpeed = GUILayout.HorizontalSlider((int)mCurrentSpeed, 0.0f, mMaxSpeed);
                if (mCurrentSpeed != lNewSpeed)
                {
                    mCurrentSpeed = lNewSpeed;
                    mCurrentAIBehaviourChanged = true;
                }

                // Create the title for the selection grid for simulation type.
                GUILayout.Label("Simulation type: ");

                // Create the selection grid.
                int lTmp = GUILayout.SelectionGrid(mSelectionGridIntSimulationType, mSelectionStringsSimulationType, 1);
                if (lTmp != mSelectionGridIntSimulationType)
                {
                    mSimulationController.currentSimulationCategory = (SIMULATION) lTmp;
                    mSimulationController.currentAIBehavior = 0;
                    mSelectionGridIntAIBehaviour = 0;
                    mCurrentAIBehaviourChanged = true;
                    mCurrentSimulationTypeChanged = true;
                    mSelectionGridIntSimulationType = lTmp;
                }

                mFlocking = GUILayout.Toggle(mFlocking, "Flocking", GUILayout.Width(140));
                mSimulationController.flockingOn = mFlocking;

                mTraceLength = GUILayout.TextField(mTraceLength);

                mSelectionGridIntCamViews[3] = GUILayout.SelectionGrid(mSelectionGridIntCamViews[3], mSelectionStringsCamViews, 4);
                mGUI_containers[4].target = mSelectionGridIntCamViews[3]+1;

                if (GUILayout.Button("Quit simulation", GUI.skin.button))
                {
                    // ToDo: find better solution for iOS build.
                    Application.Quit();
                }
            }

            GUILayout.EndVertical();
        GUILayout.EndArea ();

        // GUI area for individual NPCs.
        if(mGUI_containers[5].expanded)
        {
            GUILayout.BeginArea(mGUI_containers[5].position, mBackground);
        }
        else
            GUILayout.BeginArea(mGUI_containers[5].position_not_expanded, mBackground);

            mScrollPositionIndividualNPCs = GUILayout.BeginScrollView(mScrollPositionIndividualNPCs);

            GUILayout.BeginVertical(GUI.skin.customStyles[0]);

                mGUI_containers[5].expanded = GUILayout.Toggle(mGUI_containers[5].expanded, "Individual NPC settings", GUILayout.Width(240));

                bool expand_overlap2 = false;
                for (int i = 1; i < 6; i++)
                {
                    if (i != 5)
                    {

                        if (mGUI_containers[i].expanded)
                        {
                            if (RectsOverap(mGUI_containers[5].position, mGUI_containers[i].position))
                            {
                                expand_overlap2 = true;
                            }
                        }
                        else
                        {
                            if (RectsOverap(mGUI_containers[5].position, mGUI_containers[i].position_not_expanded))
                            {
                                expand_overlap2 = true;
                            }
                        }
                    }
                }

                if (expand_overlap2)
                {
                    mGUI_containers[5].expanded = false;
                }

                if (mGUI_containers[5].expanded)
                {

                for (int i = 0; i < mSimulationController.numberOfnpcs; i++)
                {
                    GUILayout.BeginHorizontal();

                        if (mColorPickerVisible[i] == false)
                        {
                            GUILayout.Label (mSimulationController.npcs[i].tag);
                            bool tmp = GUILayout.Toggle(mSimulationController.npcs[i].active, "Active");
                            mSimulationController.npcs[i].SetActiveRecursively(tmp);
                            if (GUILayout.Button(mNPCmarkers[i], GUI.skin.button, GUILayout.Height(18), GUILayout.Width(18)))
                            {
                                mColorPickerVisible[i] = true;
                                mColorChangeTarget = i;
                                mSelectedColor = mNPCmarkers[i].GetPixel(0,0);
                            }

                            GameObject tmpNPC = GameObject.FindWithTag("theNPC" + i);

                            if (tmpNPC != null)
                            {

                                mNPCController = tmpNPC.GetComponent<cNPCController>();
                            }

                            int lTmp2 = 0;
                            switch (mSimulationController.currentSimulationCategory)
                            {
                            case SIMULATION.KINEMATIC_MOVEMENT:
                                foreach (KINEMATIC_MOVEMENT km in KINEMATIC_MOVEMENT.GetValues(typeof(KINEMATIC_MOVEMENT)))
                                {
                                        if ((int)km < mNPCController.mActiveKinematicMovements.Length)
                                            mNPCController.mActiveKinematicMovements[(int)km] = GUILayout.Toggle(mNPCController.mActiveKinematicMovements[(int)km], km.ToString(), GUILayout.Width(0.025f*Screen.width));
                                }
                                break;
                            case SIMULATION.STEERING_BEHAVIOR:
                                foreach (STEERING_BEHAVIOR sb in STEERING_BEHAVIOR.GetValues(typeof(STEERING_BEHAVIOR)))
                                {
                                    if ((int)sb < mNPCController.mActiveKinematicMovements.Length)
                                        mNPCController.mActiveSteeringBehaviours[(int)sb] = GUILayout.Toggle(mNPCController.mActiveSteeringBehaviours[(int)sb], sb.ToString(), GUILayout.Width(0.025f*Screen.width));;
                                }
                                break;
                            }

                            if (mNPCController.mFlockingData.mRole == FLOCK_ROLE.leader || mSimulationController.flockingOn == false)
                            {
                                mIndividualAIBehaviourMarkers[i] = lTmp2;
                            }

                            int tmpSel;

                            if (mNPCController.mFlockingData.mRole == FLOCK_ROLE.boid)
                                tmpSel = 0;
                            else
                                tmpSel = 1;

                            int lTmp3 = GUILayout.SelectionGrid(tmpSel, mSelectionStringsFocking, 2, GUILayout.Width(0.10f*Screen.width));

                            if (tmpSel == 0 && lTmp3 == 1)
                                mSimulationController.flockingLeadersCount++;

                            if (tmpSel == 1 && lTmp3 == 0)
                                mSimulationController.flockingLeadersCount--;

                            if (mSimulationController.flockingOn)
                            {
                                if (lTmp3 == 0)
                                {
                                    mNPCController.mFlockingData.mRole = FLOCK_ROLE.boid;
                                    mNPCController.setAction(0);
                                    mIndividualAIBehaviourMarkers[i] = 0;
                                }
                                else
                                    mNPCController.mFlockingData.mRole = FLOCK_ROLE.leader;
                            }

                        }
                        else
                        {
                                GUILayout.Label (mSimulationController.npcs[i].tag);
                                mSelectedColor = RGBSlider (new Rect (10,10,100,30), mSelectedColor);
                                mColorBoxTexture = new Texture2D(24, 24);
                                for (int ii = 0; ii < 24; ii++)
                                    for (int j = 0; j < 24; j++)
                                        mColorBoxTexture.SetPixel(ii, j, mSelectedColor);
                                mColorBoxTexture.Apply();
                                GUILayout.Box(mColorBoxTexture, new GUIStyle());
                                if (GUILayout.Button("Change the Color"))
                                {
                                    for (int j = 0; j < 24; j++)
                                    for (int k = 0; k < 24; k++)
                                        mNPCmarkers[mColorChangeTarget].SetPixel(j, k, mSelectedColor);
                                    mNPCmarkers[mColorChangeTarget].Apply();

                                    GameObject tmpNPC = GameObject.FindWithTag("theNPC" + mColorChangeTarget);

                                    if (tmpNPC != null)
                                    {
                                        mNPCController = tmpNPC.GetComponent<cNPCController>();
                                        mNPCController.lLineAI.material.color = mSelectedColor;
                                    }

                                    mColorPickerVisible[i] = false;
                                }

                        }
                    GUILayout.EndHorizontal();
                    GUILayout.Space(5.0f);
                }

            }
            GUILayout.EndVertical();

            GUILayout.EndScrollView();
        GUILayout.EndArea ();

        // GUI areas for mini cameras.
        bool[] expand_overlaps = new bool[3];

        for (int it = 1; it < 4; it++)
        {
            if(mGUI_containers[it].expanded)
            {
                GUILayout.BeginArea(mGUI_containers[it].position, mBackground);
            }
            else
                GUILayout.BeginArea(mGUI_containers[it].position_not_expanded, mBackground);

                GUILayout.BeginVertical(mSkinToApply.customStyles[0]);

                    mGUI_containers[it].expanded = GUILayout.Toggle(mGUI_containers[it].expanded, "Camera " + it, GUILayout.Width(80));

                    expand_overlaps[it-1] = false;
                    for (int ih = 1; ih < 6; ih++)
                    {
                        if (ih != it)
                        {

                            if (mGUI_containers[ih].expanded)
                            {
                                if (RectsOverap(mGUI_containers[it].position, mGUI_containers[ih].position))
                                {
                                    expand_overlaps[it-1] = true;
                                }
                            }
                            else
                            {
                                if (RectsOverap(mGUI_containers[it].position, mGUI_containers[ih].position_not_expanded))
                                {
                                    expand_overlaps[it-1] = true;
                                }
                            }
                        }
                    }

                    if (expand_overlaps[it-1])
                    {
                        mGUI_containers[it].expanded = false;
                    }

                    if (mGUI_containers[it].expanded)
                    {

                        int tmpSelection;
                        int tmpCam = 128;
                        if (mSelectionGridIntCamSizes[it-1] == 1)
                            tmpCam = 128;
                        else if (mSelectionGridIntCamSizes[it-1] == 2)
                            tmpCam = 256;
                        if (mSelectionGridIntCamSizes[it-1] == 3)
                            tmpCam = 512;
                        tmpSelection = mSelectionGridIntCamSizes[it-1];
                        mSelectionGridIntCamSizes[it-1] = GUILayout.SelectionGrid(mSelectionGridIntCamSizes[it-1], mSelectionStringsCamSizes, 3);

                        Rect tmpRect = new Rect(mGUI_containers[it].position.x, mGUI_containers[it].position.y, mGUI_containers[it].position.width, mGUI_containers[it].position.height);

                        int tmpCam2 = tmpCam;

                        if(mSelectionGridIntCamSizes[it-1] == 0)
                        {
                            tmpCam2 = 108;
                            tmpRect.width = 130;
                            tmpRect.height = 210;
                        }
                        if(mSelectionGridIntCamSizes[it-1] == 1)
                        {
                            tmpCam2 = 236;
                            tmpRect.width = 258;
                            tmpRect.height = 338;
                        }
                        if(mSelectionGridIntCamSizes[it-1] == 2)
                        {
                            tmpCam2 = 492;
                            tmpRect.width = 514;
                            tmpRect.height = 594;
                        }

                        bool overlap = false;
                        for (int ig = 1; ig < 6; ig++)
                        {
                            if (ig != it)
                            {
                                if (mGUI_containers[ig].expanded)
                                {
                                    if (RectsOverap(tmpRect, mGUI_containers[ig].position))
                                    {
                                        overlap = true;
                                    }
                                }
                                else
                                {
                                    if (RectsOverap(tmpRect, mGUI_containers[ig].position_not_expanded))
                                    {
                                        overlap = true;
                                    }
                                }
                            }
                        }

                        if (!overlap)
                        {
                            Rect tmpRec = new Rect(0, 0, tmpCam2, tmpCam2);
                            GUILayout.Label(mMiniCameras[it-1], GUILayout.Width(tmpCam2), GUILayout.Height(tmpCam2));
                            if (Event.current.type == EventType.Repaint)
                            {
                                tmpRec = GUILayoutUtility.GetLastRect();
                            }
                            else
                            {
                                tmpRec = new Rect(0, 0, 0, 0);
                            }
                            Graphics.DrawTexture(tmpRec, mMiniCameras[it-1], mMiniCameraRTMaterial);
                            mGUI_containers[it].position.width = tmpRect.width;
                            mGUI_containers[it].position.height = tmpRect.height;
                        }
                        else
                        {
                            mSelectionGridIntCamSizes[it-1] = tmpSelection;
                            GUILayout.Label(mMiniCameras[it-1], GUILayout.Width(tmpCam), GUILayout.Height(tmpCam));
                        }

                        mSelectionGridIntCamViews[it-1] = GUILayout.SelectionGrid(mSelectionGridIntCamViews[it-1], mSelectionStringsCamViews, 4);
                        mGUI_containers[it].target = mSelectionGridIntCamViews[it-1]+1;
                    }

                GUILayout.EndVertical();
            GUILayout.EndArea();
        }

        // Tool tip for GUI elements.
        Vector2 mousePosition = Input.mousePosition;
        if (GUI.tooltip != "")
            GUI.Label(new Rect(mousePosition.x, (Screen.height-mousePosition.y), 100, 40), GUI.tooltip, mSkinToApply.customStyles[0]);

        // GUI elements dragging logic.
        for (int j = 1; j < 6; j++)
        {
            if (mGUI_containers[j].expanded)
            {
                if (mCurrentlyDragging == -1 && Event.current.type == EventType.MouseDown && PointIsWithinRect( Event.current.mousePosition, mGUI_containers[j].position) )
                {
                    mCurrentlyDragging = j;
                    mDragOffset.x = Event.current.mousePosition.x - mGUI_containers[j].position.x;
                    mDragOffset.y = Event.current.mousePosition.y - mGUI_containers[j].position.y;
                }
                else if( Event.current.type == EventType.MouseDrag && mCurrentlyDragging == j)
                {
                    mCurrentlyDragged = new Rect( Event.current.mousePosition.x - mDragOffset.x, Event.current.mousePosition.y - mDragOffset.y,
                        mGUI_containers[j].position.width, mGUI_containers[j].position.height );

                    bool overlap = false;
                    for (int ia = 1; ia < 6; ia++)
                    {
                        if (ia != j)
                        {

                            if (mGUI_containers[ia].expanded)
                            {
                                if (RectsOverap(mCurrentlyDragged, mGUI_containers[ia].position))
                                {
                                    overlap = true;
                                }
                            }
                            else
                            {
                                if (RectsOverap(mCurrentlyDragged, mGUI_containers[ia].position_not_expanded))
                                {
                                    overlap = true;
                                }
                            }
                        }
                    }

                    if (!overlap)
                    {
                        mGUI_containers[j].position = mCurrentlyDragged;
                        mGUI_containers[j].position_not_expanded.x = mGUI_containers[j].position.x;
                        mGUI_containers[j].position_not_expanded.y = mGUI_containers[j].position.y;;
                    }
                }
                else if( Event.current.type == EventType.MouseUp )
                {
                    mCurrentlyDragging = -1;
                }
            }
            else
            {
                if (mCurrentlyDragging == -1 && Event.current.type == EventType.MouseDown && PointIsWithinRect( Event.current.mousePosition, mGUI_containers[j].position_not_expanded) )
                {
                    mCurrentlyDragging = j;
                    mDragOffset.x = Event.current.mousePosition.x - mGUI_containers[j].position_not_expanded.x;
                    mDragOffset.y = Event.current.mousePosition.y - mGUI_containers[j].position_not_expanded.y;
                }
                else if( Event.current.type == EventType.MouseDrag && mCurrentlyDragging == j)
                {
                    mCurrentlyDragged = new Rect( Event.current.mousePosition.x - mDragOffset.x, Event.current.mousePosition.y - mDragOffset.y,
                        mGUI_containers[j].position_not_expanded.width, mGUI_containers[j].position_not_expanded.height );

                    bool overlap = false;
                    for (int iu = 1; iu < 6; iu++)
                    {
                        if (iu != j)
                        {

                            if (mGUI_containers[iu].expanded)
                            {
                                if (RectsOverap(mCurrentlyDragged, mGUI_containers[iu].position))
                                {
                                    overlap = true;
                                }
                            }
                            else
                            {
                                if (RectsOverap(mCurrentlyDragged, mGUI_containers[iu].position_not_expanded))
                                {
                                    overlap = true;
                                }
                            }
                        }
                    }

                    if (!overlap)
                    {
                        mGUI_containers[j].position_not_expanded = mCurrentlyDragged;
                        mGUI_containers[j].position.x = mGUI_containers[j].position_not_expanded.x;
                        mGUI_containers[j].position.y = mGUI_containers[j].position_not_expanded.y;
                    }
                }
                else if( Event.current.type == EventType.MouseUp )
                {
                    mCurrentlyDragging = -1;
                }

            }
        }

        // Display markers for NPC game objects.
        for (int iw = 0; iw < mSimulationController.numberOfnpcs; iw++)
        {
            if (mSimulationController.npcs[iw].active)
            {
                Vector3 worldPoint = mSimulationController.npcs[iw].transform.position;

          				if (Vector3.Dot(Camera.main.transform.forward, worldPoint-Camera.main.transform.position) >= 0){
                    Vector3 screenPoint = GetComponent<Camera>().WorldToScreenPoint(worldPoint);
                    Rect lTmpRect = new Rect(0, 0, Screen.width, Screen.height);
                    if (lTmpRect.Contains(screenPoint))
                    {
                        bool overlap = false;
                        Rect lLabelAreaLogo = new Rect(screenPoint.x, Screen.height-screenPoint.y, 20, 20);
                        Rect lLabelAreaTag = new Rect(screenPoint.x+20, Screen.height-screenPoint.y, 100, 20);

                        for (int l = 1; l < 6; l++)
                        {
                            if (mGUI_containers[l].expanded)
                            {
                                if (RectsOverap(lLabelAreaLogo, mGUI_containers[l].position) || RectsOverap(lLabelAreaTag, mGUI_containers[l].position))
                                {
                                    overlap = true;
                                }
                            }
                            else
                            {
                                if (RectsOverap(lLabelAreaLogo, mGUI_containers[l].position_not_expanded)|| RectsOverap(lLabelAreaTag, mGUI_containers[l].position_not_expanded))
                                {
                                    overlap = true;
                                }
                            }
                        }

                        if (!overlap)
                        {
                            GUI.Box(lLabelAreaLogo, mNPCmarkers[iw], GUI.skin.button);
                            GUI.Label(lLabelAreaTag, mSimulationController.npcs[iw].tag, GUI.skin.label);//, mNPCmarkers[iw]));
                        }
                    }
                  }

            }
        }

        // React to changed simulation type.
        if (mCurrentSimulationTypeChanged)
        {
            // Update the AI behavior dropdown list on the basis of the new simulation type
            switch (mSimulationController.currentSimulationCategory)
            {
                case SIMULATION.KINEMATIC_MOVEMENT:
                    mSelectionStringsAIBehavior = new string[System.Enum.GetValues( typeof( KINEMATIC_MOVEMENT ) ).Length];
                    for (int ic = 0; ic < mSelectionStringsAIBehavior.Length; ic++)
                    {
                        mSelectionStringsAIBehavior[ic] = ((KINEMATIC_MOVEMENT) ic).ToString();
                    }
                    break;
                case SIMULATION.STEERING_BEHAVIOR:
                    mSelectionStringsAIBehavior = new string[System.Enum.GetValues( typeof( STEERING_BEHAVIOR ) ).Length];
                    for (int iv = 0; iv < mSelectionStringsAIBehavior.Length; iv++)
                    {
                        mSelectionStringsAIBehavior[iv] = ((STEERING_BEHAVIOR) iv).ToString();
                    }
                    break;
            }

            // Set situation to "no changes have occurred".
            mCurrentSimulationTypeChanged = false;
        }

        // React to changed AI behavior
        if (mCurrentAIBehaviourChanged == true)
        {
            // Set current action of each NPC to the selected AI action.
            for (int im = 0; im < mSimulationController.numberOfnpcs; im++) {

                GameObject tmpNPC = GameObject.FindWithTag("theNPC" + im);

                if (tmpNPC != null)
                {

                    mNPCController = tmpNPC.GetComponent<cNPCController>();

                    mSimulationController.currentSimulationSpeed = (int) mCurrentSpeed;
                }

            }

            // Set situation to "no changes have occurred".
            mCurrentAIBehaviourChanged = false;
        }
    }
Ejemplo n.º 2
0
    /// <summary>
    /// Update called in every frame.
    /// </summary>
    void Update()
    {
        // Find the simulation controller script and extract Boid data.
        mSimulationController = GameObject.FindWithTag("MainCamera").GetComponent<cSimulationController>();
        mNumberOfBoids = mSimulationController.numberOfnpcs;
        mBoids = mSimulationController.npcs;

        // For each memebr of the flock...
        for (int i = 0; i < mNumberOfBoids; i++)
        {
            // Start calculating the flocking factors from reset values.
            ResetFlockingFactors();

            // For each member preceding the current one...
            for (int j = i+1; j < mNumberOfBoids; j++)
            {
                // If the members are near enough of each other, update the flocking factors and neighbour count.
                if (AreNeighbours(mBoids[i], mBoids[j]))
                {
                    NeighboursCount++;

                    CumulateCohesion(j);
                    CumulateAlignment(j);
                    CumulateSeparation(j);
                }
            }

            // For each member succeeding the current one...
            for (int j = 0; j < i; j++)
            {
                // If the member are near enough of each other, update the flocking factors and neighbour count
                if (AreNeighbours(mBoids[i], mBoids[j]))
                {
                    NeighboursCount++;

                    CumulateCohesion(j);
                    CumulateAlignment(j);
                    CumulateSeparation(j);
                }
            }

            // resolve the final flocking factors.
            ResolveCohesion(i);
            ResolveAlignment(i);
            ResolveSeparation(i);

            // Set suggestive directional force and forward direction of the current member.
            Vector3 lNewDirectionalForce = Vector3.zero;

            // Calculate new directional force to apply based on cohesion and separation.
            mCohesionFactor -= mBoids[i].transform.position;
            mSeparationFactor -= mBoids[i].transform.position;
            cNPCController lTmpScript = mBoids[i].GetComponent<cNPCController>();
            if (mCohesionFactor != Vector3.zero || mSeparationFactor != Vector3.zero)
            {
                lNewDirectionalForce = ((lTmpScript.mFlockingData.mCohesionWeight/100.0f*mCohesionFactor) + (lTmpScript.mFlockingData.mSeparationWeight/100.0f*mSeparationFactor))/2;// + (mSeparationFactor);

            }

            // Set new forward direction to apply based on the alignment factor.
            Vector3 lNewForwardDirection = mAlignmentFactor;

            // If there are leaders set for a flock to follow ...
            if (mSimulationController.flockingLeadersCount > 0)
            {
                bool LeaderFound = false;
                int j = 0;

                // Find a leader ...
                while (!LeaderFound && j < mNumberOfBoids)
                {
                    if (i != j)
                    {
                        mNPCController = GameObject.FindWithTag("theNPC" + j).GetComponent<cNPCController>();
                        if (mNPCController.mFlockingData.mRole == FLOCK_ROLE.leader)
                        {
                            // If the members are near enough of each other, update the flocking factors and neighbour count.
                            if (AreNeighbours(mBoids[i], mBoids[j]))
                            {
                                LeaderFound = true;
                                lNewDirectionalForce += (mNPCController.mKinematicData.mPosition[mNPCController.mKinematicData.mPosition.Count-1]-mBoids[i].transform.position)*10;
                            }
                        }
                    }
                    j++;
                }
            }

            // Update boid velocity and facing
            lTmpScript.mFlockingData.mBoidVelocity = lNewDirectionalForce;
            lTmpScript.mFlockingData.mBoidFacing = lNewForwardDirection;

            NeighboursCount = 0;
        }
    }