It would be great to handle a case where player hold the touch while moving or dragging (swerve mechanics).
Hi @yash_mehrotra! Maybe the tutorial project below can help you.
https://developer.playcanvas.com/en/tutorials/basic-touch-input/
Yeah I have followed this tutorial.
There are four phases i.e. start, moved, end and cancel. But there is a stationary phase (drag hold) while moving the entity through touch events.
In that case the entity stutters.
I don’t see this happening in the tutorial project, or are you using a different approach?
Naah this issue is not related to the project you shared. I am facing it in a game where an entity is moving through swerve mechanics.
I wrote this code in unity using c# to move an entity through swerve mechanics. You could see a stationary phase that unity provide for touch events.
private float startTouch;
private float swipeDelta;
private void Update()
{
if(Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Began)
{
startTouch = touch.position.x;
}
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
{
swipeDelta = touch.position.x - startTouch;
startTouch = touch.position.x;
}
if(touch.phase == TouchPhase.Ended)
{
swipeDelta = 0;
}
}
dir.x = swipeDelta * sideSpeed;
}
I don’t know why this phase doesn’t exist in PlayCanvas. Maybe you can create this phase for yourself, using the existing events. Below a related topic.
PlayCanvas input events generally mirror what you get from the browser. The browser does not have a stationary touch event so PlayCanvas doesn’t have one either
Taking your code here, the way I would do it is:
private float startTouch;
private float swipeDelta;
private void Update()
{
if(Input.touchCount > 0)
{
Touch touch = Input.GetTouch(0);
if(touch.phase == TouchPhase.Began)
{
startTouch = touch.position.x;
}
if (touch.phase == TouchPhase.Moved || touch.phase == TouchPhase.Stationary)
{
swipeDelta = touch.position.x - startTouch;
startTouch = touch.position.x;
}
if(touch.phase == TouchPhase.Ended)
{
swipeDelta = 0;
}
}
dir.x = swipeDelta * sideSpeed;
}
Would translate to something like this:
var TouchTest = pc.createScript('touchTest');
// initialize code called once per entity
TouchTest.prototype.initialize = function() {
this.touching = false;
this.startPosition = new pc.Vec2();
this.currentPosition = new pc.Vec2();
this.setEventsOnOff('on');
this.on('destroy', () => {
this.setEventsOnOff('off');
});
};
TouchTest.prototype.setEventsOnOff = function (onOff) {
const touch = this.app.touch;
if (touch) {
this.app.touch[onOff](pc.EVENT_TOUCHSTART, this.onTouchStart, this);
this.app.touch[onOff](pc.EVENT_TOUCHEND, this.onTouchEndCancel, this);
this.app.touch[onOff](pc.EVENT_TOUCHCANCEL, this.onTouchEndCancel, this);
this.app.touch[onOff](pc.EVENT_TOUCHMOVE, this.onTouchMove, this);
}
};
// update code called every frame
TouchTest.prototype.update = function(dt) {
let swipeDelta = 0;
if (this.touching) {
swipeDelta = this.currentPosition.x - this.startPosition.x;
this.startPosition.copy(this.currentPosition);
console.log(swipeDelta);
}
};
TouchTest.prototype.onTouchStart = function(event) {
const touches = event.touches;
this.touching = touches.length === 1;
if (this.touching) {
this.startPosition.set(touches[0].x, touches[0].y);
this.currentPosition.set(touches[0].x, touches[0].y);
}
};
TouchTest.prototype.onTouchEndCancel = function(event) {
const touches = event.touches;
this.touching = touches.length === 1;
};
TouchTest.prototype.onTouchMove = function(event) {
const touches = event.touches;
if (this.touching) {
this.currentPosition.set(touches[0].x, touches[0].y);
}
};
// swap method called for script hot-reloading
// inherit your script state here
// TouchTest.prototype.swap = function(old) { };
// to learn more about script anatomy, please read:
// https://developer.playcanvas.com/en/user-manual/scripting/
Alternatively, you could try https://github.com/Maksims/mr-Tap as an alternative input system
Thankyou for this. I would verify the same.