你的位置:首页 > 操作系统

[操作系统]3D touch在Unity3D中的使用


0、开篇:

     3D touch随着iOS9发布,它并不是一个单独的技术,而是可以分为pressure sensitivity、quick action以及peek&pop。在官方的介绍中提到可以给游戏更好的体验,但是实际上个人感觉除了pressure sensitivity能够改变游戏的操作方式外,quick action以及peek&pop真心是为APP设计的。

1、pressure sensitivity的使用:

    首先在unity的脚本中添加检查是否支持3D touch的函数,这个函数本质是调用iOS代码的。

 [DllImport("__Internal")]  // return 1 when device is support 3d touch  private static extern int _checkForceTouchCapability(); public static int CheckForceTouchCapability()  {    return _checkForceTouchCapability();  }

对应的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;  }}

下面是响应压力变化的处理函数,这次用传递函数指针到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);  }

对应的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数据 */+(void)UpdateForce:(NSSet<UITouch *>*) touches{  if (isSupport3DTouch && touchEventCallback != nil) {    touchEventCallback(touches.anyObject.force, touches.anyObject.maximumPossibleForce);  }  }/** * touchesEnded或者touchesCancelled触发时的处理 */+(void)TouchesEndorCancelled:(NSSet<UITouch *>*) touches{  if (isSupport3DTouch && touchEventCallback != nil) {    touchEventCallback(0, touches.anyObject.maximumPossibleForce);  }}

其实用UnitySendMessage是最简单的,在TouchesEndorCancelled中force直接赋值为0的原因是我在测试的过程中发现快速的点击并且离开屏幕有时拿到的force不是0,这样在游戏中使用这个力的时候会有问题。

2、quick action的应用

   目前想到的就是快速进入某个游戏场景吧,或者进入游戏后直接开启某个UI,总之对游戏性上没啥帮助。我在Demo中做的是快速进入场景2,默认应该是进入场景1。首先需要在info.plist中进行设置:

<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>

核心是设置UIApplicationShortcutItemUserInfo,因为我们拿到的参数是从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;}

这个系统方法是用于处理在screen使用quick action进入游戏的。看了很多别人写的例子,在didFinishLaunchingWithOptions中会调用handleShortCutItem,然后返回NO,这样可以避免performActionForShortcutItem的调用。但是实际在测试中发现完全不需要在didFinishLaunchingWithOptions中会调用handleShortCutItem。

 

3、peek&pop

     完全没有想到怎么用到游戏中,而且发现在peek时会有一个模糊的遮罩层。

4、Demo地址:https://github.com/klkucan/Unity_For3DTouch

 

 

 

 

     




希腊自助游攻略2015怎样去希腊旅游去希腊哪个旅行社好希腊旅游攻略大全希腊旅游攻略博罗象头山雷公峡漂流价格?象头山雷公峡漂流到什么时候? 惠州雷公峡漂流票在哪买便宜?雷公峡漂流网上预订? 惠州博罗雷公峡漂流怎么去?博罗雷公峡漂流交通路线? 台山月亮湾漂流全长多少?台山月亮湾一天游攻略? 北峰山漂流多少钱一次?台山北峰山漂流几点开漂? 北峰山漂流电话?江门北峰山漂流开漂时间? 台山北峰山漂流一天游怎么玩?台山北峰山玩什么? 丰顺漂流门票团购优惠吗?梅州丰顺漂流预订? 亚龙湾森林公园门票多少钱?三亚亚龙湾森林公园本地身份证有优惠吗? 盘点北京周边8大露营地 天地为家式的流浪旅行 亚龙湾森林公园攻略?三亚亚龙湾森林公园门票包含什么? 亚龙湾森林公园好玩吗?三亚亚龙湾森林公园怎么样? 2013年都江堰温泉节 境内外主要机场免税店实用攻略 独具特色的尼泊尔美食 羊卓雍措:天上的仙境 人间的羊卓(2) ISL9011AIRFJZ-T Datasheet ISL9011AIRFJZ-T Datasheet ISL9005IRNZ-T Datasheet ISL9005IRNZ-T Datasheet ISL9011AIRBLZ-T Datasheet ISL9011AIRBLZ-T Datasheet 内蒙古出发去香港游 内蒙古出发去香港游 内蒙古出发去香港游 长春出发 香港游 长春出发 香港游 长春出发 香港游 七台河出发香港旅游 七台河出发香港旅游 七台河出发香港旅游