public float changeAngleToAchieveTargetAngleWithSpeed(float inTargetAngle, float inSpeed) { float theAngleToAchieve = XMath.getNormalizedAngle(inTargetAngle); if (Mathf.Approximately(theAngleToAchieve, getAngle())) return 0.0f; float theNearestDiraction = XMath.getNormalizedAngle(theAngleToAchieve - getAngle()); if (Mathf.Abs(theNearestDiraction) <= inSpeed) { setAngle(inTargetAngle); return 0.0f; //TODO: Return real delta!!! } float theDiraction = getDiractionToAchieveAngle(inTargetAngle); return changeAngle(theDiraction * inSpeed); }
public float getNearestLimitForAngle(float inAngle) { float theNormalizedAngle = XMath.getNormalizedAngle(inAngle); float theDeltaToAchieveFromLimit = 0.0f; float theDeltaToAchieveToLimit = 0.0f; if (isAngleAchievable(inAngle)) { theDeltaToAchieveFromLimit = XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theNormalizedAngle); theDeltaToAchieveToLimit = XMath.getNormalizedAnglesClockwiseDelta(theNormalizedAngle, getLimitTo()); } else { theDeltaToAchieveFromLimit = XMath.getNormalizedAnglesClockwiseDelta(theNormalizedAngle, getLimitFrom()); theDeltaToAchieveToLimit = XMath.getNormalizedAnglesClockwiseDelta(getLimitTo(), theNormalizedAngle); } return theDeltaToAchieveFromLimit < theDeltaToAchieveToLimit ? getLimitFrom() : getLimitTo(); }
public float changeAngle(float inValueDelta) { if (Mathf.Approximately(inValueDelta, 0.0f)) return 0.0f; float theOldAngle = _state.Angle; float theNewAngle = XMath.getNormalizedAngle(_state.Angle + inValueDelta); float theDelta = XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theNewAngle); float theDirectedDelta = XMath.getNormalizedAngle(theDelta); if (!isUnlimited() && theDirectedDelta < 0.0f) { _state.Angle = getLimitFrom(); } else if (!isUnlimited() && theDirectedDelta > getLimitingAngle()) { _state.Angle = getLimitTo(); } else { _state.Angle = theNewAngle; } return XMath.getNormalizedAngle(_state.Angle - theOldAngle); }
public float getDiractionToAchieveAngle(float inAngleToAchieve) { float theCurrentAngle = getAngle(); float theAngleToAchieve = XMath.getNormalizedAngle(inAngleToAchieve); if (Mathf.Approximately(theCurrentAngle, theAngleToAchieve)) return 0.0f; if (isAngleAchievable(theAngleToAchieve)) { float theNearestDiraction = XMath.getNormalizedAngle(theAngleToAchieve - theCurrentAngle); if (isUnlimited()) return theNearestDiraction > 0.0f ? 1.0f : -1.0f; if (theNearestDiraction > 0.0f) { float theTestAngle = XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theCurrentAngle); theTestAngle += XMath.getNormalizedAnglesClockwiseDelta(theCurrentAngle, theAngleToAchieve); return theTestAngle < getLimitingAngle() || Mathf.Approximately(theTestAngle, getLimitingAngle()) ? 1.0f : -1.0f; } else { float theTestAngle = XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theCurrentAngle); theTestAngle -= XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theAngleToAchieve); return theTestAngle > 0.0f || Mathf.Approximately(theTestAngle, 0.0f) ? -1.0f : 1.0f; } } else { return getDiractionToAchieveAngle(getNearestLimitForAngle(inAngleToAchieve)); } }
void FixedUpdate() { if (!_targetObject) { return; } float theTargetAngle = XMath.getNearestAngleBetweenPoints( transform.position, _targetObject.transform.position ); float theCurrentAngle = transform.rotation.eulerAngles.z; float theNearestDelta = XMath.getNormalizedAngle(theTargetAngle - theCurrentAngle); if (XMath.equalsWithPrecision(theNearestDelta, 0.0f, 30.0f)) { _carPhysics.applyGas(); } else { float theDistanceSquare = _euristicDistanceToMakeSpeedLessIfFar * _euristicDistanceToMakeSpeedLessIfFar; Vector2 theDelta = _targetObject.transform.position - transform.position; if (theDelta.sqrMagnitude < theDistanceSquare) { if (_carPhysics.getGasValue().getValue() > _minimumGas) { _carPhysics.applyRevers(); } else { _carPhysics.applyGas(); } } else { _carPhysics.applyGas(); } } bool theIsNeedMoveByClockwiseToAchieveTargetAngle = (theNearestDelta > 0.0f); bool theItsTimeToCorrectWheels = false; _simulationManager.simulate(gameObject, 50, (ISimulatableLogic inLogic) => { var theLogic = inLogic as CarPhysicsLogic; if (theIsNeedMoveByClockwiseToAchieveTargetAngle) { theLogic.rotateSteeringWheelCounterClockwise(); if (!theLogic.isRotatingByClockwice()) { return(false); } } else { theLogic.rotateSteeringWheelClockwise(); if (theLogic.isRotatingByClockwice()) { return(false); } } float theSimulationCurrentAngle = theLogic.transform.rotation.eulerAngles.z; float theSimulationNearestDelta = XMath.getNormalizedAngle(theTargetAngle - theSimulationCurrentAngle); if (!XMath.hasSameSigns(theNearestDelta, theSimulationNearestDelta)) { theItsTimeToCorrectWheels = true; return(false); } //theLogic.debugDraw(); return(true); }); if (theIsNeedMoveByClockwiseToAchieveTargetAngle) { if (theItsTimeToCorrectWheels) { _carPhysics.rotateSteeringWheelCounterClockwise(); } else { _carPhysics.rotateSteeringWheelClockwise(); } } else { if (theItsTimeToCorrectWheels) { _carPhysics.rotateSteeringWheelClockwise(); } else { _carPhysics.rotateSteeringWheelCounterClockwise(); } } }
//-Implementation //--Utils private void normalizeState() { _state.LimitFrom = XMath.getNormalizedAngle(_state.LimitFrom); _state.LimitTo = XMath.getNormalizedAngle(_state.LimitTo); setAngle(_state.Angle); }
//-Utils public bool isAngleAchievable(float inAngle) { float theNormalizedAngle = XMath.getNormalizedAngle(inAngle); float theDelta = XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theNormalizedAngle); return theDelta < getLimitingAngle() || Mathf.Approximately(theDelta, getLimitingAngle()); }
public float setAngle(float inAngle) { float theNormalizedAngle = XMath.getNormalizedAngle(inAngle); return _state.Angle = isAngleAchievable(theNormalizedAngle) ? theNormalizedAngle : getNearestLimitForAngle(theNormalizedAngle); }
//Methods //-API public void setTargetAngle(float inTargetAngle) { _targetAngle = XMath.getNormalizedAngle(inTargetAngle); }