Is there a good way to check if an arbitrary iOS device supports ARKit? I've looked through UnityARSessionNativeInterface and couldn't see anything really obvious; for now, I'm using the following: Code (CSharp): try { ARKitSessionConfiguration s1 = new ARKitSessionConfiguration (); ARKitWorldTackingSessionConfiguration s2 = new ARKitWorldTackingSessionConfiguration (); if (s1.IsSupported || s2.IsSupported) { IsArKitSupported = true; } else { IsArKitSupported = false; } } catch { } It feels like a bit of a hack though. Any alternatives are welcome!
same question, currently the IsSupported only exist in ARKitSessionConfiguration and ARKitWorldTackingSessionConfiguration, but not exist in UnityARSessionNativeInterface
Please refer to this documentation https://developer.apple.com/documentation/arkit Apple says you can put a requirement in your plist to ensure that your app only runs on ARKit capable devices, otherwise use the Configuration .IsSuppported methods to see if it is supported on the current device.
this though doesn't work that well for me - but it is possible I'm messing things up. I've tested on a device that could run ARKit, but did not have iOS 11, which resulted in immediate crash. Currently I'm trying to do it like so, but with no success: Code (CSharp): iOSVersion = float.Parse(iOS.Device.systemVersion, System.Globalization.CultureInfo.InvariantCulture.NumberFormat); if(iOSVersion<11){ //disable parent of all ARKit objects } ARKitWorldTackingSessionConfiguration c = new ARKitWorldTackingSessionConfiguration(); if(c.IsSupported==false){ //disable parent of all ARKit objects } // otherwise start using ARKit
What is your crash? Please give us as much information as you can. Your code snippet might be more helpful in the context of everything that is happening, but on it's own, it's not very helpful. A text file with your crash log would help.
hey, thanks for getting back to me, here's what i've got: Code (CSharp): 2017-09-07 15:32:00.227809 EuclideanLands[503:204295] [DYMTLInitPlatform] platform initialization successful 2017-09-07 15:32:00.248404 EuclideanLands[503:204211] PlayerPrefsAutoSync: Loaded. 2017-09-07 15:32:00.284996 EuclideanLands[503:204211] -> registered mono modules 0x100eb9990 2017-09-07 15:32:00.441984 EuclideanLands[503:204211] You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist. -> applicationDidFinishLaunching() Player data archive not found at `/var/containers/Bundle/Application/3D394CF2-9D1D-404F-A7FE-E63D013D29C7/EuclideanLands.app/Data/data.unity3d`, using local filesystem2017-09-07 15:32:00.489862 EuclideanLands[503:204211] Metal GPU Frame Capture Enabled 2017-09-07 15:32:00.490099 EuclideanLands[503:204211] Metal API Validation Disabled 2017-09-07 15:32:00.825678 EuclideanLands[503:204211] PlayerPrefsAutoSync: iCloud Supported. Initializing. -> applicationDidBecomeActive() GfxDevice: creating device client; threaded=1 Initializing Metal device caps: Apple A9X GPU Initialize engine version: 5.6.3f1 (d3101c3b8468) OnLevelWasLoaded was found on UnityARGeneratePlane This message has been deprecated and will be removed in a later version of Unity. Add a delegate to SceneManager.sceneLoaded instead to get notifications after scene loading has completed (Filename: Line: 376) OnLevelWasLoaded was found on AROnStart This message has been deprecated and will be removed in a later version of Unity. Add a delegate to SceneManager.sceneLoaded instead to get notifications after scene loading has completed (Filename: Line: 376) UnloadTime: 0.869458 ms Setting up 1 worker threads for Enlighten. Thread -> id: 16f37b000 -> priority: 1 2017-09-07 15:32:03.412198 EuclideanLands[503:204211] PlayerPrefsAutoSync: Sending to iCloud Unloading 8 Unused Serialized files (Serialized files now loaded: 0) UnloadTime: 2.413625 ms FormatException: Unknown char: . at System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider, Boolean tryParse, Double& result, System.Exception& exc) [0x00000] in <filename unknown>:0 at System.Single.Parse (System.String s, IFormatProvider provider) [0x00000] in <filename unknown>:0 at AROnStart.Awake () [0x00000] in <filename unknown>:0 (Filename: currently not available on il2cpp Line: -1) Unloading 13 unused Assets to reduce memory usage. Loaded Objects now: 691. Total: 0.401833 ms (FindLiveObjects: 0.049875 ms CreateObjectMapping: 0.015458 ms MarkObjects: 0.304000 ms DeleteObjects: 0.031875 ms) 2017-09-07 15:32:05.456330 EuclideanLands[503:204211] Uncaught exception: ARKitNotSupportedException: ARKit is not supported in the runtime you are using. Make sure you are using a compatible device and or OS version ( 0 CoreFoundation 0x000000019337a1d8 <redacted> + 148 1 libobjc.A.dylib 0x0000000191db455c objc_exception_throw + 56 2 CoreFoundation 0x000000019337a108 <redacted> + 0 3 EuclideanLands 0x00000001004b9ee8 unity_CreateNativeARSession + 72 4 EuclideanLands 0x00000001000aba98 UnityARSessionNativeInterface__ctor_m3996903657 + 116 5 EuclideanLands 0x00000001000ae2e0 UnityARSessionNativeInterface_GetARSessionNativeInterface_m2987304195 + 108 6 EuclideanLands 0x00000001000a5698 UnityARCameraManager_Start_m1323027489 + 108 7 EuclideanLands 0x000000010048d2cc _Z31RuntimeInvoker_Void_t1841601450PK10MethodInfoPvPS2_ + 28 8 EuclideanLands 0x0000000100db8010 _ZN6il2cpp2vm7Runtime6InvokeEPK10MethodInfoPvPS5_PP15Il2CppException + 68 9 EuclideanLands 0x00000001007ec14c _Z23scripting_method_invoke18ScriptingMethodPtr18ScriptingObjectPtrR18ScriptingArgumentsP21ScriptingExceptionPtrb + 100 10 EuclideanLands 0x00000001007e4d88 _ZN19ScriptingInvocation6InvokeEP21ScriptingExceptionPtrb + 60 11 EuclideanLands 0x00000001008d0b40 _ZN13MonoBehaviour30InvokeMethodOrCoroutineCheckedE18ScriptingMethodPtr18ScriptingObjectPtrP21ScriptingExceptionPtr + 1216 12 EuclideanLands 0x00000001008d0d54 _ZN13MonoBehaviour30InvokeMethodOrCoroutineCheckedE18ScriptingMethodPtr18ScriptingObjectPtr + 92 13 EuclideanLands 0x00000001008cfaec _ZN13MonoBehaviour16DelayedStartCallEP6ObjectPv + 88 14 EuclideanLands 0x0000000100609778 _ZN18DelayedCallManager6UpdateEi + 676 15 EuclideanLands 0x0000000100711ad8 _Z10PlayerLoopv + 440 16 EuclideanLands 0x000000010092fa80 _ZL19UnityPlayerLoopImplb + 32 17 EuclideanLands 0x0000000100040614 UnityRepaint + 140 18 EuclideanLands 0x0000000100040500 -[UnityAppController(Rendering) repaintDisplayLink] + 88 19 GPUToolsCore 0x0000000102b8fb1c -[DYDisplayLinkInterposer forwardDisplayLinkCallback:] + 176 20 QuartzCore 0x00000001965801bc <redacted> + 44 21 QuartzCore 0x0000000196580068 <redacted> + 444 22 IOKit 0x00000001935e7138 IODispatchCalloutFromCFMessage + 372 23 CoreFoundation 0x000000019331056c <redacted> + 180 24 CoreFoundation 0x0000000193328934 <redacted> + 56 25 CoreFoundation 0x00000001933280e8 <redacted> + 436 26 CoreFoundation 0x0000000193325bcc <redacted> + 1840 27 CoreFoundation 0x0000000193254048 CFRunLoopRunSpecific + 444 28 GraphicsServices 0x0000000194cda198 GSEventRunModal + 180 29 UIKit 0x00000001992392fc <redacted> + 684 30 UIKit 0x0000000199234034 UIApplicationMain + 208 31 EuclideanLands 0x000000010003a450 main + 160 32 libdyld.dylib 0x00000001922385b8 <redacted> + 4 ) 2017-09-07 15:32:05.456780 EuclideanLands[503:204211] *** Terminating app due to uncaught exception 'ARKitNotSupportedException', reason: 'ARKit is not supported in the runtime you are using. Make sure you are using a compatible device and or OS version' *** First throw call stack: (0x19337a1c0 0x191db455c 0x19337a108 0x1004b9ee8 0x1000aba98 0x1000ae2e0 0x1000a5698 0x10048d2cc 0x100db8010 0x1007ec14c 0x1007e4d88 0x1008d0b40 0x1008d0d54 0x1008cfaec 0x100609778 0x100711ad8 0x10092fa80 0x100040614 0x100040500 0x102b8fb1c 0x1965801bc 0x196580068 0x1935e7138 0x19331056c 0x193328934 0x1933280e8 0x193325bcc 0x193254048 0x194cda198 0x1992392fc 0x199234034 0x10003a450 0x1922385b8) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)
from the error, it looks like your UnityARCameraManager component is alive, and it tries to instantiate the UnityARSessionNativeInterface which will create the ARSession. You should probably have everything disabled on start, and then enable it if ARKit is supported. Not the other way around. Let me know if this helps.
I don't know how I missed the fact that I can disable the objects and enable them if conditions are met, but managed to try so many obscure solutions. Thanks so much, will update here if it helps!
Here is my disabling of AR code that seems to work. Code (CSharp): public void Awake(){ // Turn off AR Camera if not supported #if UNITY_IOS Debug.Log("UnityEngine.iOS.Device.systemVersion:"+UnityEngine.iOS.Device.systemVersion); float iOSVersion = 11f; float.TryParse(UnityEngine.iOS.Device.systemVersion, out iOSVersion); if(iOSVersion<11f){ Debug.Log("Less than 11"); disableAR(); } var gen = UnityEngine.iOS.Device.generation; Debug.Log("gen:"+gen); if ( gen == UnityEngine.iOS.DeviceGeneration.iPhone4 || gen == UnityEngine.iOS.DeviceGeneration.iPhone4S || gen == UnityEngine.iOS.DeviceGeneration.iPhone5 || gen == UnityEngine.iOS.DeviceGeneration.iPhone5C || gen == UnityEngine.iOS.DeviceGeneration.iPhone5S || gen == UnityEngine.iOS.DeviceGeneration.iPhone6 || gen == UnityEngine.iOS.DeviceGeneration.iPhone6Plus || gen == UnityEngine.iOS.DeviceGeneration.iPad1Gen || gen == UnityEngine.iOS.DeviceGeneration.iPad2Gen || gen == UnityEngine.iOS.DeviceGeneration.iPad3Gen || gen == UnityEngine.iOS.DeviceGeneration.iPad4Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadAir1 || gen == UnityEngine.iOS.DeviceGeneration.iPadAir2 || gen == UnityEngine.iOS.DeviceGeneration.iPadMini1Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadMini2Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadMini3Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadMini4Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch1Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch2Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch3Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch4Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch5Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch6Gen ) { Debug.Log("Device not supported"); disableAR(); } #endif } private void disableAR(){ CameraController.cameraMain.gameObject.GetComponent<UnityARVideo>().enabled = false; CameraController.cameraMain.gameObject.GetComponent<UnityARCameraNearFar>().enabled = false; CameraController.cameraMain.clearFlags = CameraClearFlags.Skybox; GameObject.Find("UnityARKit").SetActive(false); }
dentedpixel Doesn't work in part of checkin iOS version, because iOS version can be 11.0.0 and parsing will give the results 0. It requires to split string with separator '.' Here is my version: Code (CSharp): private bool IsSupportedArKit() { #if UNITY_EDITOR return true; #endif #if UNITY_IOS Debug.Log("UnityEngine.iOS.Device.systemVersion:" + UnityEngine.iOS.Device.systemVersion); float iOSVersion = 11f; string[] ver = UnityEngine.iOS.Device.systemVersion.Split('.'); float.TryParse(ver[0], out iOSVersion); if (iOSVersion < 11f) { Debug.Log("Not supported iOS version: " + iOSVersion); return false; } var gen = UnityEngine.iOS.Device.generation; Debug.Log("gen:" + gen); if (gen == UnityEngine.iOS.DeviceGeneration.iPhone4 || gen == UnityEngine.iOS.DeviceGeneration.iPhone4S || gen == UnityEngine.iOS.DeviceGeneration.iPhone5 || gen == UnityEngine.iOS.DeviceGeneration.iPhone5C || gen == UnityEngine.iOS.DeviceGeneration.iPhone5S || gen == UnityEngine.iOS.DeviceGeneration.iPhone6 || gen == UnityEngine.iOS.DeviceGeneration.iPhone6Plus || gen == UnityEngine.iOS.DeviceGeneration.iPad1Gen || gen == UnityEngine.iOS.DeviceGeneration.iPad2Gen || gen == UnityEngine.iOS.DeviceGeneration.iPad3Gen || gen == UnityEngine.iOS.DeviceGeneration.iPad4Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadAir1 || gen == UnityEngine.iOS.DeviceGeneration.iPadAir2 || gen == UnityEngine.iOS.DeviceGeneration.iPadMini1Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadMini2Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadMini3Gen || gen == UnityEngine.iOS.DeviceGeneration.iPadMini4Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch1Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch2Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch3Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch4Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch5Gen || gen == UnityEngine.iOS.DeviceGeneration.iPodTouch6Gen) { Debug.Log("Device not supported"); return false; } return true; #endif return false; }
Thanks! Good catch, it seemed to work on some devices... but not on others... so your version should be consistent.