예제 #1
0
        // --------------------
        protected Vector3 GetFollowPos(Vector3 targetWorldPos, Vector2 worldOffset, out bool posWasOutside)
        {
            Vector3 np = this.WorldToNormalizedPos(targetWorldPos, worldOffset);

            if ((this.shape == TouchControl.Shape.Circle) || (this.shape == TouchControl.Shape.Ellipse))
            {
                if (np.sqrMagnitude <= 1.0f)
                {
                    posWasOutside = false;
                    return(targetWorldPos);
                }

                np = CFUtils.ClampInsideUnitCircle(np);
            }
            else
            {
                if ((np.x >= -1) && (np.x <= 1) && (np.y >= -1) && (np.y <= 1))
                {
                    posWasOutside = false;
                    return(targetWorldPos);
                }

                np = CFUtils.ClampInsideUnitSquare(np);
            }


            Vector3 clampedWorldPos = this.NormalizedToWorldPos(np);
            Vector3 centerWorldPos  = this.GetWorldSpaceCenter();

            posWasOutside = true;

            return(targetWorldPos - (clampedWorldPos - centerWorldPos));
        }
예제 #2
0
        // ----------------------
        protected Vector3 ClampInsideCanvas(Vector3 targetWorldPos, Canvas limiterCanvas)
        {
            RectTransform canvasTr = null;

            if ((limiterCanvas == null) || ((canvasTr = (limiterCanvas.transform as RectTransform)) == null))
            {
                return(targetWorldPos);
            }



            Rect localRect   = this.GetLocalRect();
            Rect limiterRect = canvasTr.rect;

            Matrix4x4 localToLimiterSpace = limiterCanvas.transform.worldToLocalMatrix * CFUtils.ChangeMatrixTranl(this.transform.localToWorldMatrix, targetWorldPos);

            bool thisIsRound = ((this.shape == Shape.Circle) || (this.shape == Shape.Ellipse));

            Rect rectInLimiterSpace = CFUtils.TransformRect(localRect, localToLimiterSpace, thisIsRound);


            Vector2 localOfs = CFUtils.ClampRectInside(rectInLimiterSpace, thisIsRound, limiterRect, false);

            if (localOfs == Vector2.zero)
            {
                return(targetWorldPos);
            }


            return(targetWorldPos + limiterCanvas.transform.localToWorldMatrix.MultiplyVector(localOfs));
        }
예제 #3
0
        // ---------------------
        override protected void OnUpdateControl()
        {
            base.OnUpdateControl();


            this.valPrev = this.valCur;



            // Touch started...

            if (this.touchStateWorld.JustPressedRaw())
            {
                this.startRawVal = this.rawValCur;

                if (this.physicalMode)
                {
                    this.startVec = this.touchStateOriented.GetCurPosSmooth();
                }
                else
                {
                    this.startVec = this.WorldToNormalizedPos(this.touchStateWorld.GetStartPos(), this.GetOriginOffset());
                }
            }


            if (this.touchStateWorld.PressedRaw())
            {
                float v = 0;

                if (this.physicalMode)
                {
                    v = (this.touchStateOriented.GetCurPosSmooth().x - this.startVec.x) / (this.physicalMoveRangeCm * CFScreen.dpcm * 0.5f);
                }
                else
                {
                    Vector3 np = this.WorldToNormalizedPos(this.touchStateWorld.GetCurPosSmooth(), this.GetOriginOffset());
                    v = (np.x - this.startVec.x);
                }


                float targetRawVal = this.startRawVal + v;         // * this.maxTurnAngle;

                this.rawValCur = CFUtils.MoveTowards(this.rawValCur, targetRawVal, (this.limitTurnSpeed ? this.minTurnTime : 0), Time.unscaledDeltaTime, 0.001f);
            }
            else
            {
                this.rawValCur = CFUtils.MoveTowards(this.rawValCur, 0, (this.limitTurnSpeed ? this.maxReturnTime : 0), Time.unscaledDeltaTime, 0.001f);
            }

            this.rawValCur = Mathf.Clamp(this.rawValCur, -1, 1);

            this.valCur = this.analogConfig.GetAnalogVal(this.rawValCur);


            if (this.IsActive())
            {
                this.SyncRigState();
            }
        }
예제 #4
0
        // ---------------
        protected bool SendMoveEventToSelectedObject()
        {
            GamepadManager g = GamepadManager.activeManager;

            if (g == null)
            {
                return(false);
            }

            JoystickState
                leftStick = g.GetCombinedGamepad().GetStick(GamepadManager.GamepadStick.LeftAnalog),
                dpad      = g.GetCombinedGamepad().GetStick(GamepadManager.GamepadStick.Dpad);

            Dir dir = Dir.N;

            if (leftStick.JustReleasedDir4(Dir.N))
            {
                dir = leftStick.GetDir4();
            }
            else if (dpad.JustReleasedDir4(Dir.N))
            {
                dir = dpad.GetDir4();
            }

            Vector2 dirVec = CFUtils.DirToVector(dir, false);

            Vector2 keyboardVec = new Vector2(
                (ControlFreak2.CF2Input.GetKeyDown(KeyCode.RightArrow)  ? 1.0f : ControlFreak2.CF2Input.GetKeyDown(KeyCode.LeftArrow) ? -1.0f : 0),
                (ControlFreak2.CF2Input.GetKeyDown(KeyCode.UpArrow)             ? 1.0f : ControlFreak2.CF2Input.GetKeyDown(KeyCode.DownArrow) ? -1.0f : 0));


            dirVec.x = CFUtils.ApplyDeltaInput(dirVec.x, keyboardVec.x);
            dirVec.y = CFUtils.ApplyDeltaInput(dirVec.y, keyboardVec.y);

            if (dirVec.sqrMagnitude < 0.00001f)
            {
                return(false);
            }


            var axisEventData = GetAxisEventData(dirVec.x, dirVec.y, 0.3f);

            ExecuteEvents.Execute(eventSystem.currentSelectedGameObject, axisEventData, ExecuteEvents.moveHandler);

            if ((this.eventSystem.currentSelectedGameObject != null))
            {
                this.eventSystem.firstSelectedGameObject = this.eventSystem.currentSelectedGameObject;
            }

            return(axisEventData.used);
        }
        // ----------------
        //! Get nearest direction for given angle with respect to last direction.
        // ----------------
        static public Dir DirFromAngleEx(
            float ang,                          //!< Angle in degrees
            bool as8way,                        //!< If true nearest of 8-way directions will be returned, otherwise one of major 4-way directions.
            Dir lastDir,                        //!< Last direction.
            float magnetPow                     //!< Normalized angular magnet power.
            )
        {
            if (lastDir != Dir.N && (magnetPow > 0.001f))
            {
                if (Mathf.Abs(Mathf.DeltaAngle(ang, CFUtils.DirToAngle(lastDir))) <
                    ((1.0f + (Mathf.Clamp01(magnetPow) * 0.5f)) * (as8way ? 22.5f : 45.0f)))
                {
                    return(lastDir);
                }
            }

            return(DirFromAngle(ang, as8way));
        }
예제 #6
0
        // ----------------------
        override protected void OnUpdateAnimator(bool skipAnim)
        {
            if ((this.sourceControl == null) || (this.image == null))
            {
                return;
            }

            TouchSteeringWheel wheel = (TouchSteeringWheel)this.sourceControl;


            SpriteConfig sprite = null;

            if (wheel.Pressed() && ((sprite == null) || !sprite.enabled))
            {
                sprite = this.spritePressed;
            }

            if (((sprite == null) || !sprite.enabled))
            {
                sprite = this.spriteNeutral;
            }



            if (!CFUtils.editorStopped && !this.IsIllegallyAttachedToSource())
            {
                this.extraRotation = CFUtils.SmoothTowardsAngle(this.extraRotation, -(wheel.GetValue() *
                                                                                      ((wheel.wheelMode == TouchSteeringWheel.WheelMode.Swipe) ? this.rotationRange : wheel.maxTurnAngle)),
                                                                this.rotationSmoothingTime, CFUtils.realDeltaTimeClamped, 0.001f);
            }
            else
            {
                this.extraRotation = 0;
            }


            this.BeginSpriteAnim(sprite, skipAnim);

            this.UpdateSpriteAnimation(skipAnim);
        }
예제 #7
0
        // -------------------
        protected Vector3 ClampInsideOther(Vector3 targetWorldPos, TouchControl limiter)
        {
            Rect localRect   = this.GetLocalRect();
            Rect limiterRect = limiter.GetLocalRect();

            Matrix4x4 localToLimiterSpace = limiter.transform.worldToLocalMatrix * CFUtils.ChangeMatrixTranl(this.transform.localToWorldMatrix, targetWorldPos);

            bool thisIsRound    = ((this.shape == Shape.Circle) || (this.shape == Shape.Ellipse));
            bool limiterIsRound = ((limiter.shape == Shape.Circle) || (limiter.shape == Shape.Ellipse));

            Rect rectInLimiterSpace = CFUtils.TransformRect(localRect, localToLimiterSpace, thisIsRound);


            Vector2 localOfs = CFUtils.ClampRectInside(rectInLimiterSpace, thisIsRound, limiterRect, limiterIsRound);

            if (localOfs == Vector2.zero)
            {
                return(targetWorldPos);
            }

            return(targetWorldPos + limiter.transform.localToWorldMatrix.MultiplyVector(localOfs));
        }
예제 #8
0
        // --------------------------
        public Bounds GetWorldSpaceAABB()
        {
            Rect r = this.GetLocalRect();

            return(CFUtils.TransformRectAsBounds(r, this.transform.localToWorldMatrix, ((this.shape == Shape.Circle) || (this.shape == Shape.Ellipse))));
        }
예제 #9
0
        // --------------------------
        public bool HitTest(Vector2 sp, Camera cam, float fingerRadPx, Hit hit)
        {
            hit.Reset();


            bool raycastOnly = (this.ignoreFingerRadius || (fingerRadPx < 0.001f));

            Vector2 lp = this.ScreenToLocalPos(sp, cam);

            Rect r = this.GetLocalRect();

            bool    directHit         = false;
            Vector2 closestLocalPoint = Vector2.zero;

            Vector2 delta = (lp - r.center);

            switch (this.shape)
            {
            case Shape.Circle:
                float rad = r.width * 0.5f;
                if (!(directHit = (delta.sqrMagnitude <= (rad * rad))))
                {
                    if (!raycastOnly)
                    {
                        closestLocalPoint = delta.normalized * rad;
                    }
                }
                break;


            case Shape.Ellipse:
                Vector2 scaledDelta = delta;
                scaledDelta.x /= r.width * 0.5f;
                scaledDelta.y /= r.height * 0.5f;
                if (!(directHit = (scaledDelta.sqrMagnitude <= 1.0f)) && !raycastOnly)
                {
                    if (!raycastOnly)
                    {
                        closestLocalPoint    = delta.normalized;
                        closestLocalPoint.x *= r.width * 0.5f;
                        closestLocalPoint.y *= r.height * 0.5f;
                    }
                }
                break;

            case Shape.Rectangle:
            case Shape.Square:
                if (!(directHit = ((lp.x >= r.x) && (lp.x <= r.xMax) && (lp.y >= r.y) && (lp.y <= r.yMax))))
                {
                    if (!raycastOnly)
                    {
                        closestLocalPoint = CFUtils.ClampInsideRect(lp, r);
                    }
                }
                break;
            }


            // If indirect hit's aren't supported, return false...

            if (raycastOnly && !directHit)
            {
                return(false);
            }


            // Check for indirect hit..

            Vector2 closestScreenPoint = this.LocalToScreenPos(closestLocalPoint, cam);

            bool indirectHit = (directHit ? false : ((sp - closestScreenPoint).sqrMagnitude <= (fingerRadPx * fingerRadPx)));


            if (directHit || indirectHit)
            {
                hit.c                = this;
                hit.indirectHit      = indirectHit;
                hit.depth            = this.transform.position.z;
                hit.localPos         = lp;
                hit.closestLocalPos  = (directHit ? lp : closestLocalPoint);
                hit.screenDistSqPx   = (sp - this.LocalToScreenPos(r.center, cam)).sqrMagnitude;
                hit.screenPos        = sp;
                hit.closestScreenPos = closestScreenPoint;

                return(true);
            }

            return(false);
        }
        // ----------------------
        override protected void OnUpdateAnimator(bool skipAnim)
        {
#if UNITY_EDITOR
            if (!UnityEditor.EditorApplication.isPlaying)
            {
                //this.CheckHierarchy();
                //return;
            }
#endif

            TouchJoystick joystick = (TouchJoystick)this.sourceControl;

            if ((joystick == null) || (this.image == null))
            {
                return;
            }


            JoystickState joyState = joystick.GetState();     //false); //this.useVirtualJoystickState);



            SpriteConfig sprite = null;

            if ((this.spriteMode == SpriteMode.FourWay) || (this.spriteMode == SpriteMode.EightWay))
            {
                Dir curDir = Dir.N;

                if (this.spriteMode == SpriteMode.FourWay)
                {
                    curDir = joyState.GetDir4();
                }
                else if (this.spriteMode == SpriteMode.EightWay)
                {
                    curDir = joyState.GetDir8();
                }

                switch (curDir)
                {
                case Dir.U: sprite = this.spriteUp; break;

                case Dir.UR: sprite = this.spriteUpRight; break;

                case Dir.R: sprite = this.spriteRight; break;

                case Dir.DR: sprite = this.spriteDownRight; break;

                case Dir.D: sprite = this.spriteDown; break;

                case Dir.DL: sprite = this.spriteDownLeft; break;

                case Dir.L: sprite = this.spriteLeft; break;

                case Dir.UL: sprite = this.spriteUpLeft; break;
                }
            }


            if (joystick.Pressed() && ((sprite == null) || !sprite.enabled))
            {
                sprite = this.spriteNeutralPressed;
            }


            if (((sprite == null) || !sprite.enabled))
            {
                sprite = this.spriteNeutral;
            }


            if (!CFUtils.editorStopped && !this.IsIllegallyAttachedToSource())
            {
                Vector2 joyVec = joyState.GetVectorEx((joystick.shape == TouchControl.Shape.Rectangle) || (joystick.shape == TouchControl.Shape.Square));


                if (this.animateTransl)
                {
                    this.extraOffset = CFUtils.SmoothTowardsVec2(this.extraOffset, Vector2.Scale(joyVec, this.moveScale),
                                                                 this.translationSmoothingTime, CFUtils.realDeltaTimeClamped, 0.0001f);
                }
                else
                {
                    this.extraOffset = Vector2.zero;
                }


                if (this.rotationMode != RotationMode.Disabled)
                {
                    float targetAngle = 0;

                    if (joystick.Pressed())
                    {
                        Vector2 v = joyState.GetVector();

                        if (this.rotationMode == RotationMode.Compass)
                        {
                            if (v.sqrMagnitude > 0.0001f)
                            {
                                this.lastSafeCompassAngle = joyState.GetAngle();          //CFUtils.VecToAngle(v.normalized);
                            }
                            targetAngle = -this.lastSafeCompassAngle;                     //targetRotation = Quaternion.Euler(0, 0, -this.lastSafeCompassAngle);
                        }
                        else
                        {
                            targetAngle = ((this.rotationMode == RotationMode.SimpleHorizontal) ? v.x : v.y) * -this.simpleRotationRange;
                        }
                    }
                    else
                    {
                        this.lastSafeCompassAngle = 0;
                        targetAngle = 0;
                    }


                    this.extraRotation = CFUtils.SmoothTowardsAngle(this.extraRotation, targetAngle,
                                                                    this.rotationSmoothingTime, CFUtils.realDeltaTimeClamped, 0.0001f);
                }
            }



            this.BeginSpriteAnim(sprite, skipAnim);

            this.UpdateSpriteAnimation(skipAnim);
        }
예제 #11
0
        // ---------------------
        override protected void OnUpdateControl()
        {
            base.OnUpdateControl();


            this.valPrev = this.valCur;



            // Touch started...

            if (this.touchStateWorld.JustPressedRaw())
            {
                this.startRawVal = this.rawValCur;

                // Swipe mode...

                if (this.wheelMode == WheelMode.Swipe)
                {
                    if (this.physicalMode)
                    {
                        this.startVec = this.touchStateOriented.GetCurPosSmooth();
                    }
                    else
                    {
                        this.startVec = this.WorldToNormalizedPos(this.touchStateWorld.GetStartPos(), this.GetOriginOffset());
                    }
                }

                // Real mode...
                else
                {
                    this.startVec = this.WorldToNormalizedPos(this.touchStateWorld.GetStartPos(), this.GetOriginOffset());

                    this.angleIsSafe = false;
                    this.curAngle    = 0;
                    this.startAngle  = 0;
                    this.angleDelta  = 0;
//(this.startVec.sqrMagnitude > (this.realModeDeadZone * this.realModeDeadZone));
//				this.startAngle	= this.angleIsSafe ? this.GetWheelAngle(this.startVec, 0) : 0;
//				this.curAngle		= this.startAngle;
                }
            }


            if (this.touchStateWorld.PressedRaw())
            {
                float v = 0;

                // Swipe mode...

                if (this.wheelMode == WheelMode.Swipe)
                {
                    if (this.physicalMode)
                    {
                        v = (this.touchStateOriented.GetCurPosSmooth().x - this.startVec.x) / (this.physicalMoveRangeCm * CFScreen.dpcm * 0.5f);
                    }
                    else
                    {
                        Vector3 np = this.WorldToNormalizedPos(this.touchStateWorld.GetCurPosSmooth(), this.GetOriginOffset());
                        v = (np.x - this.startVec.x);
                    }
                }

                // Real mode...

                else
                {
                    Vector3 np = this.WorldToNormalizedPos(this.touchStateWorld.GetCurPosSmooth(), this.GetOriginOffset());
                    if (np.sqrMagnitude < (this.turnModeDeadZone * this.turnModeDeadZone))
                    {
                        this.angleIsSafe = false;
                    }
                    else
                    {
                        this.curAngle = this.GetWheelAngle(np, this.curAngle);

                        if (!this.angleIsSafe)
                        {
                            this.startAngle  = this.curAngle;
                            this.startRawVal = this.rawValCur;
                            this.angleIsSafe = true;
                        }
                    }

                    this.angleDelta = CFUtils.SmartDeltaAngle(this.startAngle, this.curAngle, this.angleDelta);

                    //if (!this.angleIsSafe)
                    //	this.angleDelta = Mathf.Clamp(this.angleDelta, -this.maxTurnAngle, this.maxTurnAngle);

                    this.angleDelta = Mathf.Clamp(this.angleDelta, -this.maxTurnAngle - 360, this.maxTurnAngle + 360);

                    v = this.angleDelta / this.maxTurnAngle;
                }

                float targetRawVal = this.startRawVal + v;         // * this.maxTurnAngle;

                this.rawValCur = CFUtils.MoveTowards(this.rawValCur, targetRawVal, (this.limitTurnSpeed ? this.minTurnTime : 0), CFUtils.realDeltaTime, 0.001f);
            }

            else
            {
                this.rawValCur = CFUtils.MoveTowards(this.rawValCur, 0, (this.limitTurnSpeed ? this.maxReturnTime : 0), CFUtils.realDeltaTime, 0.001f);
            }

            this.rawValCur = Mathf.Clamp(this.rawValCur, -1, 1);

            this.valCur = this.analogConfig.GetAnalogVal(this.rawValCur);


            if (this.IsActive())
            {
                this.SyncRigState();
            }
        }