// 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; } }
// method: calculate the distance of the booster to the nearest recognized (according to Terrain Response) terrain in the direction of the booster's boosting; this also tracks for Booster Antidiminisher whether the booster is at distance to an antidiminishor // public static float distanceToTerrain(Booster booster) { // connect to the diminisher for the given booster // BoosterDiminisher diminisher = diminisherFor(booster); // determine any nontrigger colliders that this diminisher's hand is currently inside of (according to Hand Insideness Tracking) // HashSet <GameObject> allCollidedObjects = (booster.leftInstance ? HandInsidenessTracking.allCollidedObjectsForLeftHand() : HandInsidenessTracking.allCollidedObjectsForRightHand()); // if this diminisher's hand is currently inside of any nontrigger collider objects: // if (allCollidedObjects.Count > 0) { // if any of the objects this diminisher's hand is inside of is on a recognized terrain layer: calculate the distance to the nearest recognized terrain to be 0 // foreach (GameObject collidedObject in allCollidedObjects) { if (TerrainResponse.recognizedTypedTerrainLayerIndex(diminisher.recognizedTerrainType, collidedObject.layer)) { diminisher.terrainDistancingLastFoundObstruction = false; // track that obstruction was not found for this terrain distancing return(0f); } } // otherwise: track that an obstruction was found for this terrain distancing, and consider the distance to terrain to be -1, as a flag of no recognized terrain being found // diminisher.terrainDistancingLastFoundObstruction = true; return(-1f); } // otherwise: determine the distance to the nearest recognized terrain via raycasting // else { // track that obstruction was not found for this terrain distancing // diminisher.terrainDistancingLastFoundObstruction = false; // determine the relativity transform that this booster's relativizer is using currently // Transform relativityTransform = BoosterRelativizer.relativityTransform(booster); // if there is a recognized terrain below, calculate distance based on that // RaycastHit[] raycastHitsFound = Physics.RaycastAll(relativityTransform.position, -BoosterForceApplier.direction(booster).asDirectionRelativeTo(relativityTransform), Mathf.Infinity, Physics.DefaultRaycastLayers); // get all raycast hits for raycasting from the booster in the direction of the booster's force if (Any.itemsIn(raycastHitsFound)) { // determine the nearest raycast hit found's: hit distance, hit // float nearestRaycastHitDistance = Mathf.Infinity; // initialize the nearest raycast hit's distance RaycastHit nearestRaycastHit = raycastHitsFound[0]; // initialize the nearest raycast hit to the first raycast hit found, by default (since it can't be null) foreach (RaycastHit raycastHitFound in raycastHitsFound) { if (hitTriggerColliders || !raycastHitFound.collider.isTrigger) // if trigger collider hits are allowed, or this raycast did not hit a trigger collider { float raycastHitFoundDistance = Vector3.Distance(relativityTransform.position, raycastHitFound.point); // determine this raycast's hit distance // if this raycast's hit distance is less than the smallest distance found thus far, update the tracked nearest raycast hit and its distance to this raycast's // if (raycastHitFoundDistance < nearestRaycastHitDistance) { nearestRaycastHitDistance = raycastHitFoundDistance; nearestRaycastHit = raycastHitFound; } } } // if the nearest raycast hit found is legal (based on the following conditions): track whether this diminisher is at distance to an antidiminisher, return the nearest raycast's hit distance // if (hitTriggerColliders || !nearestRaycastHit.collider.isTrigger) // if trigger collider hits are allowed, or the nearest raycast did not hit a trigger collider { if (TerrainResponse.recognizedTypedTerrainLayerIndex(diminisher.recognizedTerrainType, nearestRaycastHit.transform.gameObject.layer)) // if the nearest raycast hit recognized terrain { BoosterAntidiminisher.antidiminisherFor(booster).atDistanceToAntidiminishor = BoosterAntidiminisher.antidiminishorLayer(nearestRaycastHit.transform.gameObject.layer) && (nearestRaycastHitDistance >= 0f) && (nearestRaycastHitDistance <= BoosterAntidiminisher.boosterAntidiminishingDistanceMax(booster)); // track whether this booster is at distance to an antidiminisher return(nearestRaycastHitDistance); // return the nearest raycast's hit distance } } // otherwise (if the nearest raycast hit found is not legal): // else { // track that this booster is not at distance to an antidiminisher // BoosterAntidiminisher.antidiminisherFor(booster).atDistanceToAntidiminishor = false; } } // otherwise (if no raycast hits were found): // else { // track that this booster is not at distance to an antidiminisher // BoosterAntidiminisher.antidiminisherFor(booster).atDistanceToAntidiminishor = false; } // if nothing has been returned yet: consider the distance to terrain to be -1, as a flag of no recognized terrain being found (not 0, because returning 0 (as could have been returned above) would have indicated that recognized terrain was found at an immediate distance) // return(-1f); } }