Beispiel #1
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            if (target == null || !target.Alive)
            {
                return(Steering.zero);
            }

            Vector3 delta      = Target.Position - actor.Position;
            Vector3 currentVel = actor.Velocity;

            if (manager.IsPlanar)
            {
                delta.y      = 0f;
                currentVel.y = 0f;
            }

            float dist = delta.magnitude;

            if (dist > 0.0f)
            {
                float force = manager.MaxForce * (dist / arriveRadius);
                force  = Mathf.Min(force, manager.MaxForce);
                delta *= force / dist;
            }

            return(new Steering(delta - currentVel, Vector3.zero));
        }
Beispiel #2
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            if (target == null || !target.Alive)
            {
                return Steering.zero;
            }

            Vector3 uVel = actor.Velocity;
            Vector3 uTargetVel = target.Velocity;
            Vector3 deltaPos = target.Position - actor.Position;
            Vector3 targetPos = target.Position;
            if(manager.IsPlanar) {
                uVel.y = 0f;
                uTargetVel.y = 0f;
                deltaPos.y = 0f;
                targetPos.y = 0f;
            }

            uVel.Normalize();
            uTargetVel.Normalize();
            float dv = Vector3.Dot(uVel, uTargetVel);
            if (Vector3.Dot(deltaPos, uVel) < 0f || dv > -0.93f)
            {
                Vector3 vel = uVel * manager.MaxForce;
                float combinedSpeed = (vel + target.Velocity).magnitude;
                if(combinedSpeed > 0f) {
                    float predictionTime = deltaPos.magnitude / combinedSpeed;
                    targetPos += target.Velocity * predictionTime;
                }
            }

            return new Steering(SteerToward(manager, actor, targetPos,
                dt), Vector3.zero);
        }
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            Vector3 dir = actor.Forward;
            if(actor.Velocity.magnitude > velocityFaceThreshold) {
                dir = actor.Velocity / actor.Velocity.magnitude;
            }

            Vector3 delta = Quaternion.FromToRotation(actor.Forward, dir).eulerAngles;
            Vector3 angVel = actor.AngularVelocity;

            if(manager.IsPlanar) {
                angVel.x = 0f;
                delta.x = 0f;
            } else {
                delta.x = Mathf.DeltaAngle(0f, delta.x);
            }

            angVel.z = 0f;
            delta.z = 0.0f;
            delta.y = Mathf.DeltaAngle(0f, delta.y);

            float angDist = delta.magnitude;
            if(angDist > 0.0f) {
                float torque = manager.MaxTorque * (angDist / angleThreshold);
                torque = Mathf.Min(torque, manager.MaxTorque);
                delta *= torque / angDist;
            }
            return new Steering(Vector3.zero, delta - angVel);
        }
Beispiel #4
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            if (target == null || !target.Alive)
            {
                return Steering.zero;
            }

            Vector3 delta = Target.Position - actor.Position;
            Vector3 currentVel = actor.Velocity;
            if(manager.IsPlanar) {
                delta.y = 0f;
                currentVel.y = 0f;
            }

            float dist = delta.magnitude;
            if (dist > 0.0f)
            {
                float force = manager.MaxForce * (dist / arriveRadius);
                force = Mathf.Min(force, manager.MaxForce);
                delta *= force / dist;
            }

            return new Steering(delta - currentVel, Vector3.zero);
        }
Beispiel #5
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            Steering steering = Steering.zero;

            Vector3 forward = actor.Forward;

            forward.y = 0f;
            float   size        = (maxAngle * 2f) / (numRays - 1);
            float   dHalf       = (maxDistance - minDistance) * 0.5f;
            float   dSize       = (maxDistance - minDistance) / (numRays - 1);
            float   totalWeight = 0f;
            Vector3 force       = Vector3.zero;
            Vector3 torque      = Vector3.zero;

            for (int i = 0; i < numRays; i++)
            {
                float angle = -maxAngle + i * size;

                float   weight = 1f - Mathf.Abs(angle / maxAngle) * 0.25f;
                float   dist   = maxDistance - Mathf.Abs(-dHalf + i * dSize);
                Vector3 dir    = Quaternion.AngleAxis(angle, Vector3.up) * forward;
                Debug.DrawLine(actor.Position, actor.Position + dir * dist, new Color(1f, 1f, 0f, weight));
                RaycastHit hit;
                if (Physics.SphereCast(actor.Position, 5f, dir, out hit, dist, mask))
                {
                    float   side    = Vector3.Dot(hit.normal, actor.Right);
                    Vector3 tangent = Vector3.zero;
                    Vector3 half    = Vector3.zero;
                    if (side < 0f)                      // Normal is to the left
                    {
                        tangent = Vector3.Cross(actor.Up, hit.normal);
                        half    = tangent - actor.Right;
                    }
                    else                         // Normal is to the right
                    {
                        tangent = Vector3.Cross(hit.normal, actor.Up);
                        half    = actor.Right - tangent;
                    }
                    tangent.Normalize();
                    half.Normalize();
                    totalWeight += weight;
                    float scale = 1f - hit.distance / maxDistance;
                    Debug.DrawLine(hit.point, hit.point + tangent * manager.MaxForce * scale * weight, new Color(0f, 1f, 1f, scale));
                    Debug.DrawLine(hit.point, hit.point + half * manager.MaxForce * scale * weight, new Color(1f, 0f, 0f, scale));
                    lookTarget.Point = hit.point + tangent;
                    torque          += lookAt.Update(manager, actor, dt).Torque *scale *weight * 0.5f;
                    force           += half * manager.MaxForce * scale * weight;
                }
            }

            steering.Force  = force / (totalWeight > 0f ? totalWeight : 1f);
            steering.Torque = torque;

            return(steering);
        }
Beispiel #6
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            if (target == null || !target.Alive)
            {
                return(Steering.zero);
            }

            return(new Steering(SteerToward(manager, actor,
                                            target.Position, dt), Vector3.zero));
        }
Beispiel #7
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            if (target == null || !target.Alive)
            {
                return Steering.zero;
            }

            return new Steering(SteerToward(manager, actor,
                target.Position, dt), Vector3.zero);
        }
Beispiel #8
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            float angle = Random.Range(-maxDeviation, maxDeviation);

            wanderAngle += angle;
            int     radius  = 200;
            Vector3 currPos = actor.Position;
            float   x       = currPos.x + radius * Mathf.Cos(wanderAngle);
            float   z       = currPos.z + radius * Mathf.Sin(wanderAngle);

            target.Point = new Vector3(x, currPos.y, z);
            return(base.Update(manager, actor, dt));
        }
        /// <summary>
        /// Steer away from the given point.
        /// </summary>
        /// <param name="actor">The actor for steering.</param>
        /// <param name="target">The target point.</param>
        /// <param name="dt">The delta time since the last call.</param>
        /// <returns></returns>
        protected Vector3 SteerAway(SteeringManager manager, Actor actor,
			Vector3 target, float dt)
        {
            Vector3 desired = actor.Position - target;

            if(manager.IsPlanar) {
                desired.y = 0f;
            }

            float dist = desired.magnitude;
            if (dist > 0.0f)
            {
                desired *= manager.MaxForce / dist;
                return desired - actor.Velocity;
            }
            return Vector3.zero;
        }
Beispiel #10
0
        /// <summary>
        /// Steer away from the given point.
        /// </summary>
        /// <param name="actor">The actor for steering.</param>
        /// <param name="target">The target point.</param>
        /// <param name="dt">The delta time since the last call.</param>
        /// <returns></returns>
        protected Vector3 SteerAway(SteeringManager manager, Actor actor,
                                    Vector3 target, float dt)
        {
            Vector3 desired = actor.Position - target;

            if (manager.IsPlanar)
            {
                desired.y = 0f;
            }

            float dist = desired.magnitude;

            if (dist > 0.0f)
            {
                desired *= manager.MaxForce / dist;
                return(desired - actor.Velocity);
            }
            return(Vector3.zero);
        }
Beispiel #11
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            if (target == null || !target.Alive)
            {
                return(Steering.zero);
            }

            Vector3 dir    = target.Position - actor.Position;
            Vector3 facing = actor.Forward;

            dir.y    = manager.IsPlanar ? 0f : dir.y;
            facing.y = manager.IsPlanar ? 0f : facing.y;

            Vector3 delta  = Quaternion.FromToRotation(facing, dir).eulerAngles;
            Vector3 angVel = actor.AngularVelocity;

            if (manager.IsPlanar)
            {
                angVel.x = 0f;
                delta.x  = 0f;
            }
            else
            {
                delta.x = Mathf.DeltaAngle(0f, delta.x);
            }

            angVel.z = 0f;
            delta.z  = 0.0f;
            delta.y  = Mathf.DeltaAngle(0f, delta.y);

            float angDist = delta.magnitude;

            if (angDist > 0.0f)
            {
                float torque = manager.MaxTorque * (angDist / angleThreshold);
                torque = Mathf.Min(torque, manager.MaxTorque);
                delta *= torque / angDist;
            }
            return(new Steering(Vector3.zero, delta - angVel));
        }
Beispiel #12
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            if (target == null || !target.Alive)
            {
                return(Steering.zero);
            }

            Vector3 uVel       = actor.Velocity;
            Vector3 uTargetVel = target.Velocity;
            Vector3 deltaPos   = target.Position - actor.Position;
            Vector3 targetPos  = target.Position;

            if (manager.IsPlanar)
            {
                uVel.y       = 0f;
                uTargetVel.y = 0f;
                deltaPos.y   = 0f;
                targetPos.y  = 0f;
            }

            uVel.Normalize();
            uTargetVel.Normalize();
            float dv = Vector3.Dot(uVel, uTargetVel);

            if (Vector3.Dot(deltaPos, uVel) < 0f || dv > -0.93f)
            {
                Vector3 vel           = uVel * manager.MaxForce;
                float   combinedSpeed = (vel + target.Velocity).magnitude;
                if (combinedSpeed > 0f)
                {
                    float predictionTime = deltaPos.magnitude / combinedSpeed;
                    targetPos += target.Velocity * predictionTime;
                }
            }

            return(new Steering(SteerToward(manager, actor, targetPos,
                                            dt), Vector3.zero));
        }
Beispiel #13
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
                                        float dt)
        {
            Vector3 dir = actor.Forward;

            if (actor.Velocity.magnitude > velocityFaceThreshold)
            {
                dir = actor.Velocity / actor.Velocity.magnitude;
            }

            Vector3 delta  = Quaternion.FromToRotation(actor.Forward, dir).eulerAngles;
            Vector3 angVel = actor.AngularVelocity;

            if (manager.IsPlanar)
            {
                angVel.x = 0f;
                delta.x  = 0f;
            }
            else
            {
                delta.x = Mathf.DeltaAngle(0f, delta.x);
            }

            angVel.z = 0f;
            delta.z  = 0.0f;
            delta.y  = Mathf.DeltaAngle(0f, delta.y);


            float angDist = delta.magnitude;

            if (angDist > 0.0f)
            {
                float torque = manager.MaxTorque * (angDist / angleThreshold);
                torque = Mathf.Min(torque, manager.MaxTorque);
                delta *= torque / angDist;
            }
            return(new Steering(Vector3.zero, delta - angVel));
        }
Beispiel #14
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            if (target == null || !target.Alive)
            {
                return Steering.zero;
            }

            Vector3 dir = target.Position - actor.Position;
            Vector3 facing = actor.Forward;

            dir.y = manager.IsPlanar ? 0f : dir.y;
            facing.y = manager.IsPlanar ? 0f : facing.y;

            Vector3 delta = Quaternion.FromToRotation(facing, dir).eulerAngles;
            Vector3 angVel = actor.AngularVelocity;

            if(manager.IsPlanar) {
                angVel.x = 0f;
                delta.x = 0f;
            } else {
                delta.x = Mathf.DeltaAngle(0f, delta.x);
            }

            angVel.z = 0f;
            delta.z = 0.0f;
            delta.y = Mathf.DeltaAngle(0f, delta.y);

            float angDist = delta.magnitude;
            if(angDist > 0.0f) {
                float torque = manager.MaxTorque * (angDist / angleThreshold);
                torque = Mathf.Min(torque, manager.MaxTorque);
                delta *= torque / angDist;
            }
            return new Steering(Vector3.zero, delta - angVel);
        }
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            Steering steering = Steering.zero;

            Vector3 forward = actor.Forward;
            forward.y = 0f;
            float size = (maxAngle * 2f) / (numRays - 1);
            float dHalf = (maxDistance - minDistance) * 0.5f;
            float dSize = (maxDistance - minDistance) / (numRays - 1);
            float totalWeight = 0f;
            Vector3 force = Vector3.zero;
            Vector3 torque = Vector3.zero;
            for(int i = 0; i < numRays; i ++) {
                float angle = -maxAngle + i * size;

                float weight = 1f - Mathf.Abs(angle / maxAngle) * 0.25f;
                float dist = maxDistance - Mathf.Abs(-dHalf + i * dSize);
                Vector3 dir = Quaternion.AngleAxis(angle, Vector3.up) * forward;
                Debug.DrawLine(actor.Position, actor.Position + dir * dist, new Color(1f, 1f, 0f, weight));
                Collider[] col = Physics.OverlapSphere(actor.Position + dir * dist * .5f,
                                                       dist * .5f, mask);
                if(col.Length > 0) {
                    RaycastHit hit;
                    Ray r = new Ray (actor.Position, col[0].transform.position - actor.Position);
                    col[0].Raycast (r, out hit, dist);
                    float side = Vector3.Dot(hit.normal, actor.Right);
                    Vector3 tangent = Vector3.zero;
                    Vector3 half = Vector3.zero;
                    if(side < 0f) { // Normal is to the left
                        tangent = Vector3.Cross(actor.Up, hit.normal);
                        half = tangent - actor.Right;
                    } else { // Normal is to the right
                        tangent = Vector3.Cross(hit.normal, actor.Up);
                        half = actor.Right - tangent;
                    }
                    // tangent.Normalize();
                    // half.Normalize();
                    totalWeight += weight;
                    float scale = 1f - hit.distance / maxDistance;
                    Debug.DrawLine(hit.point, hit.point + tangent * manager.MaxForce * scale * weight, new Color(0f, 1f, 1f, scale));
                    Debug.DrawLine(hit.point, hit.point + half * manager.MaxForce * scale * weight, new Color(1f, 0f, 0f, scale));
                    lookTarget.Point = hit.point + tangent;
                    torque += lookAt.Update(manager, actor, dt).Torque * scale * weight * 0.5f;
                    force += half * manager.MaxForce * scale * weight;
                }
            }

            steering.Force = force / (totalWeight > 0f ? totalWeight : 1f);
            steering.Torque = torque;

            return steering;
        }
Beispiel #16
0
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="manager">The steering manager.</param>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public override Steering Update(SteeringManager manager, Actor actor,
			float dt)
        {
            float angle = Random.Range(-maxDeviation, maxDeviation);
            wanderAngle += angle;
            int radius = 200;
            Vector3 currPos = actor.Position;
            float x = currPos.x + radius * Mathf.Cos(wanderAngle);
            float z = currPos.z + radius * Mathf.Sin(wanderAngle);
            target.Point = new Vector3(x, currPos.y, z);
            return base.Update(manager, actor, dt);
        }
Beispiel #17
0
 /// <summary>
 /// Update the behavior.
 /// </summary>
 /// <param name="actor">The actor being updated.</param>
 /// <param name="dt">The time since the last update, in seconds.
 /// </param>
 /// <returns>The steering object.</returns>
 public abstract Steering Update(SteeringManager manager, Actor actor,
                                 float dt);
        /// <summary>
        /// Update the behavior.
        /// </summary>
        /// <param name="actor">The actor being updated.</param>
        /// <param name="dt">The time since the last update, in seconds.
        /// </param>
        /// <returns>The steering object.</returns>
        public abstract Steering Update(SteeringManager manager, Actor actor,
			float dt);