iPhoneTouch.deltaTime missing for phase Stationary?

I’m trying to figure out exactly what iPhoneTouch.deltaTime represents in Unity iPhone 1.5, and i’m confused. In a device build, whenever phase == Stationary, touch.deltaTime seems to either adopt the last known time.deltaTime from a move event, or be zeroed out when the last event was a Began phase.

In the Remote, it seems to either use the last known touch.deltaTime if it was a Moved phase event, or it just picks up a value, but i’m not sure from where.

To see what i’m talking about, create a new scene and attach the following two scripts to mainCamera:

First, DebugWindow.js to get a realtime scrolling view of the touch events on the screen:

static var debugLines : Array;
static var maxLines : int = 20;
var debugSkin : GUISkin;

function Start() {
	
}

function Awake() {
	debugLines = new Array();
	AddLine("Begin Debugging");
}

function OnGUI () {
	GUI.skin = debugSkin;
	var boxWidth = 300;
	var boxHeight = 280;
	var pad = 5;
	if (debugLines) {
		var assembledString : String = debugLines.Join("\n");
		GUI.Box(Rect(Screen.width - boxWidth - pad, pad, boxWidth, boxHeight), assembledString);
	}
}

public static function AddLine(msg : String) {
	Debug.Log("[DW] : " + msg);
	debugLines.Add(String.Format("{0:#.###}", Time.time) + ": " + msg);
	if (debugLines.length >= maxLines) {
		debugLines.Shift();
	}
}

Next, UITouchTesting.js which examines touch events and adds them to our screen debug window:

function Update () {
	if (iPhoneInput.touchCount > 0  (iPhoneInput.GetTouch(0).phase != iPhoneTouchPhase.Canceled)) {
		var touch : iPhoneTouch = iPhoneInput.GetTouch(0);
		if (touch.phase == iPhoneTouchPhase.Began) {
			
			DebugWindow.AddLine("Touch began");
		} else if (touch.phase == iPhoneTouchPhase.Moved) {
			
			DebugWindow.AddLine("Touch moved: " + touch.deltaPosition + ", " + touch.deltaTime);
		} else if (touch.phase == iPhoneTouchPhase.Stationary) {
			
			DebugWindow.AddLine("Touch still: " + touch.deltaPosition + ", " + touch.deltaTime);		
		} else if (touch.phase == iPhoneTouchPhase.Ended) {
			
			DebugWindow.AddLine("Touch ended: " + touch.deltaPosition + ", " + touch.deltaTime);		
		}
	}
}

Is this a bug in the Unity engine? Is phase == Stationary supposed to always have the deltaTime from the Stationary event’s firing to the previous touch event’s timestamp? That way, if we add up all event deltaTimes from a series of touch events, it should approximately be the same as the difference in Time.time between the frames where we captured those events.

If Stationary deltaTime is missing, aggregating touch.deltaTime values is going to be off during touches that stay in one place for a while. It does appear that the deltaTime values for Moved events are accurate. They won’t add up exactly to the Time.time differences because the Events probably happen and have timestamps set apart from the Time.time available in every Update() run.

Question: if nothing changes what point would it have to update information for “during what timeframe did the change happen”?

dreamora: Good question. The documenation leads me to believe that for phase == Stationary, it should represent the delta in timestamps between the Began phase touch event and the Stationary phase touch event.

I think the documentation leads me to believe that I should be able to add up all the deltaTime values from phase == Began and get the total current duration of the swipe.

If there is a strong argument for considering deltaTime on Stationary phase touches invalid, then it should probably be always zeroed out instead of just adopting the value left behind by the last Moved phase.

My understanding of the underying UITouch interface is that each touch event comes with a timestamp and one can use this value to calculate, for example, how long a touch has been stationary. If there is a need to do that in Unity, the hacky way I can see how to do this is to record Time.time values in an Update routine and compare them.

I think deltaTime is a great convenience for use in Moved phase touch events, and I just wish that it was updated for Began->Stationary transitions and also Stationary->Moved transitions.

Unity uses timestamp value from the UITouch to calculate deltaTime. It looks like timestamp for UITouch in Stationary phase is updated only once by OS.

I agree that current behavior makes deltaTime irrelevant for Stationary touches. Thanks for pointing it out. We will address this in the future.

Please submit a bug-report or a feature request (whichever you like best :slight_smile: ).

Thanks, ReJ. I’ve submitted it along with an example project as a feature request.

Over a decade later and it still doesn’t work.

For anyone reading this now, I was able to work around this using:

if(Input.GetTouch(0).phase.Equals(TouchPhase.Stationary))
     timer += Time.deltaTime;

This was C#, btw. Hope it helps someone.

1 Like