private void AttemptToGrabRail(List <GravityRail.RailInfo> railsInRange) { // iterate over rails in range and find the one most aligned with float bestDot = 0.0f; float grabDot = maxGrabDot; //(masterComp.steeringCont.IsStunned() || masterComp.warpCont.IsWarping()) ? restrictedGrabDot : maxGrabDot; Vector2 forward = masterComp.steeringCont.GetCurrentDirection(); foreach (GravityRail.RailInfo railInfo in railsInRange) { float dotVal = Mathf.Abs(Vector2.Dot(forward, railInfo.tangent)); if (dotVal >= grabDot && dotVal > bestDot) { // set as current rail if better aligned than current best bestDot = dotVal; currentRailInfo = railInfo; } } // if we found a rail to grab if (bestDot > 0.0f) { distanceController.Reset(); // keep speed based on how well timed the grab was Vector2 direction = Vector2.Dot(forward, currentRailInfo.tangent) > 0.0f ? currentRailInfo.tangent : -currentRailInfo.tangent; long numerator = (grabFramesLeft + 1) - (grabFramesLeft == 0 ? 1 : 0); float bonusFromSkill = (0.4f * (1.0f - numerator / ((float)framesToGrab + 1))); masterComp.speedCont.SetVelocity(direction * masterComp.speedCont.GetSpeed() * (0.5f + bonusFromSkill)); // charge up rail jump based on how skilled the rail grab was if (canGetGrabBonus) { canGetGrabBonus = false; railJumpPercent = ((currentRailInfo.distance) / maxGrabDist) <= 0.5f ? 1.0f : 0.0f; } grabFramesLeft = 0; // increase max speed and acceleration of the ship masterComp.speedCont.maxSpeedAdjustors.SetAdjustor(ATTACHED_ADJUSTER_NAME, ON_RAIL_BONUS_SPEED); masterComp.speedCont.accAdjustors.SetAdjustor(ATTACHED_ADJUSTER_NAME, ON_RAIL_BONUS_ACC); // remove stun if grabbing while stunned //masterComp.steeringCont.RemoveStun(); } else { Detach(); // track grab frames left if failed to grab rail if (grabFramesLeft == 0) { grabFramesLeft = framesToGrab; } else { --grabFramesLeft; } } }
public void Detach() { currentRailInfo = null; railJumpPercent = 0.0f; // remove on rail movement bonuses masterComp.speedCont.maxSpeedAdjustors.RemoveAdjustor(ATTACHED_ADJUSTER_NAME); masterComp.speedCont.accAdjustors.RemoveAdjustor(ATTACHED_ADJUSTER_NAME); }
public List <GravityRail.RailInfo> GetRailInfoWithinDist(Vector2 pos, float dist) { List <GravityRail.RailInfo> railsInRange = new List <GravityRail.RailInfo>(); // loop over each rail in the track and test if it is in range foreach (GravityRail rail in rails) { // get info about rail relative to the passed in position and add it if close enough GravityRail.RailInfo info = rail.GetRailInfoAtPoint(pos); if (info.alongRail && info.distance <= dist) { railsInRange.Add(info); } } return(railsInRange); }
private void UpdateRailGrinding(List <GravityRail.RailInfo> railsInRange) { // test if still in range of the last rail attached to GravityRail.RailInfo updatedRailInfo = currentRailInfo.rail.GetRailInfoAtPoint(transform.position); Vector2 forward = masterComp.steeringCont.GetCurrentDirection(); float bestDot = 0.0f; GravityRail.RailInfo bestRailInfo = null; // if still on current rail, ignore tracks not in rail switch range bool usingRailSwitchRange = updatedRailInfo.alongRail && updatedRailInfo.distance <= maxGrabDist; if (usingRailSwitchRange) { railsInRange = track.GetRailInfoWithinDist(updatedRailInfo.closestPoint, track.GetRailSwitchRange()); } // get the best rail to stay on foreach (GravityRail.RailInfo railInfo in railsInRange) { float dotVal = Mathf.Abs(Vector2.Dot(forward, railInfo.tangent)); if (dotVal >= bestDot) { float velDotVal = Mathf.Abs(Vector2.Dot(masterComp.rbody.velocity.normalized, railInfo.tangent)); // only switch to rail at nearly perpendicular angle to momentum if going slow if (velDotVal > acceptableSwitchVal) { bestDot = dotVal; bestRailInfo = railInfo; } else { // ensure that player can do sharp rail switch if going slow float shipMomentum = masterComp.rbody.mass * masterComp.speedCont.GetSpeed(); // half of the max momentum float maxSwitchMomentum = (masterComp.rbody.mass * masterComp.speedCont.GetMaxSpeed()) * 0.5f; // half of the max switch momentum float minSwitchMomentum = maxSwitchMomentum * 0.5f; float anglePercent = velDotVal / acceptableSwitchVal; // only allow switch if momentum is less than max amount allowed for a rail switch if (shipMomentum < (minSwitchMomentum + (maxSwitchMomentum - minSwitchMomentum) * anglePercent)) { bestDot = dotVal; bestRailInfo = railInfo; } } } } // either found a rail to switch to or a new rail on the track to grab if (bestRailInfo != null) { //Debug.Log("rail found"); if (bestRailInfo.rail != currentRailInfo.rail) { distanceController.Reset(); } currentRailInfo = bestRailInfo; // charge up rail jump if (railJumpPercent < 1.0f) { railJumpPercent += Time.fixedDeltaTime / railJumpTimeToCharge; railJumpPercent = Mathf.Min(railJumpPercent, 1.0f); } } // else is only reached if there was no rail to switch to and current rail isn't within rail switch range else { if (!usingRailSwitchRange) { // if no rail in range, detach from rail Detach(); } else { // if in rail switch range and no rail in range found, stay on current rail currentRailInfo = updatedRailInfo; } } }