コード例 #1
0
    // at each update: //
    private void Update()
    {
        // if: the player is ready to jump, the player is terrained or midair jumping is available, locomotion input is enabled and allowed, locomotion input is pressing, this jumper's priority is not overridden: //
        if (JumpingSettings.jumpingReady() && (TerrainResponse.terrained() || JumpingSettings.midairJumpingAvailable()) && locomotionInputEnabledAndAllowed() && controller.inputPressing(inputsLocomotion) && !priorityOverridden())
        {
            // handle midair jumping //
            if (!TerrainResponse.terrained())
            {
                Vector3 playerVelocity = PlayerVelocityReader.velocity();

                if (midairJumpingReplacesVelocity && ((playerVelocity.y < forceAmount) || (Flipper.flipped && (playerVelocity.y > -forceAmount))))
                {
                    playerRigidbody.velocity = new Vector3(playerVelocity.x, 0f, playerVelocity.z);
                }

                if (!JumpingSettings.midairJumpingInfinite())
                {
                    JumpingSettings.decrementMidairJumpsCount();
                }
            }

            // play the attached jumping audio //
            playJumpingAudio();

            // change the player's velocity for this jumping //
            playerRigidbody.velocity += new Vector3(0f, (Flipper.flipped ? -forceAmount : forceAmount), 0f);

            // have Jumping Settings track the time of the last jump as right now //
            JumpingSettings.trackTimeOfLastJump();
        }
    }
コード例 #2
0
    public float minElapseSinceUnterrainingUntilTerraining     = .5f; // setting: the min required time to elapse since the last successful unterraining audio playing until terraining audio may play



    // methods //


    // methods for: adjusting volume //

    // method: calculate the current player speed (but adjust it to affect the volume accordingly if playing terraining audio) //
    protected override float currentPlayerSpeed()
    {
        if ((Time.time - timeOfLastSuccessfulTerrainingAudioPlaying) <= jumpingTerrainingAudio.length)
        {
            return(speedMax);
        }
        else
        {
            return(PlayerVelocityReader.speedY());
        }
    }
コード例 #3
0
    // method: have the audio source play a random footstep audio, plan to vibrate for the footstep based on the vibration settings, and plan to do this again after the duration of that audio has passed //
    private void playRandomFootstepRecursively()
    {
        // determine the footstep audios not played previously (to prevent adjacent repeats in the consecutive randomization), as well as the corresponding sources and indeces //
        List <AudioClip>   footstepAudiosNotPlayedPreviously        = new List <AudioClip>();
        List <AudioSource> footstepAudiosNotPlayedPreviouslySources = new List <AudioSource>();
        List <int>         footstepAudiosNotPlayedPreviouslyIndeces = new List <int>();

        for (int footstepAudioIndex = 0; footstepAudioIndex < footstepAudios.Length; footstepAudioIndex++)
        {
            if (footstepAudioIndex != previousFootstepAudioIndex)
            {
                footstepAudiosNotPlayedPreviously.Add(footstepAudios[footstepAudioIndex]);
                footstepAudiosNotPlayedPreviouslySources.Add(footstepAudioSources[footstepAudioIndex]);
                footstepAudiosNotPlayedPreviouslyIndeces.Add(footstepAudioIndex);
            }
        }

        // choose a random footstep audio (only out of the footstep audios not played previously); also track its index (out of the entire audios array) //
        int         randomizationIndex        = Random.Range(0, footstepAudiosNotPlayedPreviously.Count);       // determine the randomization index (out of the audios not played previously)
        AudioClip   randomFootstepAudio       = footstepAudiosNotPlayedPreviously[randomizationIndex];
        AudioSource randomFootstepAudioSource = footstepAudiosNotPlayedPreviouslySources[randomizationIndex];
        int         randomFootstepAudioIndex  = footstepAudiosNotPlayedPreviouslyIndeces[randomizationIndex];

        // track the index of the previously played footstep audio as this one (for next time) //
        previousFootstepAudioIndex = randomFootstepAudioIndex;

        // play the random footstep audio //
        randomFootstepAudioSource.PlayOneShot(randomFootstepAudio);

        // if vibration is enabled: plan to vibrate for the footstep after the set vibration prewait duration //
        if (vibrationEnabled)
        {
            Invoke("vibrateForFootstep", vibrationPrewait);
        }

        // determine the interval duration //
        float intervalDuration = randomFootstepAudio.length;   // initialize the interval duration to the played footstep audio's length as a default
        float playerSpeed      = PlayerVelocityReader.speed(); // determine the player's current speed

        if (playerSpeed < speedMid)                            // if the player's current speed below the mid speed reference: interpolate from min to mid
        {
            float playerSpeedRangeRatio = ((playerSpeed - speedMin) / (speedMid - speedMin));
            intervalDuration = speedIntervalCurve.clamped(intervalMax, intervalMid, playerSpeedRangeRatio);
        }
        else                    // otherwise (if the player's current speed is at or above the mid speed reference): interpolate from mid to max
        {
            float playerSpeedRangeRatio = ((playerSpeed - speedMid) / (speedMax - speedMid));
            intervalDuration = speedIntervalCurve.clamped(intervalMid, intervalMin, playerSpeedRangeRatio);
        }

        // plan to do this again after the determined interval duration has passed //
        Invoke("playRandomFootstepRecursively", intervalDuration);
    }
コード例 #4
0
    // upon uncolliding: //
    private void OnCollisionExit(Collision collision)
    {
        GameObject collidedObject = collision.gameObject;                       // connect to the collided object

        // liftoff event triggering (based on collision exit from a recognized terrain) //
        if (recognizedTerrainLayerIndex(collidedObject.layer))
        {
            // broadcast liftoff event – this is ordered to happen before untracking being collided with terrain so that any methods pending a liftoff event can check whether the player is terrained (versus merely collided with terrain)... although after testing, the event timing doesn't seem to be guaranteed so an unterraining event was implemented //
            if (liftoffEvent != null)
            {
                liftoffEvent();
            }
            // determine whether the collided terrain is ground or not //
            bool ground = recognizedGroundTerrainLayerIndex(collidedObject.layer);
            // if applicable: play liftoff feedback (audio) //
            if ((ground || feedbackForNongroundTerrainCollision) && dependenciesFeedback.areMet() && (dependenciesFeedbackNonboostingSpeedThresholdIgnorance.areMet() || Booster.eitherHandIsBoosting() || PlayerVelocityReader.speed() >= feedbackNonboostingSpeedThreshold))
            {
                // if the duration of the min interval for time between feedback attempts for the same (either liftoff\landing) event has passed since the last attempt: //
                if (timeSince(timeOfLastAttemptedLiftoffFeedback) >= minFeedbackInterval)
                {
                    // play a random liftoff audio //
                    playRandomLiftoffAudio();
                }

                // track the time of the last attempted liftoff feedback as now //
                timeOfLastAttemptedLiftoffFeedback = time;
            }
            // track this terrain as not a collided terrain //
            collidedTerrains.Remove(collidedObject);
            if (ground)
            {
                collidedGroundTerrains.Remove(collidedObject);
            }
            else
            {
                collidedNongroundTerrains.Remove(collidedObject);
            }
        }
    }
コード例 #5
0
    // upon colliding: //
    private void OnCollisionEnter(Collision collision)
    {
        GameObject collidedObject = collision.gameObject;                       // connect to the collided object

        // landing event triggering (based on colliding with a recognized terrain) //
        if (recognizedTerrainLayerIndex(collidedObject.layer))
        {
            // determine whether the collided terrain is ground or not //
            bool ground = recognizedGroundTerrainLayerIndex(collidedObject.layer);
            // if applicable: play landing feedback (vibration and audio) //
            if ((ground || feedbackForNongroundTerrainCollision) && dependenciesFeedback.areMet() && (dependenciesFeedbackNonboostingSpeedThresholdIgnorance.areMet() || Booster.eitherHandIsBoosting() || PlayerVelocityReader.speed() >= feedbackNonboostingSpeedThreshold))
            {
                // if the duration of the min interval for time between feedback attempts for the same (either liftoff\landing) event has passed since the last attempt: //
                if (timeSince(timeOfLastAttemptedLandingFeedback) >= minFeedbackInterval)
                {
                    // if each controller is on, respectively: extendedly vibrate it (with default duration and intensity) //
                    if (Controller.left)
                    {
                        Controller.left.vibrateExtended(vibrationDuration, vibrationIntensity);
                    }
                    if (Controller.right)
                    {
                        Controller.right.vibrateExtended(vibrationDuration, vibrationIntensity);
                    }
                    // play a random landing audio //
                    playRandomLandingAudio();
                }

                // track the time of the last attempted landing feedback as now //
                timeOfLastAttemptedLandingFeedback = time;
            }
            // track this terrain as a collided terrain //
            collidedTerrains.Add(collidedObject);
            if (ground)
            {
                collidedGroundTerrains.Add(collidedObject);
            }
            else
            {
                collidedNongroundTerrains.Add(collidedObject);
            }
            // broadcast landing event – this is ordered to happen after tracking being collided with terrain so that any methods pending a landing event can check whether the player is terrained (versus merely collided with terrain)... although after testing, the event timing doesn't seem to be guaranteed so a terraining event was implemented //
            if (landingEvent != null)
            {
                landingEvent();
            }
        }
    }
コード例 #6
0
    // at each physics update: //
    private void FixedUpdate()
    {
        // fuel production
        // (updated alongside physics so that it stays in sync with the fuel usage drawn by boosting forces (such that if, for example, fuel force is produced at a rate of 100, and the force being applied is 100, the current fuel force amount will not change))
        BoosterFuelSupply.addFuelForce(this, BoosterRefueler.productionAmount(this));

        // determining whether this booster's automator is currently automating //
        bool automating = BoosterAutomator.automating(this);

        // boosting inputting, modules handling, and corresponding updating //
        if (!BoosterHalter.halted(this) && ((BoosterToggler.enabledBoosting(this) && locomotionInputEnabledAndAllowed() && controller.inputPressed(inputsLocomotion)) || automating))             // if this booster's halter isn't currently halting boosting, and either boosting is enabled while the input is pressed at all or this booster's automator is automating
        {
            // initializing boosting values //
            float  forceShallow       = BoosterForceApplier.amountShallow(this);
            float  forceDeep          = BoosterForceApplier.amountDeep(this);
            float  forceAmount        = (forceShallow + forceDeep) / 2f;
            ushort vibrationIntensity = BoosterVibrator.intensityShallow(this);

            // determining the currently accessible fuel amount //
            float accessibleFuelAmount = BoosterFuelSupply.accessibleFuelForce(this);

            // determine whether the deep force fuel threshold is met by either being "swung open" (like a floodgate) by already deep boosting, or by being at or above the deep force fuel threshold (per Booster Force Applier) //
            bool deepForceFuelThresholdMet = (boostingDeeply || (accessibleFuelAmount >= BoosterForceApplier.fuelThresholdForBooster(this)));

            // determining whether the booster automator is using fuel //
            bool automatorUsingFuel = BoosterAutomator.usingFuel(this);

            // determining whether there is enough fuel for shallow force boosting andor deep force boosting //
            bool enoughFuelForShallowForce = ((accessibleFuelAmount >= forceShallow) || (automating && !automatorUsingFuel));
            bool enoughFuelForDeepForce    = ((accessibleFuelAmount >= forceDeep) && deepForceFuelThresholdMet);

            // determining boosting values - shallow //
            if ((!controller.inputDeeped(inputsLocomotion) && enoughFuelForShallowForce) || (controller.inputDeeped(inputsLocomotion) && !enoughFuelForDeepForce && enoughFuelForShallowForce))                         // whether either is true: the input is not deeped and there is enough fuel for shallow force, the input is deeped but there is not enough fuel for deep force yet there is enough fuel for shallow force
            {
                boosting       = true;
                boostingDeeply = false;

                forceAmount        = forceShallow;
                vibrationIntensity = BoosterVibrator.intensityShallow(this);
            }
            // determining boosting values - deep //
            else if (enoughFuelForDeepForce)                            // otherwise (if the input is deeped), if there is enough fuel for deep force
            {
                boosting       = true;
                boostingDeeply = true;

                forceAmount        = forceDeep;
                vibrationIntensity = BoosterVibrator.intensityDeep(this);
            }
            // determining to not be boosting due to lack of fuel, and having the fuel sputtering play accordingly (if actually inputting) //
            else
            {
                boosting       = false;
                boostingDeeply = false;

                if (controller.inputPressing(inputsLocomotion))                         // only if this booster is receiving input, since the Booster Automator is smart enough to not try to boost when there is no fuel so it doesn't sputter
                {
                    BoosterFuelSputterer.sputter(this);
                }
            }

            // boosting (if at least shallow force is boosting) //
            if (boosting)
            {
                // determine the player's current velocity //
                Vector3 currentPlayerVelocity = PlayerVelocityReader.velocity();
                // determining the rotation vector for the force direction relative to this booster //
                Vector3 forceDirectionRelative = BoosterForceApplier.direction(this).asDirectionRelativeTo(BoosterRelativizer.relativityTransform(this));
                // determining the speed of the player's rigidbody in the direction of the booster's force aiming //
                float bodySpeedInBoosterDirection = Vector3.Dot(currentPlayerVelocity, forceDirectionRelative);
                // fuel usage via Booster Defueler //
                if (!(automating && !automatorUsingFuel))                               // only if not automatically boosting without using fuel
                {
                    BoosterDefueler.defuel(this, forceAmount);
                }
                // application of boosting force //
                if (!BoosterSpeedLimiter.speedLimited(this) || (bodySpeedInBoosterDirection < BoosterSpeedLimiter.boosterSpeedLimit(this)))                       // if limiting the speed is currently unecessary
                {
                    // boosting force to apply (in the specified direction (originally/ by default, opposite the expelling of the booster)) //
                    Vector3 forceToApply = forceDirectionRelative * forceAmount * Time.fixedDeltaTime;
                    forceToApply *= BoosterForceMultiplier.forceFactor(this);                     // adjust the force to apply by the force factor provided by the corresponding Booster Force Multiplier
                    if (BoosterPulser.pulsingForcePercentage(this) != 0f)                         // add the pulsing force (based on the corresponding Booster Pulser) to the force to apply
                    {
                        if (BoosterPulser.pulsingPlayerUpDirectionOnly(this))
                        {
                            Vector3 playerUpDirection           = BasicDirection.up.asDirectionRelativeTo(playerTransform);
                            float   forceToApplyForPlayerUpOnly = Vector3.Dot(forceToApply, playerUpDirection);
                            forceToApply += (playerUpDirection * forceToApplyForPlayerUpOnly * BoosterPulser.pulsingForcePercentage(this) * Mathf.Sin(Time.time / BoosterPulser.pulsingForceFrequency(this)));
                        }
                        else
                        {
                            forceToApply += (forceToApply * BoosterPulser.pulsingForcePercentage(this) * Mathf.Sin(Time.time / BoosterPulser.pulsingForceFrequency(this)));
                        }
                    }
                    if (BoosterAntidiminisher.antidiminishingBooster(this))                                              // if this booster's Booster Antidiminisher is currently antidiminishing this booster
                    {
                        forceToApply = Vector3.Scale(-forceToApply, BoosterAntidiminisher.antidiminishingFactors(this)); // reverse the force to apply and antidiminish it based on this booster's Booster Antidiminisher
                    }
                    else if (BoosterDiminisher.diminished(this))                                                         // if this booster's Booster Diminisher is currently diminishing this booster
                    {
                        if ((bodySpeedInBoosterDirection + Vector3.Dot(forceToApply, forceDirectionRelative)) > 0f)      // if the speed the player's rigidbody will have in the booster direction after force application is greater than 0
                        {
                            forceToApply = Vector3.Scale(forceToApply, BoosterDiminisher.diminishingFactors(this));      // diminish the force to apply based on this booster's Booster Diminisher
                        }
                    }
                    // inertia dampening //
                    if (BoosterInertiaDampener.inertiaDampened(this) && (bodySpeedInBoosterDirection < forceToApply.magnitude))
                    {
                        Vector3 inertiaDampeningForceToApply = (forceDirectionRelative * Vector3.Dot(currentPlayerVelocity, -forceDirectionRelative) * BoosterInertiaDampener.dampeningFactor(this));
                        playerRigidbody.AddForce(inertiaDampeningForceToApply);
                    }
                    // application of boosting force //
                    BoosterForceApplier.applyForce(this, forceToApply);
                }
                // fall dampening //
                if (BoosterFallDampener.fallDampened(this) && (currentPlayerVelocity.y < 0) && ((forceDirectionRelative - playerTransform.up).y > -.25f))                         // if fall dampening is enabled and the rigidbody is going down and this controller is boosting against that direction by at least about 45°
                {
                    Vector3 fallDampeningForceToApply = (playerTransform.up * BoosterFallDampener.dampeningForce(this) * Time.fixedDeltaTime);
                    playerRigidbody.AddForce(fallDampeningForceToApply);
                }
                // vibrating of controller //
                controller.vibrate(vibrationIntensity);
            }
        }


        else                    // otherwise (if no input nor module is having boosting happen currently): determining to not be boosting
        {
            boosting       = false;
            boostingDeeply = false;
        }
    }
コード例 #7
0
    // methods //


    // methods for: adjusting volume //

    // method: calculate the current player speed //
    protected override float currentPlayerSpeed()
    {
        return((PlayerVelocityReader.speed() + PlayerVelocityReader.speedY()) / 2f);
    }
コード例 #8
0
    // methods //


    // method: determine the (boolean) state of this Dependency Requisite //
    public override bool state()
    {
        return(PlayerVelocityReader.speedIsSlow() || PlayerVelocityReader.speedIsSlowOnY());
    }
コード例 #9
0
    // methods //


    // methods for: adjusting volume //

    // method: calculate the current player speed //
    protected virtual float currentPlayerSpeed()
    => PlayerVelocityReader.speed();
コード例 #10
0
    // at each update: //
    private void Update()
    {
        // if either: the locomotion dependencies are met, the stuck failsafe dependencies are met: //
        if (locomotionDependencies.areMet() || dependenciesStuckFailsafe.areMet())
        {
            // if: regular gauge treading is controlled via toggling (instead of holding), regular gauge input just began: invert the tracking of whether the regular treading toggle is on //
            if (!heldVersusToggled && locomotionInputEnabledAndAllowed() && controller.inputPressing(inputsLocomotion))
            {
                regularTreadingToggle = !regularTreadingToggle;
            }
            // if regular gauge treading is not controlled via toggling or locomotion input is not enabled: ensure that the regular gauge treading toggle is off //
            if (heldVersusToggled || !locomotionInputEnabledAndAllowed())
            {
                regularTreadingToggle = false;
            }

            // if this treader is experiencing significant input: //
            if (experiencingSignificantInput())
            {
                // if a gauge of treading is beginning: broadcast the treading gauge beginning event //
                if (controller.inputPressing(inputsLocomotion) || controller.inputTouching(inputsLocomotion))
                {
                    // broadcast treading gauge beginning event //
                    if (treadingGaugeBeginningEvent != null)
                    {
                        treadingGaugeBeginningEvent();
                    }
                }

                // based on whether any touchpad input is being used: determine the max treading speed //
                float maxSpeed = 0f;                                                                                                         // initialize the max treading speed to 0
                if (controller.inputTouched(inputsLocomotion))                                                                               // if any touchpad input is being used: set the max treading speed to the corresponding max treading speed gauge:
                {
                    maxSpeed = ((controller.touchpadPressed() || !slowerSpeedEnabled || regularTreadingToggle) ? speedMax : slowerSpeedMax); // if the touchpad is being pressed or the slower guage speed is disabled or regular treading is currently toggled on: use the normal gauge; otherwise (if the touchpad is merely significantly being touched): use the slower gauge
                }
                else                                                                                                                         // otherwise (if no touchpad input is being used): simply set the max treading speed to the normal max treading speed setting
                {
                    maxSpeed = speedMax;
                }

                // initialize the treading velocity (which is just for x and z) as a proportionality (that is, without scaling it to the appropriate magnitude/speed yet) //
                Vector3 treadingVelocityProportionalityForwardPart   = FloatsVector.zeroes; // define the forward part to be the forward direction of this treader
                Vector3 treadingVelocityProportionalityRightwardPart = FloatsVector.zeroes; // initialize the rightward part as a zeroes vector
                if (controller.inputTouched(inputsLocomotion))                              // if any touchpad input is being used: proportion the velocity parts based on the touchpad input position's coordinates' signage
                {
                    // proportion the forward part of the velocity based on the touchpad's y (used for z) input position //
                    treadingVelocityProportionalityForwardPart = directionReferenceTransform.forward * controller.touchpadY();

                    // proportion the rightward part of the velocity based on the touchpad's x input position //
                    treadingVelocityProportionalityRightwardPart = directionReferenceTransform.right * controller.touchpadX();
                }
                else                            // otherwise (if no touchpad input is being used): only proportion the treading velocity forward part – using the forward direction of this treader
                {
                    treadingVelocityProportionalityForwardPart = directionReferenceTransform.forward;
                }
                Vector3 treadingVelocity = treadingVelocityProportionalityForwardPart + treadingVelocityProportionalityRightwardPart;                           // initialize the treading velocity as the sum of both the forward and rightward parts

                // trim out the y axis of the treading velocity //
                treadingVelocity = treadingVelocity.withYZero();

                // calculate the treading speed //
                float speed = 0f;                               // initialize the treading speed to 0
                if (controller.inputTouched(inputsLocomotion))  // if any touchpad input is being used:
                {
                    // set the speed to be the max treading speed, curved by the distance of the input position on the touchpad away from the center, using the curve setting //
                    speed = touchpadSpeedDistanceCurve.clamped(0f, maxSpeed, controller.touchpadDistance());
                }
                else                            // otherwise (if no touchpad input is being used): simply set the treading speed to the max treading speed
                {
                    speed = speedMax;
                }

                // scale the treading velocity to the calculated treading speed //
                treadingVelocity = treadingVelocity.normalized * speed;

                // determine the player's velocity //
                Vector3 playerVelocity = PlayerVelocityReader.velocity();

                // if the player's speed in the direction of the treading velocity is not yet at or past the treading velocity's speed: //
                if (Vector3.Dot(playerVelocity, treadingVelocity.normalized) < speed)
                {
                    // determine the appropriate responsiveness factor //
                    float appropriateResponsivnessFactor = responsivenessFactorSkiing;
                    if (!Skier.skiing)
                    {
                        bool driftingWithinOneSecondAgo = dependencyDriftingWithinOneSecondAgo.isMet();
                        if (!driftingWithinOneSecondAgo)
                        {
                            appropriateResponsivnessFactor = responsivenessFactorNonskiingNondrifting;
                        }
                        else
                        {
                            float timeAgoDriftingBoosting  = (Time.time - BoostingDriftingTracker.timePlayerWasLastBoostingDrifting);
                            float timeAgoDriftingLaunching = (Time.time - LaunchingDriftingTracker.timePlayerWasLastLaunchingDrifting);
                            float timeAgoDrifting          = Mathf.Min(timeAgoDriftingBoosting, timeAgoDriftingLaunching);

                            appropriateResponsivnessFactor = responsivenessFactorNonskiingDriftingCurve.clamped(responsivenessFactorNonskiingDriftingMin, responsivenessFactorNonskiingDriftingMax, (timeAgoDrifting / 1f));
                        }
                    }

                    // hone the player's velocity x and z axes to the treading velocity x and z axes by the determined treading velocity x and z axes' magnitudes in proportion to the current frame's duration times the appropriate responsivness factor //
                    Vector3 honingVector = ((new Vector3(Mathf.Abs(treadingVelocity.x), 0f, Mathf.Abs(treadingVelocity.z))) * (Time.deltaTime) * appropriateResponsivnessFactor);
                    playerRigidbody.velocity = playerVelocity.honed(treadingVelocity, honingVector);
                }
            }
            // otherwise (if this treader is not currently experiencing significant input): if the player is not currently skiing: //
            else if (!Skier.skiing)
            {
                // determine whether significant input is currently ceasing //
                bool significantInputCeasing = (locomotionInputEnabledAndAllowed() && (controller.inputUnpressing(inputsLocomotion) || controller.inputUntouching(inputsLocomotion)));

                // determine whether the other treader is currently experiencing significant input //
                bool otherTreaderIsCurrentlyExperiencingSignificantInput = (otherTreaderActive() && other.experiencingSignificantInput());

                // if: this treader is currently ceasing to experience significant input, the other treader is not currently experiencing significant input //
                if (significantInputCeasing && !otherTreaderIsCurrentlyExperiencingSignificantInput)
                {
                    // stop the player's x and z movement (zero the player velocity's x and z axes) //
                    playerRigidbody.velocity = new Vector3(0f, PlayerVelocityReader.velocityY(), 0f);
                }
            }
        }
    }