TouchPhase.Began is always firing

Hi,

I am testing my iphone game with unity remote, but touchphase.began is always running.

code:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class Joystick : MonoBehaviour {

	private Vector3 origin;
	public float flexibility;
	private bool pointerDown;
	public RectTransform joystickBoundaries;
	public CanvasScaler controlCanvas;
	public GameObject player;
	private Vector3 playerPoleTarget;
	public Touch closestTouch;
	
	void Start () {
		origin = joystickBoundaries.localPosition;
	}
	
	void Update () {
		if (pointerDown == true)
		{	
			if (closestTouch.phase == TouchPhase.Moved)
			{	
				float xScale = controlCanvas.referenceResolution.x / Screen.width;
				float yScale = controlCanvas.referenceResolution.y / Screen.height;
				float fromLeft = origin.x + controlCanvas.referenceResolution.x / 2;
				float fromBottom = origin.y + controlCanvas.referenceResolution.y / 2;
				Vector3 touchPos = new Vector3 (closestTouch.position.x * xScale - fromLeft, closestTouch.position.y * yScale - fromBottom, 0);
				if (Vector3.Distance (Vector3.zero, touchPos) > flexibility)
				{
					touchPos = Vector3.ClampMagnitude (touchPos, flexibility);
				}
				GetComponent <RectTransform> ().localPosition = touchPos;
				playerPoleTarget = touchPos * 10;
				player.transform.LookAt (new Vector3 (player.transform.position.x + playerPoleTarget.x, player.transform.position.y, player.transform.position.z + playerPoleTarget.y));
				player.GetComponent <PlayerController> ().direction = Vector3.forward * touchPos.y + Vector3.right * touchPos.x;
			}
			if (closestTouch.phase == TouchPhase.Ended)
			{
				pointerDown = false;
				GetComponent <RectTransform> ().localPosition = Vector3.zero;
				player.GetComponent <PlayerController> ().direction = Vector3.zero;
			}
		}
	}
	
	void OnMouseDown () {
		if (Input.touchCount > 0)
		{
			float distance = Mathf.Infinity;
			foreach (Touch touch in Input.touches)
			{	
				float xScale = controlCanvas.referenceResolution.x / Screen.width;
				float yScale = controlCanvas.referenceResolution.y / Screen.height;
				float fromLeft = origin.x + controlCanvas.referenceResolution.x / 2;
				float fromBottom = origin.y + controlCanvas.referenceResolution.y / 2;
				Vector3 touchPos = new Vector3 (touch.position.x * xScale - fromLeft, touch.position.y * yScale - fromBottom, 0);
				float newDistance = Vector3.Distance (origin, touchPos);
				if (newDistance < distance)
				{
					closestTouch = touch;
					distance = newDistance;
				}
			}
			pointerDown = true;
		}
	}
}

Okey, I think I know what the problem is, I’ll try to explain, but you have to pardon (and endure) my bad english.

The “Touch” is a struct that is built on each update of the Input.Touch… when you do

if (newDistance < distance)
{
  closestTouch = touch;
  distance = newDistance;
}

You are taking a “snapshot” of the actual Touch, with this I Mean the “Touch” you are storing is not being updated constantly, it’s just a record of how the “Touch” was in the specific moment that “OnMouseDown” was executed, and this will always lead to having a picture of a “Touch” that is “Phase == Begin”…

Take a look at the “Touch” docs, you will notice this property “fingerID”. This is the identificator (supposedly) of the finger. This is actually what you want. This gives you the key to finding the “same Touch” in subsequent frames.
Look, like this →

foreach (Touch touch in Input.touches)
{
  if (touch.fingerId == closestTouch.fingerId)
  {//BAM! this is the updated version of your target!
    closestTouch = touch;//So you can do this BEFORE your code
    //In order to keep it just like it is now
  }
}

Add that at the beginning of the Update.

I’ll keep an eye on the thread… for karmic purposes, so tell me how it goes

Adios!

No one had this issue because no one uses such a strange code ^^.

Touch is a struct and you only obtain the current state in OnMouseDown which only fires once for each touch. In Update you only use the (outdated) state you obtained in OnMouseDown. This stats doesn’t change. You have to read Input.touches every frame. If you want remember a certain touch you have to remember the fingerId of that touch and look for that touch in the touches array