Ejemplo n.º 1
0
    private void Update()
    {
        if (Time.time > changeDirectiontime)
        {
            changeDirectiontime = Time.time + Random.Range(10.0f, 20.0f);

            float rotationAngleInDeg = Random.Range(-90.0f, 90.0f);
            windDirection = AIHelperFunctions.GetRotatedVector(windDirection, rotationAngleInDeg * degToRad);
            arrow.transform.eulerAngles = new Vector3(0, Vector3.SignedAngle(Vector3.forward, windDirection, Vector3.up), 0);;
        }
    }
Ejemplo n.º 2
0
    // STATE end -----------------------------------------------

    // STATE start ---------------------------------------------
    void state_MoveRandomly()
    {
        if (obstacle1)
        {
            activeState = state_AvoidingObstacle;
            return;
        }

        if (enemyShip)
        {
            Vector3 playerShipDirection = enemyShip.transform.forward;
            playerShipDirection.y = 0;

            Vector3 ourShipDirection = transform.forward;
            ourShipDirection.y = 0;

            float angleBetweenPlayerShipDirectionAndOurShipDirection = Vector3.Angle(playerShipDirection, ourShipDirection);
            if (angleBetweenPlayerShipDirectionAndOurShipDirection > 90)
            {
                angleBetweenPlayerShipDirectionAndOurShipDirection = 180 - angleBetweenPlayerShipDirectionAndOurShipDirection;
            }

            if ((angleBetweenPlayerShipDirectionAndOurShipDirection <= 5) &&
                (AIHelperFunctions.GetDistanceBetweenPerpendicular(this.gameObject, enemyShip) <= 3))
            {
                activeState = state_Battle;
                return;
            }
        }

        //change ship direction periodically
        if (Time.time > changeDirectionTime)
        {
            changeDirectionTime = Time.time + RandomPeriodOfTime();
            float currentShipToWindAngle = angleBetweenShipAndWind.GetCurrentShipToWindAngle();
            float angle = Random.Range(-45.0f, 45.0f);

            Vector3 rotatedVector;
            if (currentShipToWindAngle - angle > 150)
            {
                rotatedVector = AIHelperFunctions.GetRotatedVector(windArea.windDirection, -150 * Mathf.Deg2Rad);
            }
            else if (currentShipToWindAngle - angle < -150)
            {
                rotatedVector = AIHelperFunctions.GetRotatedVector(windArea.windDirection, 150 * Mathf.Deg2Rad);
            }
            else
            {
                rotatedVector = AIHelperFunctions.GetRotatedVector(transform.forward, angle * Mathf.Deg2Rad);
            }

            enemyBoatController.SetNewShipDirection(rotatedVector);
        }
    }
Ejemplo n.º 3
0
    // STATE end -----------------------------------------------

    // STATE start ---------------------------------------------
    void state_GoToLastKnownPlayerShipPosition()
    {
        // START of checking the state change conditions ---------------------
        if (obstacle1)
        {
            activeState = state_AvoidObstacles;
            return;
        }

        if (playerShip)
        {
            lostPlayerLastKnownPosition = doesNotExist;
            activeState = state_GoToPlayerShip;
            return;
        }

        Vector3 towardsLostPlayerLastKnownPositionDirection = lostPlayerLastKnownPosition - transform.position;

        towardsLostPlayerLastKnownPositionDirection.y = 0;

        // if player not found near lostPlayerLastKnownPosition
        if (towardsLostPlayerLastKnownPositionDirection.magnitude < 20)
        {
            lostPlayerLastKnownPosition = doesNotExist;
            activeState = state_PlayerSearch;
            return;
        }
        // END of checking the state change conditions---------------

        Debug.DrawLine(transform.position, lostPlayerLastKnownPosition, Color.magenta, 0.0f, true);

        // float angleBetweenOurShipDirectionAndTowardsLostPlayerLastKnownPositionDirection =
        //   Vector3.SignedAngle(ourShipDirection, towardsLostPlayerLastKnownPositionDirection, Vector3.up);

        // Taking wind into account
        float angleBetweenTowardsLostPlayerLastKnownPositionDirectionAndWindDirection =
            Vector3.SignedAngle(towardsLostPlayerLastKnownPositionDirection, windArea.windDirection, Vector3.up);

        if (angleBetweenTowardsLostPlayerLastKnownPositionDirectionAndWindDirection > 150)
        {
            towardsLostPlayerLastKnownPositionDirection = AIHelperFunctions.GetRotatedVector(windArea.windDirection, -150 * Mathf.Deg2Rad);
        }
        else if (angleBetweenTowardsLostPlayerLastKnownPositionDirectionAndWindDirection < -150)
        {
            towardsLostPlayerLastKnownPositionDirection = AIHelperFunctions.GetRotatedVector(windArea.windDirection, 150 * Mathf.Deg2Rad);
        }

        enemyBoatController.SetNewShipDirection(towardsLostPlayerLastKnownPositionDirection);
    }
Ejemplo n.º 4
0
    private void DetermineInWhichZoneIsOurShip()
    {
        distanceBetweenParallel = AIHelperFunctions.GetDistanceBetweenParallel(ourShip, playerShip);

        if (distanceBetweenParallel > maxDistBetweenParallel)
        {
            ourShipIsInParallelZone             = false;
            ourShipIsInZoneBetweenParallelZones = false;
        }
        else if (distanceBetweenParallel >= minDistBetweenParallel && distanceBetweenParallel <= maxDistBetweenParallel)
        {
            ourShipIsInParallelZone             = true;
            ourShipIsInZoneBetweenParallelZones = false;
        }
        else //distance < minDistBetweenParallel
        {
            ourShipIsInParallelZone             = false;
            ourShipIsInZoneBetweenParallelZones = true;
        }
    }
Ejemplo n.º 5
0
    // STATE end -----------------------------------------------

    // STATE start ---------------------------------------------
    void state_PlayerSearch()
    {
        if (obstacle1)
        {
            activeState = state_AvoidObstacles;
            return;
        }

        if (playerShip)
        {
            activeState = state_GoToPlayerShip;
            return;
        }

        //change ship direction periodically
        if (Time.time > changeDirectionTime)
        {
            changeDirectionTime = Time.time + RandomPeriodOfTime();
            float currentShipToWindAngle = angleBetweenShipAndWind.GetCurrentShipToWindAngle();
            float angle = Random.Range(-45.0f, 45.0f);

            Vector3 rotatedVector;
            if (currentShipToWindAngle - angle > 150)
            {
                rotatedVector = AIHelperFunctions.GetRotatedVector(windArea.windDirection, -150 * Mathf.Deg2Rad);
            }
            else if (currentShipToWindAngle - angle < -150)
            {
                rotatedVector = AIHelperFunctions.GetRotatedVector(windArea.windDirection, 150 * Mathf.Deg2Rad);
            }
            else
            {
                rotatedVector = AIHelperFunctions.GetRotatedVector(transform.forward, angle * Mathf.Deg2Rad);
            }

            enemyBoatController.SetNewShipDirection(rotatedVector);
        }
    }
Ejemplo n.º 6
0
    // =========================================================
    // FSM STATES
    // =========================================================

    // STATE start ---------------------------------------------
    void state_AvoidObstacles()
    {
        // START of checking the state change conditions ---------------------
        if (!obstacle1)
        {
            if (!playerShip)
            {
                ChangeStateTo_PlayerSearch_Or_GoToLastKnownPlayerShipPosition();
                return;
            }

            if (playerShip)
            {
                activeState = state_GoToPlayerShip;
                return;
            }
        }
        // END of checking the state change conditions---------------

        Vector3 ourShipDirection = transform.forward;

        ourShipDirection.y = 0;

        float angleInDegToAvoidObstacle;

        // if there is only one obstacle
        if (obstacle1 && !obstacle2)
        {
            angleInDegToAvoidObstacle = AIHelperFunctions.GetAngleInDegToAvoidObstacle(ourShip, obstacle1, windArea, additionalRandomAngle);
        }
        else // if there are two obstacles
        {
            float angleBetweenShortestShiptToObstacle1VectorAndShipDirection =
                AIHelperFunctions.GetAngleBetweenShortestShiptToObstacleVectorAndShipDirection(obstacle1, transform);
            float angleBetweenShortestShiptToObstacle2VectorAndShipDirection =
                AIHelperFunctions.GetAngleBetweenShortestShiptToObstacleVectorAndShipDirection(obstacle2, transform);

            if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection > 0 &&
                 angleBetweenShortestShiptToObstacle2VectorAndShipDirection < 0)
                ||
                (angleBetweenShortestShiptToObstacle1VectorAndShipDirection < 0 &&
                 angleBetweenShortestShiptToObstacle2VectorAndShipDirection > 0))
            {
                if (Mathf.Abs(angleBetweenShortestShiptToObstacle1VectorAndShipDirection) <
                    Mathf.Abs(angleBetweenShortestShiptToObstacle2VectorAndShipDirection))
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetGreaterAngleInDegToAvoidObstacle(ourShip, obstacle1, additionalRandomAngle);
                }
                else
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetGreaterAngleInDegToAvoidObstacle(ourShip, obstacle2, additionalRandomAngle);
                }
            }
            else if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection > 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection == 0)
                     ||
                     (angleBetweenShortestShiptToObstacle2VectorAndShipDirection > 0 &&
                      angleBetweenShortestShiptToObstacle1VectorAndShipDirection == 0))
            {
                angleInDegToAvoidObstacle = 90 + additionalRandomAngle;
            }
            else if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection < 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection == 0)
                     ||
                     (angleBetweenShortestShiptToObstacle2VectorAndShipDirection < 0 &&
                      angleBetweenShortestShiptToObstacle1VectorAndShipDirection == 0))
            {
                angleInDegToAvoidObstacle = -90 - additionalRandomAngle;
            }
            else if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection > 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection > 0)
                     ||
                     (angleBetweenShortestShiptToObstacle1VectorAndShipDirection < 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection < 0))
            {
                if (Mathf.Abs(angleBetweenShortestShiptToObstacle1VectorAndShipDirection) <
                    Mathf.Abs(angleBetweenShortestShiptToObstacle2VectorAndShipDirection))
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetAngleInDegToAvoidObstacle(ourShip, obstacle1, windArea, additionalRandomAngle);
                }
                else
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetAngleInDegToAvoidObstacle(ourShip, obstacle2, windArea, additionalRandomAngle);
                }
            }
            else //such situation should not exist!!!
            {
                angleInDegToAvoidObstacle = 0;
                Debug.Log("Such situation should not exist!!!");
            }
        }

        Vector3 rotatedVector = AIHelperFunctions.GetRotatedVector(ourShipDirection, angleInDegToAvoidObstacle * Mathf.Deg2Rad);

        enemyBoatController.SetNewShipDirection(rotatedVector);
    }
Ejemplo n.º 7
0
    // STATE end -----------------------------------------------

    // STATE start ---------------------------------------------
    void state_Battle()
    {
        // START of checking the state change conditions ---------------------
        if (obstacle1)
        {
            activeState = state_AvoidObstacles;
            return;
        }

        if (!playerShip)
        {
            activeState = state_PlayerSearch;
            return;
        }

        Vector3 playerShipDirection = playerShip.transform.forward;

        playerShipDirection.y = 0;

        Vector3 ourShipDirection = transform.forward;

        ourShipDirection.y = 0;

        float angleBetweenPlayerShipDirectionAndOurShipDirection = Vector3.Angle(playerShipDirection, ourShipDirection);

        if (angleBetweenPlayerShipDirectionAndOurShipDirection > 90)
        {
            angleBetweenPlayerShipDirectionAndOurShipDirection = 180 - angleBetweenPlayerShipDirectionAndOurShipDirection;
        }

        if ((angleBetweenPlayerShipDirectionAndOurShipDirection > 10) ||
            (AIHelperFunctions.GetDistanceBetweenPerpendicular(this.gameObject, playerShip) > 3))
        {
            activeState = state_SailParallelToPlayerShip;
            return;
        }
        // END of checking the state change conditions---------------

        Debug.DrawLine(transform.position, playerShip.transform.position, Color.yellow, 0.0f, true);

        for (int i = 0; i < cannonsTimeOfNextFire.Length; i++)
        {
            if (Time.time < cannonsTimeOfNextFire[i])
            {
                continue;
            }

            cannonsTimeOfNextFire[i] = Time.time + 4 + Random.Range(0.0f, 1.0f);

            Transform cannonTransform = cannons[i].GetComponent <Transform>();
            Ray       cannonRay       = new Ray(cannonTransform.position, cannonTransform.forward);

            float      fireDistance = maxDistBetweenParallel;
            RaycastHit hit;

            if (Physics.Raycast(cannonRay, out hit, fireDistance))
            {
                if (hit.collider.tag == "PlayerShip")
                {
                    StartCoroutine(cannons[i].GetComponent <CannonActions>().FireToOpponentShip(hit.collider.gameObject));
                }
            }
        }
    }
Ejemplo n.º 8
0
    // STATE end -----------------------------------------------

    // STATE start ---------------------------------------------
    void state_SailParallelToPlayerShip()
    {
        // START of checking the state change conditions ---------------------
        if (obstacle1)
        {
            activeState = state_AvoidObstacles;
            return;
        }

        if (!playerShip)
        {
            Debug.Log("SailParallelToPlayerShip ------> ChangeStateTo_PlayerSearch_Or_GoToLastKnownPosition");
            ChangeStateTo_PlayerSearch_Or_GoToLastKnownPlayerShipPosition();
            return;
        }

        // This check can be performed only if playerShip != null
        DetermineInWhichZoneIsOurShip();

        if (!ourShipIsInParallelZone && !ourShipIsInZoneBetweenParallelZones)
        {
            activeState = state_GoToPlayerShip;
            return;
        }

        if (!ourShipIsInParallelZone && ourShipIsInZoneBetweenParallelZones)
        {
            activeState = state_GoToParallelZone;
            return;
        }
        // END of checking the state change conditions---------------

        Vector3 towardsPlayerShipDirection = playerShip.transform.position - transform.position;

        Vector3 playerShipDirection = playerShip.transform.forward;

        playerShipDirection.y = 0;

        Vector3 ourShipDirection = transform.forward;

        ourShipDirection.y = 0;

        Debug.DrawLine(transform.position, playerShip.transform.position, Color.red, 0.0f, true);

        float angleBetweenPlayerShipDirectionAndOurShipDirection = Vector3.Angle(playerShipDirection, ourShipDirection);

        if (angleBetweenPlayerShipDirectionAndOurShipDirection > 90)
        {
            angleBetweenPlayerShipDirectionAndOurShipDirection = 180 - angleBetweenPlayerShipDirectionAndOurShipDirection;
        }

        if ((angleBetweenPlayerShipDirectionAndOurShipDirection <= 10) &&
            (AIHelperFunctions.GetDistanceBetweenPerpendicular(this.gameObject, playerShip) <= 3))
        {
            activeState = state_Battle;
            return;
        }

        if (closeToPlayerShip)
        {
            if (angleBetweenPlayerShipDirectionAndOurShipDirection > 0.5)
            {
                AIHelperFunctions.SetShipsParallel(ourShip, playerShip, enemyBoatController);
            }
        }
        else //not closeToPlayerShip
        {
            if (AIHelperFunctions.IsOurShipDirectionConsistentWithTowardsOtherShipDirection(ourShipDirection, towardsPlayerShipDirection))
            {
                if (angleBetweenPlayerShipDirectionAndOurShipDirection > 0.5)
                {
                    AIHelperFunctions.SetShipsParallel(ourShip, playerShip, enemyBoatController);
                }
            }
            else
            {
                activeState = state_GoToPlayerShip;
            }
        }
    }
Ejemplo n.º 9
0
    // STATE end -----------------------------------------------

    // STATE start ---------------------------------------------
    void state_GoToPlayerShip()
    {
        // START of checking the state change conditions ---------------------
        if (obstacle1)
        {
            activeState = state_AvoidObstacles;
            return;
        }

        if (!playerShip)
        {
            Debug.Log("GoToPlayerShip ------> ChangeStateTo_PlayerSearch_Or_GoToLastKnownPosition");
            ChangeStateTo_PlayerSearch_Or_GoToLastKnownPlayerShipPosition();
            return;
        }

        Vector3 towardsPlayerShipDirection = playerShip.transform.position - transform.position;

        towardsPlayerShipDirection.y = 0;

        Vector3 playerShipDirection = playerShip.transform.forward;

        playerShipDirection.y = 0;

        Vector3 shipDirection = transform.forward;

        shipDirection.y = 0;

        // This check can be performed only if playerShip != null
        DetermineInWhichZoneIsOurShip();
        ourShipDirectionIsConsistentWithTowardsPlayerShipDirection =
            AIHelperFunctions.IsOurShipDirectionConsistentWithTowardsOtherShipDirection(shipDirection, towardsPlayerShipDirection);

        if (ourShipIsInParallelZone)
        {
            if (closeToPlayerShip)
            {
                activeState = state_SailParallelToPlayerShip;
                return;
            }

            if (!closeToPlayerShip)
            {
                if (ourShipDirectionIsConsistentWithTowardsPlayerShipDirection)
                {
                    activeState = state_SailParallelToPlayerShip;
                    return;
                }
            }
        }

        if (ourShipIsInZoneBetweenParallelZones)
        {
            activeState = state_GoToParallelZone;
            return;
        }
        // END of checking the state change conditions---------------

        Debug.DrawLine(transform.position, playerShip.transform.position, Color.white, 0.0f, true);

        // Taking wind into account
        float angleBetweenTowardsPlayerShipDirectionAndWindDirection = Vector3.SignedAngle(towardsPlayerShipDirection, windArea.windDirection, Vector3.up);

        if (angleBetweenTowardsPlayerShipDirectionAndWindDirection > 150)
        {
            towardsPlayerShipDirection = AIHelperFunctions.GetRotatedVector(windArea.windDirection, -150 * Mathf.Deg2Rad);
        }
        else if (angleBetweenTowardsPlayerShipDirectionAndWindDirection < -150)
        {
            towardsPlayerShipDirection = AIHelperFunctions.GetRotatedVector(windArea.windDirection, 150 * Mathf.Deg2Rad);
        }

        enemyBoatController.SetNewShipDirection(towardsPlayerShipDirection);
    }
Ejemplo n.º 10
0
    // =========================================================
    // FSM STATES
    // =========================================================

    // STATE start ---------------------------------------------
    void state_AvoidingObstacle()
    {
        if (!obstacle1)
        {
            activeState = state_MoveRandomly;
            return;
        }

        // if (!obstacle1) {
        //   if (!playerShip) {
        //     activeState = state_PlayerSearching;
        //     return;
        //   } else {
        //     activeState = state_GoToPlayerShip;
        //     return;
        //   }
        // }

        // Vector3 shipPosition = transform.position;
        Vector3 shipDirection = transform.forward;
        float   angleInDegToAvoidObstacle;

        if (obstacle1 && !obstacle2)
        {
            angleInDegToAvoidObstacle = AIHelperFunctions.GetAngleInDegToAvoidObstacle(ourShip, obstacle1, windArea, additionalRandomAngle);
        }
        else
        {
            float angleBetweenShortestShiptToObstacle1VectorAndShipDirection =
                AIHelperFunctions.GetAngleBetweenShortestShiptToObstacleVectorAndShipDirection(obstacle1, transform);
            float angleBetweenShortestShiptToObstacle2VectorAndShipDirection =
                AIHelperFunctions.GetAngleBetweenShortestShiptToObstacleVectorAndShipDirection(obstacle2, transform);

            if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection > 0 &&
                 angleBetweenShortestShiptToObstacle2VectorAndShipDirection < 0)
                ||
                (angleBetweenShortestShiptToObstacle1VectorAndShipDirection < 0 &&
                 angleBetweenShortestShiptToObstacle2VectorAndShipDirection > 0))
            {
                if (Mathf.Abs(angleBetweenShortestShiptToObstacle1VectorAndShipDirection) <
                    Mathf.Abs(angleBetweenShortestShiptToObstacle2VectorAndShipDirection))
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetGreaterAngleInDegToAvoidObstacle(ourShip, obstacle1, additionalRandomAngle);
                }
                else
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetGreaterAngleInDegToAvoidObstacle(ourShip, obstacle2, additionalRandomAngle);
                }
            }
            else if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection > 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection == 0)
                     ||
                     (angleBetweenShortestShiptToObstacle2VectorAndShipDirection > 0 &&
                      angleBetweenShortestShiptToObstacle1VectorAndShipDirection == 0))
            {
                angleInDegToAvoidObstacle = 90 + 20;
            }
            else if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection < 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection == 0)
                     ||
                     (angleBetweenShortestShiptToObstacle2VectorAndShipDirection < 0 &&
                      angleBetweenShortestShiptToObstacle1VectorAndShipDirection == 0))
            {
                angleInDegToAvoidObstacle = -90 - 20;
            }
            else if ((angleBetweenShortestShiptToObstacle1VectorAndShipDirection > 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection > 0)
                     ||
                     (angleBetweenShortestShiptToObstacle1VectorAndShipDirection < 0 &&
                      angleBetweenShortestShiptToObstacle2VectorAndShipDirection < 0))
            {
                if (Mathf.Abs(angleBetweenShortestShiptToObstacle1VectorAndShipDirection) <
                    Mathf.Abs(angleBetweenShortestShiptToObstacle2VectorAndShipDirection))
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetAngleInDegToAvoidObstacle(ourShip, obstacle1, windArea, additionalRandomAngle);
                }
                else
                {
                    angleInDegToAvoidObstacle = AIHelperFunctions.GetAngleInDegToAvoidObstacle(ourShip, obstacle2, windArea, additionalRandomAngle);
                }
            }
            else
            {
                angleInDegToAvoidObstacle = 0;
                Debug.Log("Such situation should not exist!!!");
            }
        }

        Vector3 rotatedVector = AIHelperFunctions.GetRotatedVector(shipDirection, angleInDegToAvoidObstacle * Mathf.Deg2Rad);

        enemyBoatController.SetNewShipDirection(rotatedVector);
    }