0、開篇:
3D touch隨著iOS9發(fā)布,它并不是一個單獨的技術(shù),而是可以分為PRessure sensitivity、quick action以及peek&pop。在官方的介紹中提到可以給游戲更好的體驗,但是實際上個人感覺除了pressure sensitivity能夠改變游戲的操作方式外,quick action以及peek&pop真心是為APP設(shè)計的。
1、pressure sensitivity的使用:
首先在unity的腳本中添加檢查是否支持3D touch的函數(shù),這個函數(shù)本質(zhì)是調(diào)用iOS代碼的。
[DllImport("__Internal")] // return 1 when device is support 3d touch private static extern int _checkForceTouchCapability(); public static int CheckForceTouchCapability() { return _checkForceTouchCapability(); }
對應(yīng)的iOS代碼為
-(NSInteger)CheckForceTouchCapability{ if ([[[UIDevice currentDevice] systemVersion] floatValue] < 9.0) { isSupport3DTouch = NO; return 0; } if(self.rootViewController.view.traitCollection.forceTouchCapability == UIForceTouchCapabilityAvailable) { isSupport3DTouch = YES; return 1; } else { isSupport3DTouch = NO; return 0; }}
下面是響應(yīng)壓力變化的處理函數(shù),這次用傳遞函數(shù)指針到oc代碼的方式來做,當然你也可以在iOS中使用UnitySendMessage方法。
private delegate void touch_event_callback_delegate(float force, float maximumPossibleForce);private static Action<float, float> touchEventCallback;[DllImport("__Internal")]private static extern void _registTouchEventCallback(touch_event_callback_delegate func);public static void RegistTouchEventCallback(Action<float, float> func) { touchEventCallback = func; _registTouchEventCallback(ExecuteTouchEventCallback); }[MonoPInvokeCallback(typeof(touch_event_callback_delegate))]private static void ExecuteTouchEventCallback(float force, float maximumPossibleForce) { touchEventCallback(force, maximumPossibleForce); }
對應(yīng)的iOS代碼為
typedef void (*registTouchEventCallbackFunc)(float, float);static registTouchEventCallbackFunc touchEventCallback = nil;-(void)registTouchEventCallback:(registTouchEventCallbackFunc) func{ touchEventCallback = func;}
unity生成的Xcode工程中有個UnityView.mm文件,為了能夠獲取iOS中的壓力變化,需要修改一下的代碼
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{ UnitySendTouchesBegin(touches, event); [UnityAppController UpdateForce:touches];}- (void)touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event{ UnitySendTouchesEnded(touches, event); [UnityAppController TouchesEndorCancelled:touches];}- (void)touchesCancelled:(NSSet*)touches withEvent:(UIEvent*)event{ UnitySendTouchesCancelled(touches, event); [UnityAppController TouchesEndorCancelled:touches];}- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event{ UnitySendTouchesMoved(touches, event); [UnityAppController UpdateForce:touches];}
UpdateForce和TouchesEndorCancelled的定義為:
/** * 實時反饋壓感 * * @param touches touch數(shù)據(jù) */+(void)UpdateForce:(NSSet<UITouch *>*) touches{ if (isSupport3DTouch && touchEventCallback != nil) { touchEventCallback(touches.anyObject.force, touches.anyObject.maximumPossibleForce); } }/** * touchesEnded或者touchesCancelled觸發(fā)時的處理 */+(void)TouchesEndorCancelled:(NSSet<UITouch *>*) touches{ if (isSupport3DTouch && touchEventCallback != nil) { touchEventCallback(0, touches.anyObject.maximumPossibleForce); }}
其實用UnitySendMessage是最簡單的,在TouchesEndorCancelled中force直接賦值為0的原因是我在測試的過程中發(fā)現(xiàn)快速的點擊并且離開屏幕有時拿到的force不是0,這樣在游戲中使用這個力的時候會有問題。
2、quick action的應(yīng)用
目前想到的就是快速進入某個游戲場景吧,或者進入游戲后直接開啟某個UI,總之對游戲性上沒啥幫助。我在Demo中做的是快速進入場景2,默認應(yīng)該是進入場景1。首先需要在info.plist中進行設(shè)置:
<key>UIapplicationShortcutItems</key> <array> <dict> <key>UIApplicationShortcutItemIconType</key> <string>UIApplicationShortcutIconTypePlay</string> <key>UIApplicationShortcutItemTitle</key> <string>JUMP TO SCENE 2</string> <key>UIApplicationShortcutItemType</key> <string>$(PRODUCT_BUNDLE_IDENTIFIER).action</string> <key>UIApplicationShortcutItemUserInfo</key> <dict> <key>scene</key> <string>2</string> </dict> </dict> </array>
核心是設(shè)置UIApplicationShortcutItemUserInfo,因為我們拿到的參數(shù)是從userinfo中拿到的。在使用quick action時unity中的編程非常少,主要是iOS編程。
首先需要在UnityAppcontroller.mm中添加:
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded)) completionHandler { BOOL bHandledShortCutItem = [self handleShortCutItem:shortcutItem]; completionHandler(bHandledShortCutItem);}-(BOOL)handleShortCutItem:(UIApplicationShortcutItem*) shortcutItem{ BOOL handled = NO; NSString *str = (NSString *)[shortcutItem.userInfo objectForKey:@"scene"]; if (str != nil) { handled = YES; UnitySendMessage("Interface", "ExecuteQuickAction", [str UTF8String]); } return handled;}
這個系統(tǒng)方法是用于處理在screen使用quick action進入游戲的。看了很多別人寫的例子,在didFinishLaunchingWithOptions中會調(diào)用handleShortCutItem,然后返回NO,這樣可以避免performActionForShortcutItem的調(diào)用。但是實際在測試中發(fā)現(xiàn)完全不需要在didFinishLaunchingWithOptions中會調(diào)用handleShortCutItem。
3、peek&pop
完全沒有想到怎么用到游戲中,而且發(fā)現(xiàn)在peek時會有一個模糊的遮罩層。
4、Demo地址:https://github.com/klkucan/Unity_For3DTouch
新聞熱點
疑難解答