So here is the situation: Surface tablets do support touch and keyboard / mouse. A laptop running windows 8 without touchscreen does not support touch, but keyboard and mouse. If you build a windows 8 game, it will be available on both surface and laptop. So, my question; how can one detcct if current device (laptop or surface) has got touchscreen? (I kn ow application.platform, but that doesn't covers something like 'metrodesktop' or 'metrosurface'.)
I think you can implement both keyboard mouse input or touch screen accelerator input. Then no matter the current device got touch screen or not, the application can get correct input. Sample code: (1) For keyboard and accelerator: if (Input.GetKey(KeyCode.LeftArrow)) { //Do something while press left arrow } else if (Input.GetKey(KeyCode.RightArrow)) { //Do something while press right arrow } else { // Get the input of accelerator InputX = Input.acceleration.x; } } (2) For touch screen and mouse: Work in the same way with following events: public override void OnTouchBegan(UITouch touch) { ... } public override void OnTouchMoved(UITouch touch) { ... } public override void OnTouchEnded(UITouch touch) { ... } P.S. First time to reply and answer question, hope it can help you.
Kenma is correct in that you don't want different code for tablets and laptops... you want to be able to support both touch and keyboard/mouse regardless of platform, and simply respond to the appropriate events. (Also, some laptops also support touch screens.)
you can use this class: http://msdn.microsoft.com/en-us/library/windows/apps/windows.devices.input.touchcapabilities.ASPx Remember to wrap it with UNITY_METRO define as it will only compile for Windows Store Apps.
Heey Aurimas, that sounds like exactly what I need. How do I implement this? Unity does not recognize 'using windows...' namespace not found.
Thnx for the replys! It is not really an issue of having code for both mouse and touch, but more that a desktop version should look more like a game that that can be played without touch. E.g. smaller buttons or disable some touch stuff at all. For instance, in my game, I have splitscreen modus, that only makes sense on a tablet and not on a desktop, so I want to disable that at all and give the gamer on desktop not that choice.
heey, I got it working...this seems to be the solution... #if !UNITY_EDITOR UNITY_METRO Windows.Devices.Input.TouchCapabilities TouchCapabilities = new Windows.Devices.Input.TouchCapabilities(); if(TouchCapabilities.TouchPresent != 0){ numberOfTouches = TouchCapabilities.TouchPresent; isTouchy = true; } #endif
There is now some 2x1 Intel Notebooks, where you can rotate the screen to change the Notebook to a Tablet. Is it possible in runtime to detect if It is running on "Notebook mode" or "Tablet Mode"? How?
Any advice? I need to detect the change between Tablet and Laptop modes, and need to show the virtual keyboard when needed. https://software.intel.com/en-us/articles/game-design-methodologies-for-2-in-1-devices
Humm.. I think I found something here : https://github.com/InfinitusIT/DeviceExtCapabilitiesUniversal Let's try it!
I was not able to make it work! Any advice anybody? What I need more is to detect if the mouse available now or not.... When I change the Ultrabook to Tablet Mode, Unity hide the hardware mouse and lock the mouse position, but I'm using a custom mouse (a gameobject) and I was not able to detected this change.
This is probably the closest thing to what you want: http://docs.unity3d.com/ScriptReference/TouchScreenKeyboard-isSupported.html
Hi Aurimas! Thanks for the answer! I tested it with TouchScreenKeyboard-isSupported.html but on my Ultrabook it always returns me true! I'm still not able to detect when the user is using it on Tablet or Notebook Mode. There is something else I can try?
There's also Input.mousePresent property. Maybe that works better? Unfortunately, it's kinda hard to define the boundaries of being a tablets or a laptop of such a device...
I think I finally was able to solve it! Code (csharp): [DllImport("user32.dll")] public static extern int GetSystemMetrics(SystemMetric smIndex); public enum SystemMetric { SM_CONVERTABLESLATEMODE = 0x2003, SM_SYSTEMDOCKED = 0x2004, } if ((GetSystemMetrics(SystemMetric.SM_CONVERTABLESLATEMODE) == 0) && (TouchScreenKeyboard.isSupported)) { GameCursor.gameObject.SetActive(false); Debug.Log("slate/tablet mode"); } else { GameCursor.gameObject.SetActive(true); Debug.Log("docked/laptop mode"); }
Everything worked, but now I failed on Windows Store App Validation. GetSystemMetrics in user32.dll is not supported for this application type.
You could also try this - maybe it will work on your hardware: http://stackoverflow.com/questions/...app-is-running-in-windows-8-tab-or-desktop-pc
Hey @Wagenheimer, did you continue work on this? Is it still working, even if you can't publish on the Windows Store? I'm investigating the topic and would love a way to detect the convertible state.
Hi @Martin Sharkbomb! I don't tested it yet, but I just found this : https://msdn.microsoft.com/en-us/magazine/mt590976.aspx Code (csharp): public static bool IsWindows10UserInteractionModeTouch { get { bool isInTouchMode = false; #if UNITY_WSA_10_0 && NETFX_CORE UnityEngine.WSA.Application.InvokeOnUIThread(() => { isInTouchMode = UIViewSettings.GetForCurrentView().UserInteractionMode == UserInteractionMode.Touch; }, true); #endif return isInTouchMode; } } Please let me know if it worked for you!
Based on your code I built this, which seemed to work. I don't have a 2-in-1 device, but a friend of mine tested it and confirmed it. So that's good. Code (CSharp): using System.Collections; using System.Runtime.InteropServices; public class SlateModeDetect : MonoBehaviour { [DllImport("user32.dll")] public static extern int GetSystemMetrics(SystemMetric smIndex); public enum SystemMetric { SM_CONVERTABLESLATEMODE = 0x2003, SM_SYSTEMDOCKED = 0x2004, } public enum ConvertibleMode { LaptopDockedMode, SlateTabletMode }; public ConvertibleMode currentMode; void Update() { if (GetSystemMetrics(SystemMetric.SM_CONVERTABLESLATEMODE) == 0 && TouchScreenKeyboard.isSupported) { if (currentMode == ConvertibleMode.SlateTabletMode) return; currentMode = ConvertibleMode.SlateTabletMode; Cursor.visible = false; Cursor.lockState = CursorLockMode.Locked; Debug.Log("slate/tablet mode"); } else if (currentMode != ConvertibleMode.LaptopDockedMode) { currentMode = ConvertibleMode.LaptopDockedMode; Cursor.visible = true; Cursor.lockState = CursorLockMode.None; Debug.Log("docked/laptop mode"); } } } Also great find on that link. Need to give that a try sometime.
@Martin Sharkbomb I just tested your code on a real device and it works like a charm! Thanks for sharing it!
@Martin Sharkbomb Was you able to publish your APP to Windows Store? Using this code, the validation failed with the error : Supported APIs Error Found: The supported APIs test detected the following errors: API GetSystemMetrics in user32.dll is not supported for this application type. Assembly-CSharp.dll calls this API. Impact if not fixed: Using an API that is not part of the Windows SDK for Windows Store apps violates the Windows Store certification requirements.
GetSystemMetrics is not allowed to be used on Windows Store applications. User32.dll doesn't even exist outside of desktop: you'll crash (or get an exception) if you try to call it on a phone, hololens or xbox.
@Tautvydas Zilys Is there an alternative to detect if the 2x1 is currently on Desktop or Tablet mode?
You could use this API if you're targeting Windows 10: https://msdn.microsoft.com/en-us/li...ement.uiviewsettings.userinteractionmode.aspx
I know that this is an old post, but I have been looking on the Internet and finally found that Unity supports it, just use: Code (CSharp): Input.touchSupported https://docs.unity3d.com/ScriptReference/Input-touchSupported.html