Пример #1
0
        // In this function we actually move each assigned unit of a grid point towards that moving (in most cases) grid point
        // We use the Rigidbody velocity and the velocity is calculated based on the distance from the unit to the grid point.
        public void MoveUnitsRigidBodyMode(int gridPointIndex, FormationGridPoint fgp, Vector3 vlcity, float endReachedDistance)
        {
            Rigidbody rigidbody = fgp.GetRigidbody();

            if (!rigidbody)
            {
                Debug.LogError("FormationGrid.MoveUnitsRigidBodyMode(): Rigidbody missing on assigned unit.");
            }


            Vector3 acceleration = fgp.GetPosition() - fgp.GetAssignedUnit().transform.position;

            acceleration.y = 0;
            acceleration.Normalize();
            acceleration *= maximumAcceleration;

            //DebugPanel.Log("Acceleration "+gridPointIndex, "Rigidbody", acceleration.magnitude);

            rigidbody.velocity += acceleration * Time.deltaTime;

            if (rigidbody.velocity.magnitude > maximumVelocity)
            {
                rigidbody.velocity = rigidbody.velocity.normalized * maximumVelocity;
            }

            //DebugPanel.Log("Rgb velocity "+gridPointIndex, "Rigidbody", rigidbody.velocity.magnitude);

            fgp.SetAssignedVelocity(rigidbody.velocity);
        }
Пример #2
0
        // In this function we actually move each assigned unit of a grid point towards that moving (in most cases) grid point
        // We use the Move function of the CharacterController and the motion is calculated based on the distance from the unit to the grid point.
        public void MoveUnitsCharacterControllerMode(int gridPointIndex, FormationGridPoint fgp, Vector3 vlcity, float endReachedDistance)
        {
            CharacterController controller = fgp.GetCharacterController();

            if (!controller)
            {
                Debug.LogError("FormationGrid.MoveUnitsCharacterControllerMode(): Character Controller missing on assigned unit.");
            }

            float distanceToGridPoint = fgp.CalculateDistanceUnitToGridPoint();

            //if (gridPointIndex == 0) DebugPanel.Log("GridPoint [" + gridPointIndex + "] unittogrid", "Grid", distanceToGridPoint);

            // default acceleration multiplier
            float acceleration = 1.0F;

            if (distanceToGridPoint > endReachedDistance * 5)
            {
                // takeover
                acceleration = accelerationStraggler;
            }
            else if ((distanceToGridPoint > endReachedDistance) && ((distanceToGridPoint < endReachedDistance * 5)))
            {
                // slowdown
                float slope     = 1 / (4 * endReachedDistance);         //      1 / ((5-1) * endReachedDistance)
                float intercept = -1 * (slope * endReachedDistance);    //

                acceleration = slope * distanceToGridPoint + intercept; //      a = 0 at endReachedDistance and a = 1 at 5*endReachedDistance

                //acceleration = distanceToGridPoint / 0.5F;
            }
            else if (distanceToGridPoint < endReachedDistance)
            {
                acceleration = 0.0f;
            }

            //if (gridPointIndex == 0) DebugPanel.Log("GridPoint [" + gridPointIndex + "] acceleration", "Grid", acceleration);

            Vector3 direction    = fgp.GetPosition() - fgp.GetAssignedUnit().transform.position;
            Vector3 fgp_velocity = direction * acceleration;


            if (useGravity)
            {
                // Use gravity and calculate vertical velocity down
                float vSpeed = fgp.GetUnitVerticalSpeed();
                if (controller.isGrounded)
                {
                    vSpeed = 0;
                }
                vSpeed -= gravity * Time.deltaTime;
                fgp.SetUnitVerticalSpeed(vSpeed);
                fgp_velocity.y = vSpeed;
            }


            controller.Move(fgp_velocity * Time.deltaTime);

            fgp.SetAssignedVelocity(fgp_velocity);
        }
Пример #3
0
        // If we use Rigidbody we need to assign the velocities in FixedUpdate()
        private void FixedUpdate()
        {
            if (anchor == null)
            {
                return;
            }

            if (movementType == MovementType.CharacterController)
            {
                return;                 // Oops for some reason we ended up here. Should never happen.
            }

            if (state == FormationStates.Move)
            {
                if (formationAnchor != null)
                {
                    float   endReachedDistance = formationAnchor.endReachedDistance;
                    Vector3 vlcity             = formationAnchor.GetVelocity();

                    //DebugPanel.Log("Anchor velocity", "Anchor", vlcity.magnitude);


                    for (int i = 0; i < gridPoints.Count; i++)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        if (fgp != null)
                        {
                            if (fgp.IsUnitAssigned())
                            {
                                switch (movementType)
                                {
                                case MovementType.RigidBody:
                                    MoveUnitsRigidBodyMode(i, fgp, vlcity, endReachedDistance);
                                    break;

                                case MovementType.CharacterController:
                                    //MoveUnitsCharacterControllerMode(i, fgp, vlcity, endReachedDistance);
                                    break;

                                default:
                                    Debug.LogError("FormationGrid.Update(): Unknown movementType");
                                    break;
                                }


                                FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation();
                                if (formationUnitAnimation)
                                {
                                    formationUnitAnimation.velocity = fgp.GetAssignedVelocity();
                                    //DebugPanel.Log("FUA.velocity", "Unit Animation", fgp.GetAssignedVelocity());
                                }
                            }
                        }

                        oldPosition = anchorPosition;
                        oldRotation = transform.rotation.eulerAngles.y;
                    }
                }
            }
        }
Пример #4
0
        // Change the movement state of the units assigned to a grid point:
        // False = stop moving
        // True = start moving
        public void ChangeMoveStateOnGridObjects(bool state)
        {
            for (int i = 0; i < gridPoints.Count; i++)
            {
                FormationGridPoint fgp = gridPoints[i];
                GameObject         go  = fgp.GetAssignedUnit();

                if (go)
                {
#if T7T_ASTAR
                    AIPath aip = go.GetComponent <AIPath>();
                    if (aip)
                    {
                        aip.target    = fgp.GetTransform();
                        aip.canSearch = state;
                        aip.canMove   = state;
                    }
                    else
                    {
                        Debug.LogError("FormationGrid.EnableMoveOnGridObjects(): no assigned unit found for gridpoint.");
                    }
#else
                    NavMeshAgent nma = go.GetComponent <NavMeshAgent>();
                    if (nma)
                    {
                        if (state)
                        {
                            nma.destination = fgp.GetPosition();
                            nma.Resume();
                        }
                        else
                        {
                            nma.Stop();
                            Rigidbody rigidbody = fgp.GetRigidbody();
                            if (rigidbody)
                            {
                                rigidbody.velocity = Vector3.zero;
                            }
                        }
                    }
                    else
                    {
                        Debug.LogError("FormationGrid.EnableMoveOnGridObjects(): no nav mesh agent found for assigned unit.");
                    }
#endif
                }
            }
        }
Пример #5
0
        // Calculate grid positions in the real world taking the grid/anchor position and rotation into account
        public void CalculatePositionsAllGridPoints()
        {
            if (gridPoints == null)
            {
                return;
            }

            float   rotationY = transform.rotation.eulerAngles.y;
            Vector3 position  = transform.position;

            for (int i = 0; i < gridPoints.Count; i++)
            {
                FormationGridPoint fgp = gridPoints[i];

                fgp.SetPosition(position, rotationY, gridScale, mask);

                fgp.VisualizeGridPoint(visualizeGrid);
            }
        }
Пример #6
0
        // Change the animation state of each unit assigned to a grid point:
        // False = go to Idle state
        // True = go to movement state
        public void ChangeAnimationStateOnGridObjects(bool state)
        {
            for (int i = 0; i < gridPoints.Count; i++)
            {
                FormationGridPoint fgp = gridPoints[i];
                GameObject         go  = fgp.GetAssignedUnit();

                if (go)
                {
                    FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation();
                    if (formationUnitAnimation)
                    {
                        if (state)
                        {
                            formationUnitAnimation.StartAnimations();
                        }
                        else
                        {
                            formationUnitAnimation.StopAnimations();
                        }
                    }
                }
            }
        }
Пример #7
0
        // Assign the objects in a list to the FormationGridPoint(s) in the gridPoints list
        public bool AssignObjectsToGrid(List <GameObject> list)
        {
            bool result = true;

            if (list.Count > gridPoints.Count)
            {
                Debug.LogWarning("FormationGrid.AssignObjectsToGrid(): too many objects for this grid.");
                result = false;
            }

            for (int i = 0; i < list.Count; i++)
            {
                if (i < gridPoints.Count)
                {
                    GameObject go = list[i];

                    // Now check if the required components are available so we can move the objects
                    if (movementType == MovementType.CharacterController)
                    {
                        CharacterController cc = go.GetComponent <CharacterController>();
                        if (!cc)
                        {
                            Debug.LogError("FormationGrid.AssignObjectsToGrid(): GameObject to be assigned does not have the required CharacterController for this movement type.");
                        }
                    }
                    else if (movementType == MovementType.RigidBody)
                    {
                        Rigidbody rb = go.GetComponent <Rigidbody>();
                        if (!rb)
                        {
                            Debug.LogError("FormationGrid.AssignObjectsToGrid(): GameObject to be assigned does not have the required RigidBody for this movement type.");
                        }
                    }



#if T7T_ASTAR
                    AIPath aip = go.GetComponent <AIPath>();
                    if (aip)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        fgp.AssignUnit(go);

                        aip.target  = fgp.GetTransform();
                        aip.canMove = true;

                        Debug.Log("FormationGrid.AssignObjectsToGrid(): Assigned new target to object " + go.transform.name);
                    }
                    else
                    {
                        Debug.LogWarning("FormationGrid.AssignObjectsToGrid(): Assigned Object [" + go.transform.name + "] has no AIPath component.");
                        result = false;
                    }
#else
                    NavMeshAgent nma = go.GetComponent <NavMeshAgent>();
                    if (nma)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        fgp.AssignUnit(go);

                        nma.destination = fgp.GetPosition();

                        Debug.Log("FormationGrid.AssignObjectsToGrid(): Assigned new target to object " + go.transform.name);
                    }
                    else
                    {
                        Debug.LogWarning("FormationGrid.AssignObjectsToGrid(): Assigned Object [" + go.transform.name + "] has no Navmesh component.");
                        result = false;
                    }
#endif
                }
            }

            return(result);
        }
Пример #8
0
        // Setup the grid based on static offsets contained in the function.
        // TODO: replace these static definitions by JSON files loaded from the project.
        public bool SetupGrid(GridTypes gridtype)
        {
            gridPoints.Clear();

            Vector2[] grid;

            switch (gridtype)
            {
            case GridTypes.Box9:
                grid    = new Vector2[9];
                grid[0] = new Vector2(1.0f, 1.5f);
                grid[1] = new Vector2(0.0f, 1.5f);
                grid[2] = new Vector2(-1.0f, 1.5f);

                grid[3] = new Vector2(1.0f, 0.5f);
                grid[4] = new Vector2(0.0f, 0.5f);
                grid[5] = new Vector2(-1.0f, 0.5f);

                grid[6] = new Vector2(1.0f, -0.5f);
                grid[7] = new Vector2(0.0f, -0.5f);
                grid[8] = new Vector2(-1.0f, -0.5f);
                break;

            case GridTypes.Wedge9:
                grid    = new Vector2[9];
                grid[0] = new Vector2(0.0f, 2.0f);
                grid[1] = new Vector2(0.5f, 1.0f);
                grid[2] = new Vector2(-0.5f, 1.0f);

                grid[3] = new Vector2(1.0f, 0.0f);
                grid[4] = new Vector2(-1.0f, 0.0f);

                grid[5] = new Vector2(1.5f, -1.0f);
                grid[6] = new Vector2(-1.5f, -1.0f);

                grid[7] = new Vector2(2.0f, -2.0f);
                grid[8] = new Vector2(-2.0f, -2.0f);
                break;

            case GridTypes.Column10:
                grid    = new Vector2[10];
                grid[0] = new Vector2(0.0f, -0.5f);
                grid[1] = new Vector2(0.0f, -1.5f);
                grid[2] = new Vector2(0.0f, -2.5f);
                grid[3] = new Vector2(0.0f, -3.5f);
                grid[4] = new Vector2(0.0f, -4.5f);
                grid[5] = new Vector2(0.0f, -5.5f);
                grid[6] = new Vector2(0.0f, -6.5f);
                grid[7] = new Vector2(0.0f, -7.5f);
                grid[8] = new Vector2(0.0f, -8.5f);
                grid[9] = new Vector2(0.0f, -9.5f);
                break;

            default:
                grid    = new Vector2[1];
                grid[0] = new Vector2(0.0f, 0.0f);
                Debug.LogError("FormationGrid.SetupGrid(): no grid type selected");
                break;
            }

            if (!formation)
            {
                formation = transform.gameObject;
            }


            for (int i = 0; i < grid.GetLength(0); i++)
            {
                FormationGridPoint fgp = new FormationGridPoint(i, formation, randomizeOffset);              // DKE: fixed missing id number.
                fgp.offsetX = grid[i].x;
                fgp.offsetZ = grid[i].y;
                gridPoints.Add(fgp);
            }

            return(true);
        }
Пример #9
0
        // Update is called once per frame
        void Update()
        {
            if (anchor == null)
            {
                return;
            }

            if (state == FormationStates.Form)
            {
                for (int i = 0; i < gridPoints.Count; i++)
                {
                    FormationGridPoint fgp = gridPoints[i];
                    if (fgp != null)
                    {
                        if (fgp.IsUnitAssigned())
                        {
                            FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation();
                            if (formationUnitAnimation)
                            {
                                GameObject go = fgp.GetAssignedUnit();
                                if (go)
                                {
#if T7T_ASTAR
                                    AIPath aip = go.GetComponent <AIPath>();
                                    formationUnitAnimation.velocity = aip.CalculateVelocity(Vector3.zero); // obselete but velocity property is not available.
#else
                                    NavMeshAgent nma = go.GetComponent <NavMeshAgent>();
                                    formationUnitAnimation.velocity = nma.velocity;
#endif
                                }
                            }
                        }
                    }
                }
            }

            if (state == FormationStates.Move)
            {
                if ((oldPosition - anchorPosition).sqrMagnitude > 0.001f * 0.001f)  // TODO: potentially we can do this by checking if target has been reached
                {
                    positionDirty = true;
                }
                else
                {
                    positionDirty = false;
                }

                if (Mathf.Abs(anchorRotation.eulerAngles.y - oldRotation) > 0.01f)
                {
                    rotationDirty = true;
                }
                else
                {
                    rotationDirty = false;
                }

                Quaternion target = anchorRotation;
                if (rotationDirty)
                {
                    transform.rotation = Quaternion.Slerp(transform.rotation, target, Time.deltaTime * smoothRotation);
                }

                // Rotate the units at grid points to align with anchor rotation:
                // TODO: can we check when not to run this by means of "fully rotated" units?
                if (formationAnchor != null)
                {
                    // Vector3 velocity = formationAnchor.GetVelocity();

                    for (int i = 0; i < gridPoints.Count; i++)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        if (fgp != null)
                        {
                            if (fgp.IsUnitAssigned())
                            {
                                GameObject au = fgp.GetAssignedUnit();

                                au.transform.rotation = Quaternion.Slerp(au.transform.rotation, target, Time.deltaTime * smoothRotation);
                            }
                        }
                    }
                }



                if (positionDirty)
                {
                    transform.position = anchorPosition;    // Move the Formation to Anchor position. TODO: If dampening needed, do Lerp here.

                    if (randomizeOffset > 0.0F)
                    {                                       // Randomize the positions slightly if enabled
                        reRandomizeOffsets += Time.deltaTime;

                        if (reRandomizeOffsets > reRandomizeNextTime)      // ReRandomize the gridpoints every 3 seconds
                        {
                            reRandomizeOffsets  = 0.0F;
                            reRandomizeNextTime = reRandomizeTimeMin + (reRandomizeTimeMax - reRandomizeTimeMin) * Random.value;

                            for (int i = 0; i < gridPoints.Count; i++)
                            {
                                FormationGridPoint fgp = gridPoints[i];
                                fgp.RandomizePosition();
                            }
                        }
                    }

                    CalculatePositionsAllGridPoints();      // Calculate all Grid Points relative to the Anchor which has moved by means of A*Pathfinfing.
                }



                // Now move the units (assigned to grid positions) towards their grid position:

                // TODO: Add a check here to stop if all units have arrived.

                if (formationAnchor != null)
                {
                    float   endReachedDistance = formationAnchor.endReachedDistance;
                    Vector3 vlcity             = formationAnchor.GetVelocity();

                    //DebugPanel.Log("Anchor velocity", "Anchor", vlcity.magnitude);


                    for (int i = 0; i < gridPoints.Count; i++)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        if (fgp != null)
                        {
                            if (fgp.IsUnitAssigned())
                            {
                                switch (movementType)
                                {
                                case MovementType.RigidBody:
                                    // Do nothing since in case of rigidbody we use FixedUpdate() instead of Update()
                                    //MoveUnitsRigidBodyMode(i, fgp, vlcity, endReachedDistance);
                                    break;

                                case MovementType.CharacterController:
                                    MoveUnitsCharacterControllerMode(i, fgp, vlcity, endReachedDistance);
                                    break;

                                default:
                                    Debug.LogError("FormationGrid.Update(): Unknown movementType");
                                    break;
                                }


                                FormationUnitAnimation formationUnitAnimation = fgp.GetFormationUnitAnimation();
                                if (formationUnitAnimation)
                                {
                                    formationUnitAnimation.velocity = fgp.GetAssignedVelocity();
                                    //DebugPanel.Log("FUA.velocity", "Unit Animation", fgp.GetAssignedVelocity());
                                }
                            }
                        }

                        oldPosition = anchorPosition;
                        oldRotation = transform.rotation.eulerAngles.y;
                    }
                }
            }

            if (state == FormationStates.Disband)
            {
                if (disbandTimer == 0.0f)
                {
                    // set the directions for each assigned unit
                    for (int i = 0; i < gridPoints.Count; i++)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        if (fgp != null)
                        {
                            if (fgp.IsUnitAssigned())
                            {
                                fgp.SetDisbandDesitination(disbandRadius, mask);
                                fgp.SetPositionToDisband(mask);
                            }
                        }
                    }
                    ChangeMoveStateOnGridObjects(true);
                    disbanded = false;
                }


                // start a timer, for x seconds have the assigned units move into a random direction
                disbandTimer += Time.deltaTime;
                if (disbandTimer < disbandDuration)
                {
                    // Move them

                    //DebugPanel.Log("disbandtimer", "disband", disbandTimer);
                }
                else
                {
                    if (!disbanded)
                    {
                        ChangeMoveStateOnGridObjects(false);
                        ChangeAnimationStateOnGridObjects(false);
                        disbanded = true;
                    }
                }
            }
        }
Пример #10
0
        /* Change the grid to a new type:
         *      If the grid already has existing FormationGridPoints then
         *          Collect the assigned units
         *          Destroy the spheres in the FormationGridPoints to cleanup memory
         *      Clear the grid points list
         *      Setup the new grid points list
         *      Setup the new grid
         *          Assign the previously assigned units to the FormationGridPoints
         *      Calculate the new positions
         */

        public void ChangeGridTo(GridTypes gridtype)
        {
            gridType = gridtype;

            // Create the list for collecting the already assigned units
            List <GameObject> units = new List <GameObject>();

            Debug.Log("FormationGrid.ChangeGridTo(): change state to " + gridType);


            if (gridPoints != null)
            {
                if (gridPoints.Count > 0)
                {
                    // collect units assigned to gridpoint so we can reassign automatically after grid change

                    Debug.Log("FormationGrid.ChangeGridTo(): grid exists so check if it has assigned units");

                    for (int i = 0; i < gridPoints.Count; i++)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        GameObject         go  = fgp.GetAssignedUnit();
                        if (go)
                        {
                            units.Add(go);
                            Debug.Log("FormationGrid.ChangeGridTo(): found one unit " + go.name);
                        }
                    }

                    // destroy list items first: cleanup the spheres
                    for (int i = 0; i < gridPoints.Count; i++)
                    {
                        FormationGridPoint fgp = gridPoints[i];
                        fgp.DestroySphere();
                    }
                }
                gridPoints.Clear();
            }

            // Create a new list to completely start a new grid from scratch.
            gridPoints = new List <FormationGridPoint>();
            if (gridPoints == null)
            {
                Debug.LogError("FormationGrid.ChangeGridTo(): gridPoints not initialized");
                return;
            }

            // Setup the new grid for the new gridtype
            bool result = SetupGrid(gridtype);

            // Now add the units we has assigned to the previous grid
            if (units.Count > 0)
            {
                AssignObjectsToGrid(units);
            }

            // Calculate the real positions of the grid based on the offsets in the grid definition
            CalculatePositionsAllGridPoints();

            Debug.Log("FormationGrid.ChangeGridTo(): result SetupGrid()=" + result);
        }