/// <summary>
        /// Evade using the target's position and it's velocity
        /// </summary>
        public SteeringOutput Evade(AutonomousAgent character, Vector3 targetPosition, Vector3 velocityOfTarget)
        {
            SteeringOutput output = new SteeringOutput();

            // it calculates how long it would take the agent to get to the postion of the target
            // with the current speed. If that is too much it limits that down to maxPrediction.
            // We need that time to calculate where the target will be in the future in that time
            // so we can set the target to that position and flee from it.

            float distance   = (targetPosition - character.transform.position).magnitude;
            float agentSpeed = character.Velocity.magnitude;

            float prediction;

            if (agentSpeed <= distance / maxPrediction)
            {
                prediction = maxPrediction;
            }
            else
            {
                prediction = distance / agentSpeed;
            }

            // in which direction to evade
            Vector3 evadeDirection = character.transform.position - (targetPosition + velocityOfTarget * prediction);

            // what velocity we want to reach
            Vector3 targetVelocity;

            // target is out of detection radius
            if (distance > detectionRadius)
            {
                targetVelocity = new Vector3();
            }
            else
            {
                targetVelocity = evadeDirection.normalized * character.maxSpeed;
            }

            // make acceleration
            output.linear  = targetVelocity - character.Velocity;
            output.linear /= timeToTarget;

            return(output);
        }
Beispiel #2
0
        public SteeringOutput Seperate(AutonomousAgent character, Vector3 targetPostion)
        {
            SteeringOutput steering = new SteeringOutput();

            int count = Physics2D.OverlapCircleNonAlloc(character.transform.position, targetRadius, collidedWith, 1 << layerMask);

            for (int i = 0; i < count; i++)
            {
                // not the same gameobject tht we are currently inspecting
                if (!collidedWith[i].gameObject.Equals(character.gameObject))
                {
                    float distance = Vector3.Distance(character.transform.position, collidedWith[i].transform.position);
                    float strength = Mathf.Min(character.maxAcceleration, decayCoefficient * distance * distance);

                    steering.linear += strength * (character.transform.position - collidedWith[i].transform.position).normalized;
                }
            }

            return(steering);
        }
Beispiel #3
0
        public SteeringOutput Seek(AutonomousAgent character, Vector3 targetPostion)
        {
            SteeringOutput steering = new SteeringOutput();

            // Get the direction
            Vector3 direction = targetPostion - character.transform.position;
            float   distance  = direction.magnitude;

            // We are inside stopping radius
            if (distance < targetRadius)
            {
                steering.linear = -character.Velocity;
                return(steering);
            }

            float targetSpeed;

            // We are inside the slowdown radius but not the stopping radius
            if (distance < slowDownRadius)
            {
                // start slowing down linearly
                targetSpeed = distance / (slowDownRadius - targetRadius) * character.maxSpeed;
            }
            else     // we are outside of slow down radius
            {
                targetSpeed = character.maxSpeed;
            }

            // combines the direction and the speed
            Vector3 targetVelocity = direction.normalized;

            targetVelocity *= targetSpeed;

            // Calculate acceleration because we can't just change speed immediatly
            // Calculate delta v then divide it by t because a = v / t
            steering.linear  = targetVelocity - character.Velocity;
            steering.linear /= timeToTarget;

            return(steering);
        }
Beispiel #4
0
        public SteeringOutput Wander(AutonomousAgent character, WeightedSteeringBehaviour agentLocalBehaviour)
        {
            SteeringOutput output = new SteeringOutput();

            // update wander angle with [-wanderRate;wanderRate]
            agentLocalBehaviour.wanderAngle += (UnityEngine.Random.value * 2f - 1f) * wanderRate;

            Vector3 targetCircleCenter = character.transform.position + character.transform.up * wanderOffset;
            // move from center of circle by a vector with wanderAngle angle and wanderRadius length
            Vector3 targetOnCircleLocation = targetCircleCenter +
                                             Quaternion.Euler(0, 0, agentLocalBehaviour.wanderAngle) * character.transform.up * wanderRadius;

            if (character.showGizmos)
            {
                Debug.DrawLine(character.transform.position, targetOnCircleLocation, Color.red);
            }

            // get rotation
            output = Face(character, targetOnCircleLocation);
            // set linear to full acceleration ahead
            output.linear = character.transform.up * character.maxAcceleration;

            return(output);
        }
Beispiel #5
0
        public SteeringOutput FollowPath(AutonomousAgent character, WeightedSteeringBehaviour agentLocalBehaviour)
        {
            SteeringOutput output = new SteeringOutput();

            // Debug.Log(agentLocalBehaviour.currentPathStation + " " + agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation));
            switch (followType)
            {
            case FollowType.Station:
                #region Station
                // in agentLocalBehaviour we store the current station that is being followed
                // so we need to check whether the agent is closer to that station or the next one
                // to check that we need to get the position

                // if the current path is farther away then the next path
                if ((agentLocalBehaviour.path.GetDistanceFromPathTo(character.transform.position, agentLocalBehaviour.currentPathStation) >
                     agentLocalBehaviour.path.GetDistanceFromPathTo(character.transform.position, agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation)))
                    // or we have reached the station
                    || Vector3.Distance(character.transform.position, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation)) <= targetRadius)
                {
                    // make the next station the target
                    agentLocalBehaviour.currentPathStation = agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation);
                }

                output = Seek(character, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation));
                #endregion
                break;

            case FollowType.AlwaysReachStation:
                #region AlwaysReachStation
                // we have reached the station
                if (Vector3.Distance(character.transform.position, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation)) <= targetRadius)
                {
                    // make the next station the target
                    agentLocalBehaviour.currentPathStation = agentLocalBehaviour.path.GetNextStationIndex(agentLocalBehaviour.currentPathStation);
                }

                output = Seek(character, agentLocalBehaviour.path.GetStationPosition(agentLocalBehaviour.currentPathStation));
                #endregion
                break;

            case FollowType.Path:
                #region Path
                // here we look ahead on the path with followAheadPercent and set that as a target

                float   percent = agentLocalBehaviour.path.GetClosestPointOnPathPercent(character.transform.position);
                Vector3 target  = agentLocalBehaviour.path.GetPointOnPathPercent(percent + followAheadPercent);
                output = Seek(character, target);

                if (character.showGizmos)
                {
                    Debug.DrawLine(character.transform.position, target, Color.green);
                }
                #endregion
                break;

            case FollowType.PredictivePath:
                #region Predictive Path
                percent = agentLocalBehaviour.path.GetClosestPointOnPathPercent(character.transform.position + character.Velocity * predictTime);
                target  = agentLocalBehaviour.path.GetPointOnPathPercent(percent + followAheadPercent);
                output  = Seek(character, target);

                if (character.showGizmos)
                {
                    Debug.DrawLine(character.transform.position, character.transform.position + character.Velocity * predictTime, Color.yellow);
                    Debug.DrawLine(character.transform.position, target, Color.green);
                }
                #endregion
                break;
            }

            return(output);
        }
Beispiel #6
0
        public void Update(SteeringOutput steering, GameTime time, Game game)
        {
            newState = Keyboard.GetState();

            bool keyPressed = false;

            if (game.playerHunter.health > 0 && game.playerHunter.spearJab == false && game.playerHunter.spearThrow == false)
            {
                if (Game.keyboard.IsKeyDown(Keys.A))
                {
                    velocity.X -= maxAcceleration;
                    keyPressed  = true;
                }
                if (Game.keyboard.IsKeyDown(Keys.D))
                {
                    velocity.X += maxAcceleration;
                    keyPressed  = true;
                }
                if (Game.keyboard.IsKeyDown(Keys.W))
                {
                    velocity.Y -= maxAcceleration;
                    keyPressed  = true;
                }
                if (Game.keyboard.IsKeyDown(Keys.S))
                {
                    velocity.Y += maxAcceleration;
                    keyPressed  = true;
                }
            }
            if (game.playerHunter.spearJab == true || game.playerHunter.spearThrow == true)
            {
                for (int i = 0; i < game.deerManager.GetDeerCount(); i++)
                {
                    Deer d = (Deer)game.deerManager.deers[i];
                    dirFromSpear = (d.Position - this.Position);
                    float distance = dirFromSpear.Length();
                    if (distance < 30)
                    {
                        game.deerManager.KillDeer(d);
                        game.playerHunter.spearJab   = false;
                        game.playerHunter.spearThrow = false;
                        break;
                    }
                }

                float distStoL = (game.lion.Position - this.Position).Length();
                if (distStoL < 30)
                {
                    if (game.playerHunter.spearJab)
                    {
                        game.lion.health          -= 2;
                        game.playerHunter.spearJab = false;
                    }
                    if (game.playerHunter.spearThrow)
                    {
                        game.lion.health            -= 1;
                        game.playerHunter.spearThrow = false;
                    }
                }
            }
            if (game.playerHunter.spearJab && game.playerHunter.health > 0)
            {
                keyPressed  = true;
                getPosition = this.position;
                Vector2 movement = game.playerHunter.Velocity;

                movement.X += 12 * (float)Math.Cos(game.playerHunter.orientation);
                movement.Y += (12 * (float)Math.Sin(game.playerHunter.orientation));

                move += 3;
                if (move < jabDistance)
                {
                    this.position    = getPosition;
                    this.position.X += ((int)movement.X);
                    this.position.Y += ((int)movement.Y);
                }

                else
                {
                    this.position              = game.playerHunter.Position;
                    this.position.X           += 40;
                    this.position.Y           -= 20;
                    move                       = 0;
                    game.playerHunter.spearJab = false;
                }
            }

            if (game.playerHunter.spearThrow && game.playerHunter.health > 0)
            {
                //game.playerHunter.spearThrow = true;
                Vector2 movement = Vector2.Zero;
                getPosition = this.position;
                movement    = game.playerHunter.throwVelocity;

                movement.X += 8 * (float)Math.Cos(game.playerHunter.throwOrientation);
                movement.Y += (8 * (float)Math.Sin(game.playerHunter.throwOrientation));
                keyPressed  = true;


                move += 4;
                if (move < throwDistance)
                {
                    this.position    = getPosition;
                    this.position.X += ((int)movement.X);
                    this.position.Y += ((int)movement.Y);
                }

                else
                {
                    this.position    = game.playerHunter.Position;
                    this.position.X += 40;
                    this.position.Y -= 20;
                    move             = 0;
                    game.playerHunter.spearThrow = false;
                }
            }


            if (!keyPressed)
            {
                this.position    = game.playerHunter.Position;
                this.position.X += 40;
                this.position.Y -= 20;
                velocity         = new Vector2();
            }
            if (velocity.Length() > MaxSpeed)
            {
                velocity.Normalize();
                velocity *= maxSpeed;
            }


            base.Update(steering, time);

            //position += velocity;
            //orientation += rotation;

            collide.position.X += (float)((((image.Height - 5) / 2) * Math.Cos(this.orientation)));
            collide.position.Y += (float)(((image.Height - 5) / 2) * Math.Sin(this.orientation));
        }
Beispiel #7
0
        public override void Update(SteeringOutput steering, GameTime time)
        {
            if (health > 4)
            {
                health = 4;
            }
            prevState = newState;
            newState  = Keyboard.GetState();
            threatCooldown--;
            if (threatCooldown < 0)
            {
                decayThreat();
            }
            bool keyPressed = false;

            if (health > 0 && spearJab == false && spearThrow == false)
            {
                if (Game.keyboard.IsKeyDown(Keys.A))
                {
                    velocity.X -= maxAcceleration;
                    keyPressed  = true;
                }
                if (Game.keyboard.IsKeyDown(Keys.D))
                {
                    velocity.X += maxAcceleration;
                    keyPressed  = true;
                }
                if (Game.keyboard.IsKeyDown(Keys.W))
                {
                    velocity.Y -= maxAcceleration;
                    keyPressed  = true;
                }
                if (Game.keyboard.IsKeyDown(Keys.S))
                {
                    velocity.Y += maxAcceleration;
                    keyPressed  = true;
                }
            }

            if (!canAttack)
            {
                coolDown--;

                if (coolDown <= 0)
                {
                    coolDown  = 50;
                    canAttack = true;
                }
            }

            if (canAttack)
            {
                if (newState.IsKeyDown(Keys.J) && prevState.IsKeyUp(Keys.J))
                {
                    canAttack  = false;
                    keyPressed = true;
                    spearJab   = true;
                    threaten();
                }

                if (newState.IsKeyDown(Keys.K) && prevState.IsKeyUp(Keys.K))
                {
                    canAttack        = false;
                    keyPressed       = true;
                    spearThrow       = true;
                    throwOrientation = this.orientation;
                    throwVelocity    = this.velocity;
                    threaten();
                }
            }

            if (!keyPressed)
            {
                velocity = new Vector2();
            }

            if (velocity.Length() > MaxSpeed)
            {
                velocity.Normalize();
                velocity *= maxSpeed;
            }


            base.Update(steering, time);
        }
Beispiel #8
0
        private void FixedUpdate()
        {
            SteeringOutput steering = new SteeringOutput();

            switch (blendingType)
            {
                #region Signle Blending
            case SteeringBlendingTypes.Single:
                // Get the first and only steering we need
                steering = steeringBehaviours[0].behaviour.GetSteering(this, steeringBehaviours[0]);
                break;

                #endregion
                #region Weighted Blending
            case SteeringBlendingTypes.Weighted:
                SteeringOutput weighted;
                for (int i = 0; i < steeringBehaviours.Count; i++)
                {
                    weighted          = steeringBehaviours[i].behaviour.GetSteering(this, steeringBehaviours[i]);
                    steering.linear  += weighted.linear * steeringBehaviours[i].velocityWeight;
                    steering.angular += weighted.angular * steeringBehaviours[i].rotationWeight;
                }
                break;
                #endregion
            }

            steering.LimitOutputs(maxAcceleration, maxAngularAcceleration);

            // Update pos and orientation
            transform.position += velocity * Time.fixedDeltaTime;
            transform.Rotate(0, 0, rotationVelocity * Time.fixedDeltaTime);

            velocity += steering.linear * Time.fixedDeltaTime;

            float speed = velocity.magnitude;
            // Limit to velocity
            if (speed > maxSpeed)
            {
                velocity.Normalize();
                velocity *= maxSpeed;
            }

            if (Mathf.Approximately((float)Math.Round(speed, 1), 0f))
            {
                velocity = new Vector3();
            }

            if (lookWhereGoingInstantly)
            {
                transform.rotation = Quaternion.Euler(0, 0, Mathf.Atan2(velocity.y, velocity.x) * Mathf.Rad2Deg - 90f);
            }
            else
            {
                // update with steering
                rotationVelocity += steering.angular * Time.fixedDeltaTime;

                // Limit angular velocity
                if (rotationVelocity > maxRotation)
                {
                    // * .... so it keeps the direction
                    rotationVelocity = maxRotation * (maxRotation / Mathf.Abs(maxRotation));
                }
            }
        }