Beispiel #1
0
        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);
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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));
            }
        }
Beispiel #5
0
    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();
            }
        }
    }
Beispiel #6
0
        //-Implementation
        //--Utils
        private void normalizeState() {
            _state.LimitFrom = XMath.getNormalizedAngle(_state.LimitFrom);
            _state.LimitTo = XMath.getNormalizedAngle(_state.LimitTo);

            setAngle(_state.Angle);
        }
Beispiel #7
0
 //-Utils
 public bool isAngleAchievable(float inAngle) {
     float theNormalizedAngle = XMath.getNormalizedAngle(inAngle);
     float theDelta = XMath.getNormalizedAnglesClockwiseDelta(getLimitFrom(), theNormalizedAngle);
     return theDelta < getLimitingAngle() || Mathf.Approximately(theDelta, getLimitingAngle());
 }
Beispiel #8
0
 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);
 }