예제 #1
0
    private AgentDirection CalculateAgentDirection(Vector3 selfPosition, Vector3 rayDirection, float sightFactor = 1.0f)
    {
        if (debug)
        {
            Debug.DrawRay(selfPosition, rayDirection * sight, visionColor);
        }

        //Calculate a random utility to initiate the AgentDirection.
        float utility = Random.Range(Mathf.Min(randomDirectionValue.x, randomDirectionValue.y), Mathf.Max(randomDirectionValue.x, randomDirectionValue.y));

        //Create an AgentDirection struct with a random utility value [utility]. Ignores y component.
        AgentDirection direction = new AgentDirection(new Vector3(rayDirection.x, 0.0f, rayDirection.z), utility);

        //Raycast into the rayDirection to check if something can be seen in that direction.
        //The sightFactor is a variable that increases / decreases the size of the ray.
        //For now, the sightFactor is only used to control the long sight in front of the agent.
        if (Physics.Raycast(selfPosition, rayDirection, out RaycastHit raycastHit, sight * sightFactor))
        {
            if (debug)
            {
                Debug.DrawLine(selfPosition, raycastHit.point, foundColor);
            }

            //Calculate the normalized distance from the agent to the intersected object.
            //Closer objects will have distancedNormalized close to 0, and further objects will have it close to 1.
            float distanceNormalized = (raycastHit.distance / (sight * sightFactor));

            //Inverts the distanceNormalized. Closer objects will tend to 1, while further objects will tend to 0.
            //Thus, closer objects will have a higher value.
            float distanceIndex = 1.0f - distanceNormalized;

            //Calculate the utility of the found object according to its type.
            switch (raycastHit.collider.gameObject.tag)
            {
            //All formulas are the same. Only the weights change.
            case "Box":
                utility = distanceIndex * distanceFactor + boxWeight;
                break;

            case "x4Box":
                utility = distanceIndex * x4distanceFactor + x4boxWeight;
                break;

            case "x16Box":
                utility = distanceIndex * x16distanceFactor + x16boxWeight;
                break;

            case "Boat":
                utility = distanceIndex * boatDistanceFactor + boatWeight;
                break;

            case "Wall":
                utility = distanceIndex * wallDistanceFactor + wallWeight;
                break;
            }
        }

        direction.utility = utility;
        return(direction);
    }
예제 #2
0
 public void SetDecision(int index, Decision decide)
 {
     for (int i = 0; i < Data.AgentsCount; ++i)
     {
         AgentDirection dir = DirectionExtensions.CastPointToDir(decide.Agents[i]);
         viewModel.Players[index].AgentViewModels[i].Data.AgentDirection = dir;
         viewModel.Players[index].AgentViewModels[i].Data.State          = AgentState.Move;
     }
 }
예제 #3
0
 public void SetDirection(AgentDirection direction)
 {
     if (this.Direction != direction)
     {
         var scale = this.transform.localScale;
         this.transform.localScale = new Vector3(-scale.x, scale.y, scale.z);
         this.Direction            = direction;
     }
 }
예제 #4
0
    /// <summary>
    /// Calculate the best direction to move using the Agent properties.
    /// The agent shoots a ray in a area on front of itself and calculates the utility of each one of them based on what
    /// it did intersect or using a random value (uses a Random from [randomDirectionValue.x, randomDirectionValue.y]).
    /// </summary>
    private void Act()
    {
        //Clear the visible objetcs with a small delay, so that the objects in actual range dont get ignored because the raycast moved
        if (actIteration >= 60)
        {
            visibleObjects.Clear();
            actIteration = 0;

            //Reset environment factor along with the visible objects
            speedEnvironmentWeight      = 1f;
            pullEnvironmentWeight       = 1f;
            multiplierEnvironmentWeight = 1f;
        }

        Transform selfTransform = transform;
        Vector3   forward       = selfTransform.forward;

        //Ignores the y component to avoid flying/sinking Agents.
        forward.y = 0.0f;
        forward.Normalize();
        Vector3 selfPosition = selfTransform.position;

        //Initiate the rayDirection on the opposite side of the spectrum.
        Vector3 rayDirection = Quaternion.Euler(0, -1.0f * steps * (rayRadius / 2.0f), 0) * forward;

        //List of AgentDirection (direction + utility) for all the directions.
        List <AgentDirection> directions = new List <AgentDirection>();

        for (int i = 0; i <= rayRadius; i++)
        {
            //Add the new calculatedAgentDirection looking at the rayDirection.
            directions.Add(CalculateAgentDirection(selfPosition, rayDirection));

            //Rotate the rayDirection by _steps every iteration through the entire rayRadius.
            rayDirection = Quaternion.Euler(0, steps, 0) * rayDirection;
        }
        //Adds an extra direction for the front view with a extra range.
        directions.Add(CalculateAgentDirection(selfPosition, forward, 1.5f));

        directions.Sort();
        //There is a (100 - _maxUtilityChoiceChance) chance of using the second best option instead of the highest one. Should help into ambiguous situation.
        AgentDirection highestAgentDirection = directions[Random.Range(0.0f, 100.0f) <= _maxUtilityChoiceChance ? 0 : 1];

        //Rotate towards to direction. The factor of 0.1 helps to create a "rotation" animation instead of automatically rotates towards the target.
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(highestAgentDirection.Direction), 0.1f);

        //Sets the velocity using the chosen direction
        _rigidbody.velocity = highestAgentDirection.Direction * movingSpeed * speedMultiplier;

        actIteration++;

        if (debug)
        {
            Debug.DrawRay(selfPosition, highestAgentDirection.Direction * (sight * 1.5f), directionColor);
        }
    }
예제 #5
0
    /// <summary>
    /// Notices that this method is an "inverse" sorting. It makes the higher values on top of the Sort, instead of
    /// the smaller values. For the smaller values, the return line would be utility.CompareTo(otherAgent.utility).
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public int CompareTo(object obj)
    {
        if (obj == null)
        {
            return(1);
        }

        AgentDirection otherAgent = (AgentDirection)obj;

        return(otherAgent.utility.CompareTo(utility));
    }
예제 #6
0
 protected override bool Trigger()
 {
     if (this.Agent.DashStatus.IsDashing)
     {
         return(false);
     }
     if (Input.GetAxis("Horizontal") < -0.1)
     {
         this.direction = AgentDirection.Left;
         return(true);
     }
     if (Input.GetAxis("Horizontal") > 0.1)
     {
         this.direction = AgentDirection.Right;
         return(true);
     }
     return(false);
 }
예제 #7
0
파일: Agent.cs 프로젝트: GQBrendel/heroes
        private void moveTowards()
        {
            // Move the agent towards the node
            Vector3 update = Vector3.MoveTowards(lastPosition, target.WorldPosition, moveSpeed * Time.deltaTime);

            // Get the movement vector only
            Vector3 temp = update - lastPosition;

            // Make sure the vector is not zero
            if (temp.sqrMagnitude != 0)
            {
                // Check if the movement is up or down
                if (temp.y <= 0.002f)
                {
                    // Moving downwards - Default to forward where possible
                    direction = AgentDirection.Forward;
                }
                else
                {
                    // Moving upwards
                    direction = AgentDirection.Backward;
                }

                if (temp.x > 0)
                {
                    // Moiving right
                    direction |= AgentDirection.Right;
                }
                else if (temp.x < 0)
                {
                    // Moving left
                    direction |= AgentDirection.Left;
                }
            }

            // Set the moving flag
            isMoving = (update != transform.position);

            // Update the position
            transform.position = update;
            lastPosition       = transform.position;
        }
예제 #8
0
    private AgentDirection CalculateAgentDirection(Vector3 selfPosition, Vector3 rayDirection, float sightFactor = 1.0f)
    {
        if (debug)
        {
            Debug.DrawRay(selfPosition, rayDirection * sight, visionColor);
        }

        //Calculate a random utility to initiate the AgentDirection.
        float utility = Random.Range(Mathf.Min(randomDirectionValue.x, randomDirectionValue.y), Mathf.Max(randomDirectionValue.x, randomDirectionValue.y));

        //Create an AgentDirection struct with a random utility value [utility]. Ignores y component.
        AgentDirection direction = new AgentDirection(new Vector3(rayDirection.x, 0.0f, rayDirection.z), utility);

        //Raycast into the rayDirection to check if something can be seen in that direction.
        //The sightFactor is a variable that increases / decreases the size of the ray.
        //For now, the sightFactor is only used to control the long sight in front of the agent.
        if (Physics.Raycast(selfPosition, rayDirection, out RaycastHit raycastHit, sight * sightFactor))
        {
            if (debug)
            {
                Debug.DrawLine(selfPosition, raycastHit.point, foundColor);
            }

            //Calculate the normalized distance from the agent to the intersected object.
            //Closer objects will have distancedNormalized close to 0, and further objects will have it close to 1.
            float distanceNormalized = (raycastHit.distance / (sight * sightFactor));

            //Inverts the distanceNormalized. Closer objects will tend to 1, while further objects will tend to 0.
            //Thus, closer objects will have a higher value.
            float distanceIndex = 1.0f - distanceNormalized;

            GameObject visibleObject = raycastHit.collider.gameObject;

            //Calculate the utility of the found object according to its type.
            switch (visibleObject.tag)
            {
            case "Box":
                utility = distanceIndex * boxDistanceFactor + boxWeight;
                break;

            case "Boat":
                utility = distanceIndex * boatDistanceFactor + boatWeight;
                break;

            case "Enemy":
                utility = distanceIndex * enemyDistanceFactor + enemyWeight;
                break;

            case "Speed":
                if (!abled)
                {
                    break;
                }
                utility = distanceIndex * speedDistanceFactor + speedWeight * speedEnvironmentWeight * speedActiveFactor;
                break;

            case "Pull":
                if (!abled)
                {
                    break;
                }
                utility = distanceIndex * pullDistanceFactor + pullWeight * pullEnvironmentWeight;
                break;

            case "Multiplier":
                if (!abled)
                {
                    break;
                }
                utility = distanceIndex * multiplierDistanceFactor + multiplierWeight * multiplierEnvironmentWeight * multiplierActiveFactor;
                break;
            }

            //Add or update the object in the dictionary.
            if (visibleObjects.ContainsKey(visibleObject))
            {
                visibleObjects[visibleObject] = utility;
            }
            else
            {
                visibleObjects.Add(visibleObject, utility);

                //Increase the probability of the agent to pick up a powerup, depending on how many objects are around.
                speedEnvironmentWeight      += speedEnvironmentFactor;
                pullEnvironmentWeight       += pullEnvironmentFactor;
                multiplierEnvironmentWeight += multiplierEnvironmentFactor;
            }
        }

        direction.utility = utility;
        return(direction);
    }