So I am making a joystick for a mobile device(think phone) to learn about mobile development. I am using a slightly outdated tutorial from Sebastian Lague, anyways I am using a Sphere Collider and when I reach the center of the Sphere it acts as if I have slid my finger off of my screen and returns to the start position. Here is the code: Touch Input script. Code (CSharp): using UnityEngine; using System.Collections; using System.Collections.Generic; public class TouchInput : MonoBehaviour { [SerializeField] LayerMask touchMask; private List<GameObject> touchList = new List<GameObject>(); private GameObject[] touchesOld; private RaycastHit hit; void Update() { #if UNITY_EDITOR if (Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0)) { touchesOld = new GameObject[touchList.Count]; touchList.CopyTo(touchesOld); touchList.Clear(); Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray, out hit, touchMask)) { GameObject recipient = hit.transform.gameObject; touchList.Add(recipient); if (Input.GetMouseButtonDown(0)) { recipient.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver); } if (Input.GetMouseButtonUp(0)) { recipient.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver); } if (Input.GetMouseButton(0)) { recipient.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver); } } foreach (GameObject g in touchesOld) { if (!touchList.Contains(g)) { g.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver); } } } #endif if (Input.touchCount > 0) { touchesOld = new GameObject[touchList.Count]; touchList.CopyTo(touchesOld); touchList.Clear(); foreach (Touch touch in Input.touches) { Ray ray = Camera.main.ScreenPointToRay(touch.position); if (Physics.Raycast(ray, out hit, touchMask)) { GameObject recipient = hit.transform.gameObject; touchList.Add(recipient); if (touch.phase == TouchPhase.Began) { recipient.SendMessage("OnTouchDown", hit.point, SendMessageOptions.DontRequireReceiver); } if (touch.phase == TouchPhase.Ended) { recipient.SendMessage("OnTouchUp", hit.point, SendMessageOptions.DontRequireReceiver); } if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved) { recipient.SendMessage("OnTouchStay", hit.point, SendMessageOptions.DontRequireReceiver); } if (touch.phase == TouchPhase.Canceled) { recipient.SendMessage("OnTouchExit", hit.point, SendMessageOptions.DontRequireReceiver); } } } foreach (GameObject g in touchesOld) { if (!touchList.Contains(g)) { g.SendMessage("OnTouchExit", hit.point,SendMessageOptions.DontRequireReceiver); } } } } } The Slider script: Code (CSharp): using UnityEngine; using System.Collections; public class Slider : MonoBehaviour { public Transform knob; public Transform limitingCollider; private Vector3 targetPos; private Vector3 startPos; [Header ("Inputs")] public float xInput = 0; public float yInput = 0; public float widthX; public float heightY; void Start() { startPos = knob.position; targetPos = knob.position; widthX = limitingCollider.GetComponent<SphereCollider>().radius * 2; heightY = limitingCollider.GetComponent<SphereCollider>().radius * 2; } void Update() { knob.position = targetPos; UpdateXInput(); UpdateYInput(); } void OnTouchStay(Vector3 point) { targetPos = new Vector3(point.x, point.y, targetPos.z); } void OnTouchUp() { targetPos = startPos; } void OnTouchExit() { targetPos = startPos; } void UpdateXInput() { xInput = Mathf.Clamp01((knob.localPosition.x + widthX / 2) / widthX); if (xInput == 0.5f) { return; } if (xInput > 0.5f) { xInput = 1f; } else { xInput = 0f; } } void UpdateYInput() { yInput = Mathf.Clamp01((knob.localPosition.y + heightY / 2) / heightY); if (yInput == 0.5f) { return; } if (yInput > 0.5f) { yInput = 1f; } else { yInput = 0f; } } } Thank you.
Mobile touch joysticks should generally be coded so they are sticky: as long as the finger continues to touch the screen, the input should continue to be valid, deflected by a limited amount of the actual deflection, usually limited to a box or a circle around the initial point of contact. It sounds like this script simply stops sending values when it no longer detects collision within the sphere. I have a little module here that contains a VAButton class you can use for this: it is sticky, and once your finger goes down inside the rect, it keeps giving valid output until you let go. https://bitbucket.org/kurtdekker/proximity_buttons