// -------------------- 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)); }
// ---------------------- 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)); }
// --------------------- 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(); } }
// --------------- 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)); }
// ---------------------- 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); }
// ------------------- 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)); }
// -------------------------- public Bounds GetWorldSpaceAABB() { Rect r = this.GetLocalRect(); return(CFUtils.TransformRectAsBounds(r, this.transform.localToWorldMatrix, ((this.shape == Shape.Circle) || (this.shape == Shape.Ellipse)))); }
// -------------------------- 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); }
// --------------------- 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(); } }