Simulate Touch with mouse inside Editor

I would like to know if there is a way to simulate touch using mouse inside the editor. I don’t want, every time, to compile the game and execute on the phone to see if it works. Neither i will be able to keep my phone connected all the time with the computer. Any way to just simulate scrolling, click etc with the mouse?

Thanks,
Davide.

There is no simple solution to this problem. The cleanest solution I came up with is to write a wrapper around UnityEngine.Input class. I implemented only the most common functions, but you can add your own at any time.

To use it, add this line on top of your script that uses UnityEngine.Input:

using Input = InputWrapper.Input;

Source code:

using UnityEngine;
using UnityEngine.Assertions;


namespace InputWrapper {
    public static class Input {
        static bool touchSupported => UnityEngine.Input.touchSupported;
        static Touch? fakeTouch => SimulateTouchWithMouse.Instance.FakeTouch;

        public static bool GetButton(string buttonName) {
            return UnityEngine.Input.GetButton(buttonName);
        }

        public static bool GetButtonDown(string buttonName) {
            return UnityEngine.Input.GetButtonDown(buttonName);
        }

        public static bool GetButtonUp(string buttonName) {
            return UnityEngine.Input.GetButtonUp(buttonName);
        }

        public static bool GetMouseButton(int button) {
            return UnityEngine.Input.GetMouseButton(button);
        }

        public static bool GetMouseButtonDown(int button) {
            return UnityEngine.Input.GetMouseButtonDown(button);
        }

        public static bool GetMouseButtonUp(int button) {
            return UnityEngine.Input.GetMouseButtonUp(button);
        }

        public static int touchCount {
            get {
                if (touchSupported) {
                    return UnityEngine.Input.touchCount;
                } else {
                    return fakeTouch.HasValue ? 1 : 0;
                }
            }
        }

        public static Touch GetTouch(int index) {
            if (touchSupported) {
                return UnityEngine.Input.GetTouch(index);
            } else {
                Assert.IsTrue(fakeTouch.HasValue && index == 0);
                return fakeTouch.Value;
            }
        }

        public static Touch[] touches {
            get {
                if (touchSupported) {
                    return UnityEngine.Input.touches;
                } else {
                    return fakeTouch.HasValue ? new[] {fakeTouch.Value} : new Touch[0];
                }
            }
        }
    }

    internal class SimulateTouchWithMouse {
        static SimulateTouchWithMouse instance;
        float lastUpdateTime;
        Vector3 prevMousePos;
        Touch? fakeTouch;


        public static SimulateTouchWithMouse Instance {
            get {
                if (instance == null) {
                    instance = new SimulateTouchWithMouse();
                }

                return instance;
            }
        }

        public Touch? FakeTouch {
            get {
                update();
                return fakeTouch;
            }
        }

        void update() {
            if (Time.time != lastUpdateTime) {
                lastUpdateTime = Time.time;
                
                var curMousePos = UnityEngine.Input.mousePosition;
                var delta = curMousePos - prevMousePos;
                prevMousePos = curMousePos;

                fakeTouch = createTouch(getPhase(delta), delta);
            }
        }

        static TouchPhase? getPhase(Vector3 delta) {
            if (UnityEngine.Input.GetMouseButtonDown(0)) {
                return TouchPhase.Began;
            } else if (UnityEngine.Input.GetMouseButton(0)) {
                return delta.sqrMagnitude < 0.01f ? TouchPhase.Stationary : TouchPhase.Moved;
            } else if (UnityEngine.Input.GetMouseButtonUp(0)) {
                return TouchPhase.Ended;
            } else {
                return null;
            }
        }

        static Touch? createTouch(TouchPhase? phase, Vector3 delta) {
            if (!phase.HasValue) {
                return null;
            }
            
            var curMousePos = UnityEngine.Input.mousePosition;
            return new Touch {
                phase = phase.Value,
                type = TouchType.Indirect,
                position = curMousePos,
                rawPosition = curMousePos,
                fingerId = 0,
                tapCount = 1,
                deltaTime = Time.deltaTime,
                deltaPosition = delta
            };
        }
    }
}

yes, there is a way to have the mouse simulate a single touch.
Can’t find this option right now, and since I reformatted by laptop and installed unity from scratch, I will have to find how I did it… As soon as I do, I will write down in here.

Update
Well, can’t find it yet, but a nice alternative is to select “simulator” instead of “Game” in the game view.

In Unity 2019.4, using the new Input system.
Go to Window → Analysis → InputDebugger → Options → SimulateTouchInputFromMauseOrPen

Use Unity remote. Unity remote 5

If I understood the problem correctly, in Unity 6, now you can do this:

  1. Add the Input Debug Window (Window → Analysis → Input Debugger)
  2. In the window’s Options dropdown menu (top left corner for me), check Simulate Touch Input From Mouse or Pen
    Now the simulated touch should work in the Play window, not only the Device Simulator window

You can simulate touch with your mouse inside most editors, so you don’t need to run the game on your phone every time.

  • left click = tap

  • click and drag = swipe/scroll

  • many engines support this by default
    What to do:
    Unity: The mouse already works like touch in the editor
    Unreal Engine: “Enable ‘Use Mouse for Touch’” in project settings → input
    Godot: Mouse events generally map to touch in the editor
    better testing (optional):

  • Use an Android emulator or ios simulator for more realistic mobile behavior

  • do final testing on a real phone only when needed