MattRix / Futile

A super simple Unity 2D framework
http://struct.ca/futile
833 stars 130 forks source link

[Feature request] Simulate programmatically a touch in FTouchManager #213

Open jpsarda opened 10 years ago

jpsarda commented 10 years ago

The same way you simulate touch events with mouse events, would be cool to be able to fake a touch. I've built a stress machine (a loop randomly faking a click on the screen every 4 frames) on my current project, and it revealed a lot of problems that would have taken a long time to reproduce and fix with user feedback.

I know you've planned to change the FTouchManager so I wont submit a pull request, but let me know if you want to see it.

MattRix commented 10 years ago

Sure yeah, I'd like to see it. The FTouchManager is different now, but it should be even easier to integrate into it, I think.

jpsarda commented 10 years ago

Here it is, it allows to fake single touch (not multi touch).

Added these methods in FTouchManager :

    protected FTouch _lastFakeTouch;    
    protected bool _fakeTouchToProcess=false;
    public void FakeTouchDown(Vector2 pos) {
        FTouch touch=new FTouch();
        touch.fingerId = 100;
        touch.tapCount = 1;
        touch.deltaTime = Time.deltaTime;
        touch.deltaPosition = new Vector2(0,0);
        touch.position = pos;
        touch.phase = TouchPhase.Began;

        _lastFakeTouch=touch;
        _fakeTouchToProcess=true;
    }
    public void FakeTouchUp() {
        _lastFakeTouch.phase = TouchPhase.Ended;
        _fakeTouchToProcess=true;
    }
    public void FakeTouchMove(Vector2 pos) {
        _lastFakeTouch.phase = TouchPhase.Moved;
        _lastFakeTouch.deltaPosition = pos-_lastFakeTouch.position;
        _lastFakeTouch.position=pos;
        _fakeTouchToProcess=true;
    }

A few changes in HandleUpdate :

        int touchCount = Input.touchCount;
        int offset = 0;

        if(wasMouseTouch) touchCount++;
        if (_fakeTouchToProcess) touchCount++;

        FTouch[] touches = new FTouch[touchCount];

        if(wasMouseTouch) 
        {
            touches[offset] = mouseTouch;
            offset++;
        }

        if (_fakeTouchToProcess)
        {
            touches[offset] = _lastFakeTouch;
            offset++;
            _fakeTouchToProcess=false;
        }

Then a stress test engine example would be something like this :

    protected void HandleUpdate ()
    {
        frameCount++;
        if (frameCount%4==0) {
            Futile.touchManager.FakeTouchDown(new Vector2(RXRandom.Range(-Futile.screen.halfWidth,Futile.screen.halfWidth),RXRandom.Range(-Futile.screen.halfHeight,Futile.screen.halfHeight)));
        } else if (frameCount%4==2) {
            Futile.touchManager.FakeTouchUp();
        }
    }