예제 #1
0
        // Token: 0x0600213A RID: 8506 RVA: 0x0018DB20 File Offset: 0x0018BD20
        protected override void MovementUpdateInternal(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
        {
            float num = this.maxAcceleration;

            if (num < 0f)
            {
                num *= -this.maxSpeed;
            }
            if (this.updatePosition)
            {
                this.simulatedPosition = this.tr.position;
            }
            if (this.updateRotation)
            {
                this.simulatedRotation = this.tr.rotation;
            }
            Vector3 simulatedPosition = this.simulatedPosition;

            this.interpolator.MoveToCircleIntersection2D(simulatedPosition, this.pickNextWaypointDist, this.movementPlane);
            Vector2 deltaPosition    = this.movementPlane.ToPlane(this.steeringTarget - simulatedPosition);
            float   num2             = deltaPosition.magnitude + Mathf.Max(0f, this.interpolator.remainingDistance);
            bool    reachedEndOfPath = this.reachedEndOfPath;

            this.reachedEndOfPath = (num2 <= this.endReachedDistance && this.interpolator.valid);
            if (!reachedEndOfPath && this.reachedEndOfPath)
            {
                this.OnTargetReached();
            }
            Vector2 vector = this.movementPlane.ToPlane(this.simulatedRotation * (this.rotationIn2D ? Vector3.up : Vector3.forward));
            float   num3;

            if (this.interpolator.valid && !base.isStopped)
            {
                num3 = ((num2 < this.slowdownDistance) ? Mathf.Sqrt(num2 / this.slowdownDistance) : 1f);
                if (this.reachedEndOfPath && this.whenCloseToDestination == CloseToDestinationMode.Stop)
                {
                    this.velocity2D -= Vector2.ClampMagnitude(this.velocity2D, num * deltaTime);
                }
                else
                {
                    this.velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(deltaPosition, deltaPosition.normalized * this.maxSpeed, this.velocity2D, num, this.rotationSpeed, this.maxSpeed, vector) * deltaTime;
                }
            }
            else
            {
                num3             = 1f;
                this.velocity2D -= Vector2.ClampMagnitude(this.velocity2D, num * deltaTime);
            }
            this.velocity2D = MovementUtilities.ClampVelocity(this.velocity2D, this.maxSpeed, num3, this.slowWhenNotFacingTarget, vector);
            base.ApplyGravity(deltaTime);
            if (this.rvoController != null && this.rvoController.enabled)
            {
                Vector3 pos = simulatedPosition + this.movementPlane.ToWorld(Vector2.ClampMagnitude(this.velocity2D, num2), 0f);
                this.rvoController.SetTarget(pos, this.velocity2D.magnitude, this.maxSpeed);
            }
            Vector2 p = this.lastDeltaPosition = base.CalculateDeltaToMoveThisFrame(this.movementPlane.ToPlane(simulatedPosition), num2, deltaTime);

            nextPosition = simulatedPosition + this.movementPlane.ToWorld(p, this.verticalVelocity * this.lastDeltaTime);
            this.CalculateNextRotation(num3, out nextRotation);
        }
예제 #2
0
    /** A modified version of AIPath.Movement Update which allows movement without rotation.*/
    protected override void MovementUpdate(float deltaTime)
    {
        if (!canMove)
        {
            return;
        }

        if (!interpolator.valid)
        {
            velocity2D = Vector3.zero;
        }
        else
        {
            var currentPosition = tr.position;

            interpolator.MoveToLocallyClosestPoint(currentPosition, true, false);
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            targetPoint = interpolator.position;
            direction   = movementPlane.ToPlane(targetPoint - currentPosition);

            var distanceToEnd = direction.magnitude + interpolator.remainingDistance;
            // How fast to move depending on the distance to the target.
            // Move slower as the character gets closer to the target.
            float slowdown = slowdownDistance > 0 ? distanceToEnd / slowdownDistance : 1;

            // a = v/t, should probably expose as a variable
            float   acceleration = speed / 0.4f;
            Vector2 forward      = enableRotation ? (Vector2)(rotationIn2D ? tr.up : tr.forward) : direction;

            if (enableAcceleration)
            {
                velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(direction, direction.normalized * speed, velocity2D, acceleration, speed) * deltaTime;
            }
            else
            {
                velocity2D = direction.normalized * speed * CONSTANT_SPEED_MODIFIER * deltaTime;
            }
            velocity2D = MovementUtilities.ClampVelocity(velocity2D, speed, slowdown, enableRotation, movementPlane.ToPlane(forward));

            ApplyGravity(deltaTime);

            if (distanceToEnd <= endReachedDistance && !TargetReached)
            {
                TargetReached = true;
                OnTargetReached();
            }

            // Rotate towards the direction we are moving in
            if (enableRotation)
            {
                var currentRotationSpeed = rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(slowdown) - 0.3f) / 0.7f);
                RotateTowards(velocity2D, currentRotationSpeed * deltaTime);
            }

            var delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
            Move(currentPosition, movementPlane.ToWorld(delta2D, verticalVelocity * deltaTime));

            velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);
        }
    }
        void TraverseFunnel(RichFunnel fn, float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
        {
            // Clamp the current position to the navmesh
            // and update the list of upcoming corners in the path
            // and store that in the 'nextCorners' field
            var     position3D = UpdateTarget(fn);
            float   elevation;
            Vector2 position = movementPlane.ToPlane(position3D, out elevation);

            // Only find nearby walls every 5th frame to improve performance
            if (Time.frameCount % 5 == 0 && wallForce > 0 && wallDist > 0)
            {
                wallBuffer.Clear();
                fn.FindWalls(wallBuffer, wallDist);
            }

            // Target point
            steeringTarget = nextCorners[0];
            Vector2 targetPoint = movementPlane.ToPlane(steeringTarget);
            // Direction to target
            Vector2 dir = targetPoint - position;

            // Normalized direction to the target
            Vector2 normdir = VectorMath.Normalize(dir, out distanceToSteeringTarget);
            // Calculate force from walls
            Vector2 wallForceVector = CalculateWallForce(position, elevation, normdir);
            Vector2 targetVelocity;

            if (approachingPartEndpoint)
            {
                targetVelocity = slowdownTime > 0 ? Vector2.zero : normdir * maxSpeed;

                // Reduce the wall avoidance force as we get closer to our target
                wallForceVector *= System.Math.Min(distanceToSteeringTarget / 0.5f, 1);

                if (distanceToSteeringTarget <= endReachedDistance)
                {
                    // Reached the end of the path or an off mesh link
                    NextPart();
                }
            }
            else
            {
                var nextNextCorner = nextCorners.Count > 1 ? movementPlane.ToPlane(nextCorners[1]) : position + 2 * dir;
                targetVelocity = (nextNextCorner - targetPoint).normalized * maxSpeed;
            }

            var     forwards = movementPlane.ToPlane(simulatedRotation * (orientation == OrientationMode.YAxisForward ? Vector3.up : Vector3.forward));
            Vector2 accel    = MovementUtilities.CalculateAccelerationToReachPoint(targetPoint - position, targetVelocity, velocity2D, acceleration, rotationSpeed, maxSpeed, forwards);

            // Update the velocity using the acceleration
            velocity2D += (accel + wallForceVector * wallForce) * deltaTime;

            // Distance to the end of the path (almost as the crow flies)
            var distanceToEndOfPath = distanceToSteeringTarget + Vector3.Distance(steeringTarget, fn.exactEnd);
            var slowdownFactor      = distanceToEndOfPath < maxSpeed *slowdownTime?Mathf.Sqrt(distanceToEndOfPath / (maxSpeed *slowdownTime)) : 1;

            FinalMovement(position3D, deltaTime, distanceToEndOfPath, slowdownFactor, out nextPosition, out nextRotation);
        }
예제 #4
0
        private void TraverseFunnel(RichFunnel fn, float deltaTime)
        {
            float   elevation;
            Vector2 vector = this.movementPlane.ToPlane(this.UpdateTarget(fn), out elevation);

            if (Time.frameCount % 5 == 0 && this.wallForce > 0f && this.wallDist > 0f)
            {
                this.wallBuffer.Clear();
                fn.FindWalls(this.wallBuffer, this.wallDist);
            }
            Vector2 vector2 = this.waypoint = this.movementPlane.ToPlane(this.nextCorners[0]);
            Vector2 vector3 = vector2 - vector;
            object  obj     = this.lastCorner && this.nextCorners.Count == 1;
            Vector2 vector4 = VectorMath.Normalize(vector3, out this.distanceToWaypoint);
            Vector2 a       = this.CalculateWallForce(vector, elevation, vector4);
            object  obj2    = obj;
            Vector2 targetVelocity;

            if (obj2 != null)
            {
                targetVelocity = ((this.slowdownTime > 0f) ? Vector2.zero : (vector4 * this.maxSpeed));
                a *= Math.Min(this.distanceToWaypoint / 0.5f, 1f);
                if (this.distanceToWaypoint <= this.endReachedDistance)
                {
                    this.NextPart();
                }
            }
            else
            {
                targetVelocity = (((this.nextCorners.Count > 1) ? this.movementPlane.ToPlane(this.nextCorners[1]) : (vector + 2f * vector3)) - vector2).normalized * this.maxSpeed;
            }
            Vector2 a2 = MovementUtilities.CalculateAccelerationToReachPoint(vector2 - vector, targetVelocity, this.velocity2D, this.acceleration, this.maxSpeed);

            this.velocity2D += (a2 + a * this.wallForce) * deltaTime;
            float distanceToEndOfPath = fn.DistanceToEndOfPath;
            float num = (this.slowdownTime > 0f) ? (distanceToEndOfPath / (this.maxSpeed * this.slowdownTime)) : 1f;

            this.velocity2D = MovementUtilities.ClampVelocity(this.velocity2D, this.maxSpeed, num, this.slowWhenNotFacingTarget, this.movementPlane.ToPlane(this.rotationIn2D ? this.tr.up : this.tr.forward));
            base.ApplyGravity(deltaTime);
            if (this.rvoController != null && this.rvoController.enabled)
            {
                Vector3 pos = this.movementPlane.ToWorld(vector + Vector2.ClampMagnitude(this.velocity2D, distanceToEndOfPath), elevation);
                this.rvoController.SetTarget(pos, this.velocity2D.magnitude, this.maxSpeed);
            }
            Vector2 vector5 = base.CalculateDeltaToMoveThisFrame(vector, distanceToEndOfPath, deltaTime);
            float   num2    = (obj2 != null) ? Mathf.Clamp01(1.1f * num - 0.1f) : 1f;

            this.RotateTowards(vector5, this.rotationSpeed * num2 * deltaTime);
            base.Move(this.movementPlane.ToWorld(vector, elevation), this.movementPlane.ToWorld(vector5, this.verticalVelocity * deltaTime));
        }
예제 #5
0
    protected override void MovementUpdate(float deltaTime)
    {
        if (!this.canMove)
        {
            return;
        }
        if (!this.interpolator.valid)
        {
            this.velocity2D = Vector3.zero;
            return;
        }
        Vector3 position = this.tr.position;

        this.interpolator.MoveToLocallyClosestPoint(position, true, false);
        this.interpolator.MoveToCircleIntersection2D(position, this.pickNextWaypointDist, this.movementPlane);
        this.targetPoint = this.interpolator.position;
        Vector2 deltaPosition = this.movementPlane.ToPlane(this.targetPoint - position);
        float   num           = deltaPosition.magnitude + this.interpolator.remainingDistance;
        float   num2          = (this.slowdownDistance > 0f) ? (num / this.slowdownDistance) : 1f;
        float   acceleration  = this.speed / 0.4f;

        this.velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(deltaPosition, deltaPosition.normalized * this.speed, this.velocity2D, acceleration, this.speed) * deltaTime;
        this.velocity2D  = MovementUtilities.ClampVelocity(this.velocity2D, this.speed, num2, true, this.movementPlane.ToPlane(this.rotationIn2D ? this.tr.up : this.tr.forward));
        base.ApplyGravity(deltaTime);
        if (num <= this.endReachedDistance && !this.TargetReached)
        {
            this.TargetReached = true;
            this.OnTargetReached();
        }
        float num3 = this.rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(num2) - 0.3f) / 0.7f);

        this.RotateTowards(this.velocity2D, num3 * deltaTime);
        if (this.rvoController != null && this.rvoController.enabled)
        {
            Vector3 pos = position + this.movementPlane.ToWorld(Vector2.ClampMagnitude(this.velocity2D, num), 0f);
            this.rvoController.SetTarget(pos, this.velocity2D.magnitude, this.speed);
        }
        Vector2 p = base.CalculateDeltaToMoveThisFrame(this.movementPlane.ToPlane(position), num, deltaTime);

        base.Move(position, this.movementPlane.ToWorld(p, this.verticalVelocity * deltaTime));
        this.velocity = this.movementPlane.ToWorld(this.velocity2D, this.verticalVelocity);
    }
예제 #6
0
        // Token: 0x0600217C RID: 8572 RVA: 0x0018E4A4 File Offset: 0x0018C6A4
        private void TraverseFunnel(RichFunnel fn, float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
        {
            Vector3 vector = this.UpdateTarget(fn);
            float   elevation;
            Vector2 vector2 = this.movementPlane.ToPlane(vector, out elevation);

            if (Time.frameCount % 5 == 0 && this.wallForce > 0f && this.wallDist > 0f)
            {
                this.wallBuffer.Clear();
                fn.FindWalls(this.wallBuffer, this.wallDist);
            }
            this.steeringTarget = this.nextCorners[0];
            Vector2 vector3 = this.movementPlane.ToPlane(this.steeringTarget);
            Vector2 vector4 = vector3 - vector2;
            Vector2 vector5 = VectorMath.Normalize(vector4, out this.distanceToSteeringTarget);
            Vector2 a       = this.CalculateWallForce(vector2, elevation, vector5);
            Vector2 targetVelocity;

            if (this.approachingPartEndpoint)
            {
                targetVelocity = ((this.slowdownTime > 0f) ? Vector2.zero : (vector5 * this.maxSpeed));
                a *= Math.Min(this.distanceToSteeringTarget / 0.5f, 1f);
                if (this.distanceToSteeringTarget <= this.endReachedDistance)
                {
                    this.NextPart();
                }
            }
            else
            {
                targetVelocity = (((this.nextCorners.Count > 1) ? this.movementPlane.ToPlane(this.nextCorners[1]) : (vector2 + 2f * vector4)) - vector3).normalized * this.maxSpeed;
            }
            Vector2 forwardsVector = this.movementPlane.ToPlane(this.simulatedRotation * (this.rotationIn2D ? Vector3.up : Vector3.forward));
            Vector2 a2             = MovementUtilities.CalculateAccelerationToReachPoint(vector3 - vector2, targetVelocity, this.velocity2D, this.acceleration, this.rotationSpeed, this.maxSpeed, forwardsVector);

            this.velocity2D += (a2 + a * this.wallForce) * deltaTime;
            float num            = this.distanceToSteeringTarget + Vector3.Distance(this.steeringTarget, fn.exactEnd);
            float slowdownFactor = (num < this.maxSpeed * this.slowdownTime) ? Mathf.Sqrt(num / (this.maxSpeed * this.slowdownTime)) : 1f;

            this.FinalMovement(vector, deltaTime, num, slowdownFactor, out nextPosition, out nextRotation);
        }
예제 #7
0
파일: AIPath.cs 프로젝트: smithhd/SE_Final
        /// <summary>Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not</summary>
        protected override void MovementUpdateInternal(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
        {
            float currentAcceleration = maxAcceleration;

            // If negative, calculate the acceleration from the max speed
            if (currentAcceleration < 0)
            {
                currentAcceleration *= -maxSpeed;
            }

            if (updatePosition)
            {
                // Get our current position. We read from transform.position as few times as possible as it is relatively slow
                // (at least compared to a local variable)
                simulatedPosition = tr.position;
            }
            if (updateRotation)
            {
                simulatedRotation = tr.rotation;
            }

            var currentPosition = simulatedPosition;

            // Update which point we are moving towards
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            var dir = movementPlane.ToPlane(steeringTarget - currentPosition);

            // Calculate the distance to the end of the path
            float distanceToEnd = dir.magnitude + Mathf.Max(0, interpolator.remainingDistance);

            // Check if we have reached the target
            var prevTargetReached = reachedEndOfPath;

            reachedEndOfPath = distanceToEnd <= endReachedDistance && interpolator.valid;
            if (!prevTargetReached && reachedEndOfPath)
            {
                OnTargetReached();
            }
            float slowdown;

            // Normalized direction of where the agent is looking
            var forwards = movementPlane.ToPlane(simulatedRotation * (orientation == OrientationMode.YAxisForward ? Vector3.up : Vector3.forward));

            // Check if we have a valid path to follow and some other script has not stopped the character
            if (interpolator.valid && !isStopped)
            {
                // How fast to move depending on the distance to the destination.
                // Move slower as the character gets closer to the destination.
                // This is always a value between 0 and 1.
                slowdown = distanceToEnd < slowdownDistance?Mathf.Sqrt(distanceToEnd / slowdownDistance) : 1;

                if (reachedEndOfPath && whenCloseToDestination == CloseToDestinationMode.Stop)
                {
                    // Slow down as quickly as possible
                    velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
                }
                else
                {
                    velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * maxSpeed, velocity2D, currentAcceleration, rotationSpeed, maxSpeed, forwards) * deltaTime;
                }
            }
            else
            {
                slowdown = 1;
                // Slow down as quickly as possible
                velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
            }

            velocity2D = MovementUtilities.ClampVelocity(velocity2D, maxSpeed, slowdown, slowWhenNotFacingTarget && enableRotation, forwards);

            ApplyGravity(deltaTime);


            // Set how much the agent wants to move during this frame
            var delta2D = lastDeltaPosition = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);

            nextPosition = currentPosition + movementPlane.ToWorld(delta2D, verticalVelocity * lastDeltaTime);
            CalculateNextRotation(slowdown, out nextRotation);
        }
예제 #8
0
    /** Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not */
    protected override void MovementUpdate(float deltaTime)
    {
        if (!canMove)
        {
            return;
        }

        if (!interpolator.valid)
        {
            velocity2D = Vector3.zero;
        }
        else
        {
            var currentPosition = tr.position;

            interpolator.MoveToLocallyClosestPoint(currentPosition, true, false);
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            targetPoint = interpolator.position;
            var dir = movementPlane.ToPlane(targetPoint - currentPosition);

            var distanceToEnd = dir.magnitude + interpolator.remainingDistance;
            // How fast to move depending on the distance to the target.
            // Move slower as the character gets closer to the target.
            float slowdown = slowdownDistance > 0 ? distanceToEnd / slowdownDistance : 1;

            // a = v/t, should probably expose as a variable
            float acceleration = speed / 0.4f;
            velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * speed, velocity2D, acceleration, speed) * deltaTime;
            velocity2D  = MovementUtilities.ClampVelocity(velocity2D, speed, slowdown, true, movementPlane.ToPlane(rotationIn2D ? tr.up : tr.forward));

            ApplyGravity(deltaTime);

            if (distanceToEnd <= endReachedDistance && !TargetReached)
            {
                TargetReached = true;
                OnTargetReached();
            }

            // Rotate towards the direction we are moving in
            var currentRotationSpeed = rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(slowdown) - 0.3f) / 0.7f);
            RotateTowards(velocity2D, currentRotationSpeed * deltaTime);

            if (rvoController != null && rvoController.enabled)
            {
                // Send a message to the RVOController that we want to move
                // with this velocity. In the next simulation step, this
                // velocity will be processed and it will be fed back to the
                // rvo controller and finally it will be used by this script
                // when calling the CalculateMovementDelta method below

                // Make sure that we don't move further than to the end point
                // of the path. If the RVO simulation FPS is low and we did
                // not do this, the agent might overshoot the target a lot.
                var rvoTarget = currentPosition + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, distanceToEnd), 0f);
                rvoController.SetTarget(rvoTarget, velocity2D.magnitude, speed);
            }
            var delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
            Move(currentPosition, movementPlane.ToWorld(delta2D, verticalVelocity * deltaTime));

            velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);
        }
    }
예제 #9
0
        /** Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not */
        protected override void MovementUpdateInternal(float deltaTime, out Vector3 nextPosition, out Quaternion nextRotation)
        {
            float currentAcceleration = maxAcceleration;

            // If negative, calculate the acceleration from the max speed
            if (currentAcceleration < 0)
            {
                currentAcceleration *= -maxSpeed;
            }

            if (updatePosition)
            {
                // Get our current position. We read from transform.position as few times as possible as it is relatively slow
                // (at least compared to a local variable)
                simulatedPosition = tr.position;
            }
            if (updateRotation)
            {
                simulatedRotation = tr.rotation;
            }

            var currentPosition = simulatedPosition;

            // Update which point we are moving towards
            //Good Game
            //interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            interpolator.MoveToCircleIntersection2D((VInt3)currentPosition, pickNextWaypointDist, movementPlane);
            var dir = movementPlane.ToPlane(steeringTarget - currentPosition);

            // Calculate the distance to the end of the path
            float distanceToEnd = dir.magnitude + Mathf.Max(0, interpolator.remainingDistance);

            // Check if we have reached the target
            var prevTargetReached = reachedEndOfPath;

            reachedEndOfPath = distanceToEnd <= endReachedDistance && interpolator.valid;
            if (!prevTargetReached && reachedEndOfPath)
            {
                OnTargetReached();
            }
            float slowdown;

            // Normalized direction of where the agent is looking
            var forwards = movementPlane.ToPlane(simulatedRotation * (rotationIn2D ? Vector3.up : Vector3.forward));

            // Check if we have a valid path to follow and some other script has not stopped the character
            if (interpolator.valid && !isStopped)
            {
                // How fast to move depending on the distance to the destination.
                // Move slower as the character gets closer to the destination.
                // This is always a value between 0 and 1.
                slowdown = distanceToEnd < slowdownDistance?Mathf.Sqrt(distanceToEnd / slowdownDistance) : 1;

                if (reachedEndOfPath && whenCloseToDestination == CloseToDestinationMode.Stop)
                {
                    // Slow down as quickly as possible
                    velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
                }
                else
                {
                    velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * maxSpeed, velocity2D, currentAcceleration, rotationSpeed, maxSpeed, forwards) * deltaTime;
                }
            }
            else
            {
                slowdown = 1;
                // Slow down as quickly as possible
                velocity2D -= Vector2.ClampMagnitude(velocity2D, currentAcceleration * deltaTime);
            }

            velocity2D = MovementUtilities.ClampVelocity(velocity2D, maxSpeed, slowdown, slowWhenNotFacingTarget, forwards);

            ApplyGravity(deltaTime);

            if (rvoController != null && rvoController.enabled)
            {
                // Send a message to the RVOController that we want to move
                // with this velocity. In the next simulation step, this
                // velocity will be processed and it will be fed back to the
                // rvo controller and finally it will be used by this script
                // when calling the CalculateMovementDelta method below

                // Make sure that we don't move further than to the end point
                // of the path. If the RVO simulation FPS is low and we did
                // not do this, the agent might overshoot the target a lot.
                var rvoTarget = currentPosition + movementPlane.ToWorld(Vector2.ClampMagnitude(velocity2D, distanceToEnd), 0f);
                //GG
                //rvoController.SetTarget(rvoTarget, velocity2D.magnitude, maxSpeed);
                rvoController.SetTarget(rvoTarget, (int)(velocity2D.magnitude * 1000), (int)(maxSpeed * 1000));
            }

            // Set how much the agent wants to move during this frame
            var delta2D = lastDeltaPosition = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);

            nextPosition = currentPosition + movementPlane.ToWorld(delta2D, verticalVelocity * lastDeltaTime);
            CalculateNextRotation(slowdown, out nextRotation);
        }
예제 #10
0
    /** Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not */
    protected override void MovementUpdate(float deltaTime)
    {
        if (Zone.changeRange)
        {
            playerRange      = beginPlayerRange;
            playerRange      = playerRange * TutorialStates.rangeMultiplier;
            Zone.changeRange = false;
        }
        if (playerRange <= 0)
        {
            playerRange = beginPlayerRange;
        }
        // draw gizmos bij de civilian
        SurvivorMovement.ranget = targetRange;
        SurvivorMovement.rangeP = playerRange;
        collide = false;
        // target zetten als er geen target is
        if (target == null)
        {
            ChooseTarget();
            previousWaypoint = target;
        }
        //target = GetClosestWaypoint(TutorialWaypoints.pathfindingWaypoints);
        dToPlayer = Vector3.Distance(player.transform.position, transform.position);
        dToTarget = Vector3.Distance(target.transform.position, transform.position);
        // verandert de target naar player als de waypoint in de cirkel is
        waypointMax = TutorialStates.waypointMax;
        if (dToPlayer < playerRange)
        {
            if (targetRange > dToTarget)
            {
                target = previousWaypoint;
                time   = timeReset;
                if (j <= TutorialStates.waypointMax)
                {
                    if (j < TutorialWaypoints.waypoints)
                    {
                        target = TutorialWaypoints.pathfindingWaypoints[j];
                        // Debug.Log("waypoint = " + TutorialWaypoints.pathfindingWaypoints[j] + " J is " + j);
                    }
                    if (j == TutorialStates.waypointMax && TutorialStates.stateName == "Defend")
                    {
                        endPoint = true;
                    }
                    j++;
                    previousWaypoint = target;
                }
            }
        }
        else
        {
            target = gameObject.transform;
        }
        stateName = TutorialStates.stateName;
        /////////////////////////////////////////////////////////////////////////////////
        if (!canMove)
        {
            return;
        }

        if (!interpolator.valid)
        {
            velocity2D = Vector3.zero;
        }
        else
        {
            var currentPosition = tr.position;

            interpolator.MoveToLocallyClosestPoint(currentPosition, true, false);
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            targetPoint = interpolator.position;
            var dir = movementPlane.ToPlane(targetPoint - currentPosition);

            var distanceToEnd = dir.magnitude + interpolator.remainingDistance;
            // How fast to move depending on the distance to the target.
            // Move slower as the character gets closer to the target.
            float slowdown = slowdownDistance > 0 ? distanceToEnd / slowdownDistance : 1;

            // a = v/t, should probably expose as a variable
            float acceleration = speed / 0.4f;
            velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * speed, velocity2D, acceleration, speed) * deltaTime;
            velocity2D  = MovementUtilities.ClampVelocity(velocity2D, speed, slowdown, true, movementPlane.ToPlane(rotationIn2D ? tr.up : tr.forward));

            ApplyGravity(deltaTime);

            if (distanceToEnd <= endReachedDistance && !TargetReached)
            {
                TargetReached = true;
                OnTargetReached();
            }

            // Rotate towards the direction we are moving in
            var currentRotationSpeed = rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(slowdown) - 0.3f) / 0.7f);
            RotateTowards(velocity2D, currentRotationSpeed * deltaTime);

            var delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
            Move(currentPosition, movementPlane.ToWorld(delta2D, verticalVelocity * deltaTime));

            velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);
        }
    }
예제 #11
0
    /** Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not */
    protected override void MovementUpdate(float deltaTime)
    {
        // draw gizmos bij de civilian
        CivilianMovement.ranget = targetRange;
        collide = false;
        // target zetten als er geen target is
        if (target == null)
        {
            target = GetClosestWaypoint(PathfindingWaypoints.pathfindingWaypoints);
        }

        dToTarget = Vector3.Distance(target.transform.position, transform.position);
        if (targetRange > dToTarget && target != player.transform)
        {
            time   = timeReset;
            target = player.transform;
        }
        // verandert de target naar player als de waypoint in de cirkel is
        if (survivor != null)
        {
            if (targetRange > dToTarget && target != survivor.transform)
            {
                time = timeReset;

                tutorial = true;
                target   = survivor.transform;
            }
        }

        //Afstand tussen civilian en bus wordt berekend en als in range veranderd target
        safePlaceRange    = safePlace.transform.position - transform.position;
        distanceSafePlace = safePlaceRange.magnitude;
        if (distanceSafePlace < range)
        {
            target = safePlace.transform;
        }
        /////////////////////////////////////////////////////////////////////////////////
        if (!canMove)
        {
            return;
        }

        if (!interpolator.valid)
        {
            velocity2D = Vector3.zero;
        }
        else
        {
            var currentPosition = tr.position;

            interpolator.MoveToLocallyClosestPoint(currentPosition, true, false);
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            targetPoint = interpolator.position;
            var dir = movementPlane.ToPlane(targetPoint - currentPosition);

            var distanceToEnd = dir.magnitude + interpolator.remainingDistance;
            // How fast to move depending on the distance to the target.
            // Move slower as the character gets closer to the target.
            float slowdown = slowdownDistance > 0 ? distanceToEnd / slowdownDistance : 1;

            // a = v/t, should probably expose as a variable
            float acceleration = speed / 0.4f;
            velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * speed, velocity2D, acceleration, speed) * deltaTime;
            velocity2D  = MovementUtilities.ClampVelocity(velocity2D, speed, slowdown, true, movementPlane.ToPlane(rotationIn2D ? tr.up : tr.forward));

            ApplyGravity(deltaTime);

            if (distanceToEnd <= endReachedDistance && !TargetReached)
            {
                TargetReached = true;
                OnTargetReached();
            }

            // Rotate towards the direction we are moving in
            var currentRotationSpeed = rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(slowdown) - 0.3f) / 0.7f);
            RotateTowards(velocity2D, currentRotationSpeed * deltaTime);

            var delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
            Move(currentPosition, movementPlane.ToWorld(delta2D, verticalVelocity * deltaTime));

            velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);
        }
    }
예제 #12
0
    /** Called during either Update or FixedUpdate depending on if rigidbodies are used for movement or not */
    protected override void MovementUpdate(float deltaTime)
    {
        EnemyBehaviour.ranget     = targetRange;
        EnemyBehaviour.chaseRange = chaseRange;
        // target zetten als er geen target is
        if (target == null)
        {
            if (!EnemiesKilled.KillMode)
            {
                //Kiest tussen de player, defendpoints en civilians
                target = GetClosestWaypoint(PathfindingWaypoints.pathfindingWaypoints);
            }
            else
            {
                // met kill count mission wordt het altijd de player
                target        = player.transform;
                playerInRange = true;
            }
        }
        dToTarget = Vector3.Distance(target.transform.position, transform.position);
        // verandert de target naar player als de waypoint in de cirkel is
        if (targetRange > dToTarget && target != player.transform)
        {
            time   = timeReset;
            target = GetClosestWaypoint(PathfindingWaypoints.pathfindingWaypoints);
        }
        //bepaalt of de defenndpoint, rescuepoint of player in range is
        if (dToTarget < chaseRange)
        {
            playerInRange = true;
        }
        else
        {
            playerInRange = false;
        }

        if (!playerInRange)
        {
            waypointTimer++;

            if (waypointTimer % (60 * 10) == 0 || !placeFound)
            {
                MoveToRandomPoint();
                waypointTimer = 0;
            }

            speed = idleSpeed;
        }
        else
        {
            speed = chaseSpeed;
        }

        ////////////////////////////////////////////////////////////////////////////
        if (!canMove)
        {
            return;
        }

        if (!interpolator.valid)
        {
            velocity2D = Vector3.zero;
        }
        else
        {
            var currentPosition = tr.position;

            interpolator.MoveToLocallyClosestPoint(currentPosition, true, false);
            interpolator.MoveToCircleIntersection2D(currentPosition, pickNextWaypointDist, movementPlane);
            targetPoint = interpolator.position;
            var dir = movementPlane.ToPlane(targetPoint - currentPosition);

            var distanceToEnd = dir.magnitude + interpolator.remainingDistance;
            // How fast to move depending on the distance to the target.
            // Move slower as the character gets closer to the target.
            float slowdown = slowdownDistance > 0 ? distanceToEnd / slowdownDistance : 1;

            // a = v/t, should probably expose as a variable
            float acceleration = speed / 0.4f;
            velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * speed, velocity2D, acceleration, speed) * deltaTime;
            velocity2D  = MovementUtilities.ClampVelocity(velocity2D, speed, slowdown, true, movementPlane.ToPlane(rotationIn2D ? tr.up : tr.forward));

            ApplyGravity(deltaTime);

            if (distanceToEnd <= endReachedDistance && !TargetReached)
            {
                TargetReached = true;
                OnTargetReached();
            }

            // Rotate towards the direction we are moving in
            var currentRotationSpeed = rotationSpeed * Mathf.Clamp01((Mathf.Sqrt(slowdown) - 0.3f) / 0.7f);
            RotateTowards(velocity2D, currentRotationSpeed * deltaTime);

            var delta2D = CalculateDeltaToMoveThisFrame(movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);
            Move(currentPosition, movementPlane.ToWorld(delta2D, verticalVelocity * deltaTime));

            velocity = movementPlane.ToWorld(velocity2D, verticalVelocity);
        }
    }
예제 #13
0
        void TraverseFunnel(RichFunnel fn, float deltaTime)
        {
            // Clamp the current position to the navmesh
            // and update the list of upcoming corners in the path
            // and store that in the 'nextCorners' variable
            float   elevation;
            Vector2 position = movementPlane.ToPlane(UpdateTarget(fn), out elevation);

            // Only find nearby walls every 5th frame to improve performance
            if (Time.frameCount % 5 == 0 && wallForce > 0 && wallDist > 0)
            {
                wallBuffer.Clear();
                fn.FindWalls(wallBuffer, wallDist);
            }

            // Target point
            Vector2 targetPoint = waypoint = movementPlane.ToPlane(nextCorners[0]);
            // Direction to target
            Vector2 dir = targetPoint - position;

            // Is the endpoint of the path (part) the current target point
            bool targetIsEndPoint = lastCorner && nextCorners.Count == 1;

            // Normalized direction to the target
            Vector2 normdir = VectorMath.Normalize(dir, out distanceToWaypoint);
            // Calculate force from walls
            Vector2 wallForceVector = CalculateWallForce(position, elevation, normdir);
            Vector2 targetVelocity;

            if (targetIsEndPoint)
            {
                targetVelocity = slowdownTime > 0 ? Vector2.zero : normdir * maxSpeed;

                // Reduce the wall avoidance force as we get closer to our target
                wallForceVector *= System.Math.Min(distanceToWaypoint / 0.5f, 1);

                if (distanceToWaypoint <= endReachedDistance)
                {
                    // END REACHED
                    NextPart();
                }
            }
            else
            {
                var nextNextCorner = nextCorners.Count > 1 ? movementPlane.ToPlane(nextCorners[1]) : position + 2 * dir;
                targetVelocity = (nextNextCorner - targetPoint).normalized * maxSpeed;
            }

            Vector2 accel = MovementUtilities.CalculateAccelerationToReachPoint(targetPoint - position, targetVelocity, velocity2D, acceleration, maxSpeed);

            // Update the velocity using the acceleration
            velocity2D += (accel + wallForceVector * wallForce) * deltaTime;

            // Distance to the end of the path (as the crow flies)
            var distToEndOfPath = fn.DistanceToEndOfPath;
            var slowdownFactor  = slowdownTime > 0 ? distToEndOfPath / (maxSpeed * slowdownTime) : 1;

            velocity2D = MovementUtilities.ClampVelocity(velocity2D, maxSpeed, slowdownFactor, slowWhenNotFacingTarget, movementPlane.ToPlane(tr.forward));

            ApplyGravity(deltaTime);

            if (rvoController != null && rvoController.enabled)
            {
                // Send a message to the RVOController that we want to move
                // with this velocity. In the next simulation step, this
                // velocity will be processed and it will be fed back to the
                // rvo controller and finally it will be used by this script
                // when calling the CalculateMovementDelta method below

                // Make sure that we don't move further than to the end point
                // of the path. If the RVO simulation FPS is low and we did
                // not do this, the agent might overshoot the target a lot.
                var rvoTarget = movementPlane.ToWorld(position + Vector2.ClampMagnitude(velocity2D, distToEndOfPath), elevation);
                rvoController.SetTarget(rvoTarget, velocity2D.magnitude, maxSpeed);
            }

            // Direction and distance to move during this frame
            var deltaPosition = CalculateDeltaToMoveThisFrame(position, distToEndOfPath, deltaTime);

            // Rotate towards the direction we are moving in
            // Slow down the rotation of the character very close to the endpoint of the path to prevent oscillations
            var rotationSpeedFactor = targetIsEndPoint ? Mathf.Clamp01(1.1f * slowdownFactor - 0.1f) : 1f;

            RotateTowards(deltaPosition, rotationSpeed * rotationSpeedFactor * deltaTime);

            Move(movementPlane.ToWorld(position, elevation), movementPlane.ToWorld(deltaPosition, verticalVelocity * deltaTime));
        }
예제 #14
0
        private void MovementUpdateInternal(float deltaTime)
        {
            // a = v/t, should probably expose as a variable
            var acceleration = MaxSpeed / 0.4f;

            // Get our current position. We read from transform.position as few times as possible as it is relatively slow
            // (at least compared to a local variable)
            var currentPosition = Tr.position;

            // Update which point we are moving towards
            _interpolator.MoveToCircleIntersection2D(currentPosition, _pickNextWaypointDist, _movementPlane);
            var dir = _movementPlane.ToPlane(SteeringTargetV3 - currentPosition);

            // Calculate the distance to the end of the path
            var distanceToEnd = dir.magnitude + MathEx.Max(0, _interpolator.remainingDistance);

            // Check if we have reached the target
            var prevTargetReached = TargetReached;

            TargetReached = distanceToEnd <= _endReachedDistance && _interpolator.valid;
            if (!prevTargetReached && TargetReached)
            {
                MovementCompleted();
            }
            // Check if we have a valid path to follow and some other script has not stopped the character
            float slowdown = 1;

            if (_interpolator.valid)
            {
                // How fast to move depending on the distance to the destination.
                // Move slower as the character gets closer to the destination.
                // This is always a value between 0 and 1.
                if (distanceToEnd < _slowdownDistance)
                {
                    slowdown          = Mathf.Sqrt(distanceToEnd / _slowdownDistance);
                    _slowLerp.Enabled = false;
                }
                else
                {
                    if (_interpolator.ShouldSlow())
                    {
                        if (!_slowLerp.Enabled)
                        {
                            _slowLerp.RestartLerp(1, 0, _slowdownTime);
                        }
                        slowdown = _slowLerp.GetLerpValue();
                    }
                    else
                    {
                        _slowLerp.Enabled = false;
                    }
                }
                if (TargetReached && _goToExactEndPoint)
                {
                    // Slow down as quickly as possible
                    _velocity2D -= Vector2.ClampMagnitude(_velocity2D, acceleration * deltaTime);
                }
                else
                {
                    // Normalized direction of where the agent is looking
                    var forwards = _movementPlane.ToPlane(Tr.rotation * Vector3.forward);
                    _velocity2D += MovementUtilities.CalculateAccelerationToReachPoint(dir, dir.normalized * MaxSpeed, _velocity2D, acceleration, _rotationSpeed, MaxSpeed, forwards) * deltaTime;
                }
            }
            else
            {
                slowdown = 1;
                // Slow down as quickly as possible
                _velocity2D -= Vector2.ClampMagnitude(_velocity2D, acceleration * deltaTime);
            }

            _velocity2D = MovementUtilities.ClampVelocity(
                _velocity2D, MaxSpeed, slowdown, _slowWhenNotFacingTarget,
                _movementPlane.ToPlane(Tr.forward));

            ApplyGravity(deltaTime);

            if (_rvoController != null && _rvoController.enabled)
            {
                // Send a message to the RVOController that we want to move
                // with this velocity. In the next simulation step, this
                // velocity will be processed and it will be fed back to the
                // rvo controller and finally it will be used by this script
                // when calling the CalculateMovementDelta method below

                // Make sure that we don't move further than to the end point
                // of the path. If the RVO simulation FPS is low and we did
                // not do this, the agent might overshoot the target a lot.
                var rvoTarget = currentPosition + _movementPlane.ToWorld(Vector2.ClampMagnitude(_velocity2D, distanceToEnd), 0f);
                _rvoController.SetTarget(rvoTarget, _velocity2D.magnitude, MaxSpeed);
            }

            Vector2 desiredRotationDirection;

            if (_rvoController != null && _rvoController.enabled)
            {
                // When using local avoidance, use the actual velocity we are moving with (delta2D/deltaTime) if that velocity
                // is high enough, otherwise fall back to the velocity that we want to move with (velocity2D).
                // The local avoidance velocity can be very jittery when the character is close to standing still
                // as it constantly makes small corrections. We do not want the rotation of the character to be jittery.
                //var actualVelocity = delta2D / deltaTime;
                var actualVelocity = _lastDeltaPosition / _lastDeltaTime;
                desiredRotationDirection = Vector2.Lerp(_velocity2D, actualVelocity, 4 * actualVelocity.magnitude / (MaxSpeed + 0.0001f));
            }
            else
            {
                desiredRotationDirection = _velocity2D;
            }
            var delta2D = _lastDeltaPosition = CalculateDeltaToMoveThisFrame(_movementPlane.ToPlane(currentPosition), distanceToEnd, deltaTime);

            // Rotate towards the direction we are moving in
            var currentRotationSpeed = _rotationSpeed * MathEx.Max(0, (slowdown - 0.3f) / 0.7f);

            RotateTowards(desiredRotationDirection, currentRotationSpeed * deltaTime);

            var deltaPosition = _movementPlane.ToWorld(delta2D, _verticalVelocity * deltaTime);

            Move(currentPosition, deltaPosition);
        }