예제 #1
0
        // FLIGHT //
        private void ProcessFlight()
        {
            Vector3 relativeVel          = attachedBody.transform.InverseTransformDirection(attachedBody.velocity);
            bool    goingForward         = relativeVel.z > 0.01f;
            float   distanceToInteract   = parentCreature.getCreatureStats().getDistanceFromTargetBeforeConsideredReached();
            bool    needDirectionForward = Mathf.Abs(attachedAgent.GetDistanceZFromDestination()) > distanceToInteract /
                                           miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Z_Engine_Dist_To_Act_FWD_Factor];
            bool needDirectionUp = attachedAgent.GetDistanceYFromDestination() < distanceToInteract *
                                   miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Y_Engine_Dist_To_Act_UP_Mult];
            bool goingUp = (relativeVel.y > .01f);

            attachedAgent.SetBrakeRequestToZero();

            // Loop through axis //
            for (int count = 0; count < 3; count++)
            {
                EngineMovementVariables engine = engineMovementVariables[count];
                engine.Update();
                if (engineMovementVariables[count].CurrentState == MovementState.STARTING)
                {
                    continue;
                }

                bool goingPlusDirection;
                bool needToGoPlusDirection;
                if (engine.flightDirection == Direction.Y)
                {
                    goingPlusDirection    = goingUp;
                    needToGoPlusDirection = needDirectionUp;
                }
                else if (engine.flightDirection == Direction.Z)
                {
                    goingPlusDirection    = goingForward;
                    needToGoPlusDirection = needDirectionForward;
                }
                else // X AXIS
                {
                    float kickInIfMoreThan =
                        miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_X_Engine_Kick_In_When_Faster_Than];
                    // Speed on X axis //
                    if (relativeVel.x > kickInIfMoreThan)
                    {
                        needToGoPlusDirection = false;
                        goingPlusDirection    = true;
                    }
                    else if (relativeVel.x < -kickInIfMoreThan)
                    {
                        needToGoPlusDirection = true;
                        goingPlusDirection    = false;
                    }
                    // Not much movement on X axis //
                    else
                    {
                        // Dummy values since these will be skipped //
                        needToGoPlusDirection = false;
                        goingPlusDirection    = false;
                    }
                }

                // Make throttle adjustments //
                MovementState desiredState = MovementState.NONE;
                if (!goingPlusDirection && needToGoPlusDirection && !engine._engineLocked)
                {
                    desiredState = MovementState.FORWARD;
                }
                else if (goingPlusDirection && !needToGoPlusDirection && !engine._engineLocked)
                {
                    if (engine.flightDirection != Direction.X)
                    {
                        desiredState = MovementState.IDLE;
                    }
                    else
                    {
                        desiredState = MovementState.REVERSE;
                    }
                }
                else if (!goingPlusDirection && !needToGoPlusDirection && !engine._engineLocked)
                {
                    if (engine.flightDirection == Direction.Y)
                    {
                        if (attachedAgent.IsCollidingWithSomethingOnAxis(Direction.Y))
                        {
                            Debug.LogWarning("Hitting ground, throttle to Y");
                            desiredState = MovementState.FORWARD;
                        }
                        else
                        {
                            desiredState = MovementState.IDLE;
                        }
                    }
                    else
                    {
                        desiredState = MovementState.IDLE;
                    }
                }
                else
                {
                    float timeToCollision = -1;

                    // CALCULATE NEARBY COLLISIONS //
                    if (!attachedAgent.ignoreIncomingCollisions)
                    {
                        timeToCollision = attachedAgent.TimeToCollisionAtCurrentVel;
                        // Imminenet Collision //
                        float collisionProblem =
                            miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Reverse_Engine_If_Colliding_In];
                        if (goingPlusDirection && needToGoPlusDirection)
                        {
                            // Z Engine, go into reverse if we're going to collide //
                            if (timeToCollision < collisionProblem &&
                                engine.flightDirection == Direction.Z)
                            {
                                if (engine.CurrentState != MovementState.REVERSE)
                                {
                                    engine.SetState(MovementState.REVERSE);
                                }
                            }
                        }

                        // X Engine, move to the side to avoid collision in front //
                        if (engine.flightDirection == Direction.X)
                        {
                            if ((timeToCollision < collisionProblem) ||
                                (attachedAgent.GetDistanceBeforeCollision(CreatureUtilities.RayCastDirection.FORWARD)
                                 < 1))
                            {
                                engineMovementVariables[(int)Direction.X]._engineLocked = true;
                                float distanceLeft = attachedAgent.GetDistanceBeforeCollision(CreatureUtilities.RayCastDirection.LEFT);
                                // If the Left is clear, don't bother checking Right //
                                float distanceRight;
                                if (distanceLeft != Mathf.Infinity)
                                {
                                    distanceRight = attachedAgent.GetDistanceBeforeCollision(CreatureUtilities.RayCastDirection.RIGHT);
                                }
                                else
                                {
                                    distanceRight = 0;
                                }
                                if (distanceLeft > distanceRight)
                                {
                                    if (engine.CurrentState != MovementState.REVERSE)
                                    {
                                        engine.SetState(MovementState.REVERSE);
                                    }
                                }
                                else
                                {
                                    if (engine.CurrentState != MovementState.FORWARD)
                                    {
                                        engine.SetState(MovementState.FORWARD);
                                    }
                                }
                            }
                            else
                            {
                                engineMovementVariables[(int)Direction.X]._engineLocked = false;
                            }
                        }
                    }
                }
                if (engine.CurrentState != desiredState && desiredState != MovementState.NONE)
                {
                    engine.SetState(desiredState);
                }
            }
            // If close to target apply brakes //
            if (attachedAgent.GetDistanceFromDestination() < distanceToInteract *
                attachedAgent.slowDownModifier && !attachedAgent.GetRigidBody().isKinematic)
            {
                if (relativeVel.magnitude >
                    miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Max_Vel_Mag_Before_Brake])
                {
                    Vector3 amount = Vector3.one;
                    attachedAgent.ApplyBrake(amount *
                                             miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Angular_Velocity_Brake_When_Over], true);
                    attachedAgent.ApplyBrake(amount *
                                             miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Angular_Velocity_Brake_When_Over], false);
                    //Debug.LogWarning("Applying brake, close to target - " + amount);
                }
            }
            float magnitude = attachedBody.velocity.magnitude;

            if (magnitude > attachedAgent.maxVelocityMagnitude)
            {
                attachedAgent.ApplyBrake(attachedBody.velocity *
                                         miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Max_Vel_Magnitude_Brake_Multiplier], false);
            }
            // END FLIGHT PROCESSING //
        }
예제 #2
0
 private void Flight(ActionStep.Actions currentCreatureAction)
 {
     if (currentCreatureAction == ActionStep.Actions.MoveTo)
     {
         EngineMovementVariables engineZ = engineMovementVariables[(int)Direction.Z];
         EngineMovementVariables engineY = engineMovementVariables[(int)Direction.Y];
         EngineMovementVariables engineX = engineMovementVariables[(int)Direction.X];
         Vector3 relativeVel             = attachedBody.transform.InverseTransformDirection(attachedBody.velocity);
         float   distFromGround          = attachedAgent.GetDistanceBeforeCollision(CreatureUtilities.RayCastDirection.DOWN);
         float   distanceFromFirstZHit   = attachedAgent.GetDistanceBeforeCollision(
             CreatureUtilities.RayCastDirection.FORWARD);
         float objectBlockDistance   = miscVariables[MiscVariables.AgentMiscVariables.Part_Flight_Halt_Forward_Movement_If_Object_Is_Distance];
         bool  objectBlockingForward = distanceFromFirstZHit < objectBlockDistance;
         //Debug.LogWarning("Distance from first z- " + distanceFromFirstZHit);
         MovementState stateToSetY = MovementState.IDLE;
         // Moving down or close to ground, throttle up //
         if (relativeVel.y < -.5f || distFromGround < attachedAgent.GetSustainHeight())
         {
             stateToSetY = MovementState.FORWARD;
         }
         else if (distFromGround == Mathf.Infinity)
         {
             if (attachedBody.position.y < Area.MinimumHeight)
             {
                 stateToSetY = MovementState.FORWARD;
             }
             else if (attachedBody.position.y > Area.MaximumHeight)
             {
                 stateToSetY = MovementState.IDLE;
             }
         }
         // Moving up, throttle idle
         else if (relativeVel.y > .5f)
         {
             stateToSetY = MovementState.IDLE;
         }
         else
         {
             stateToSetY = MovementState.IDLE;
         }
         if (engineY.CurrentState != stateToSetY)
         {
             engineY.SetState(stateToSetY);
         }
         // Don't move forward if we're blocked //
         if (engineZ.CurrentState != MovementState.FORWARD && !objectBlockingForward)
         {
             engineZ.SetState(MovementState.FORWARD);
         }
         if (objectBlockingForward)
         {
             float distanceRight = attachedAgent.GetDistanceBeforeCollision(CreatureUtilities.RayCastDirection.RIGHT);
             float distanceLeft  = attachedAgent.GetDistanceBeforeCollision(CreatureUtilities.RayCastDirection.LEFT);
             if (engineX.CurrentState == MovementState.IDLE)
             {
                 bool goRight = distanceLeft < distanceRight;
                 if (goRight)
                 {
                     engineX.SetState(MovementState.FORWARD);
                 }
                 else
                 {
                     engineX.SetState(MovementState.REVERSE);
                 }
             }
             if (engineZ.CurrentState == MovementState.FORWARD)
             {
                 engineZ.SetState(MovementState.IDLE);
             }
             else if (engineZ.CurrentState == MovementState.IDLE &&
                      distanceFromFirstZHit < .5f)
             {
                 engineZ.SetState(MovementState.REVERSE);
             }
             else if (engineZ.CurrentState == MovementState.REVERSE &&
                      distanceFromFirstZHit >= .5f)
             {
                 engineZ.SetState(MovementState.IDLE);
             }
         }
         else
         {
             if (engineX.CurrentState != MovementState.IDLE)
             {
                 engineX.SetState(MovementState.IDLE);
             }
         }
     }
 }