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

时间: 2024-10-13 22:26:02

3D touch在Unity3D中的使用的相关文章

在iOS9中使用3D Touch

iOS9提供了四类API( Home Screen Quick Action . UIKit Peek & Pop . WebView Peek & Pop 和 UITouch Force Properties )用于操作3D Touch.不过无论使用哪一种API,首先需要做的事情是检查3D Touch是否可用. 检测是否支持3D Touch 在iOS9中提供如下的接口用于检查设备是否支持3D Touch: @property(nonatomic, readonly) UIForceTou

Unity3d中3D Text对模型的穿透显示

昨晚,好友在电话里问我在Unity3d中使用3D Text,不想让其穿透模型显示,即想让场景中的3D Text与模型有正确的遮挡关系,怎么解? 今早谷歌上查了查,明白了原因,因为3D Text的默认材质的shader是GUI/Text Shader(自然就有了GUI的穿透显示的特性),而且不可以去手动更改. 记录解决方式如下: 1.自己写个想要的shader,并建个使用它的材质球: 2.导入自己的中文字体: 3.替换掉3D Text上的默认材质球. 首先,搭建一个好友在电话里描述的场景: 新建一

【Unity3d游戏开发】Unity3D中的3D数学基础---向量

向量是2D.3D数学研究的标准工具,在3D游戏中向量是基础.因此掌握好向量的一些基本概念以及属性和常用运算方法就显得尤为重要.在本篇博客中,马三就来和大家一起回顾和学习一下Unity3D中那些常用的3D数学知识. 一.向量概念及基本定义 1.向量的数学定义 向量就是一个数字列表,对于程序员来说一个向量就是一个数组. 向量的维度就是向量包含的"数"的数目,向量可以有任意正数维,标量可以被认为是一维向量. 书写向量时,用方括号将一列数括起来,如[1,2,3] 水平书写的向量叫行向量 垂直书

(转载)Unity3d中3D Text对模型的穿透显示

Unity3D中使用3D Text(Text Mesh)时,如何让场景中的物体和3D Text有正确的遮挡关系.由于3D Text默认材质是(Font Material),他的shader是GUI/Text Shader,自然也就有了GUI的穿透特性,所以我们使用自定义材质就可以解决这个问题了. 1.新建材质,并将如下shader设置给它 Shader "Custom/3D Text Shader" { Properties { _MainTex ("Font Texture

初识3D Touch

3D Touch  概述: 从.Net转来也快有半年之多了,从小生到现在也算是经历了无所bug了,不过还是打到不了Ios在我心目中的地位!!! 一.前言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同的用户交互.但是对于开发人员来说我们确实遇到了一个难题:xcode7是支持3D Touch开发的,可是模拟器并不支持这个手势 不过还好的是,在我们码农界的大

iOS 3d touch设计的秘密

相信很多苹果的用户对这个3d touch这个功能都不是很了解,而苹果设备上的这个交互设计主要是给用户带来更多的互动维度.那苹果公司为啥要这个交互功能,那我们首先来解析一下这个设计的用法:在支持的设备上,人们可以通过按压主屏幕应用程序的图标快速选择特定的操作.在应用程序中,人们可以使用压力来获得项目的预览,可以在一个单独的视图中打开该项目,并获得相关的操作. Peek和PopPeek可以让用户在没有打开应用的情况下预览的应用所支持的快捷操作.轻压有支持Peek的应用图标可以显示一个矩形的Pop视图

由3D touch所想到的那些。

最近在看Fview评测iPhone6s的时候,提到3D touch的一个特性是把你后面想做的事情提到前面来,缩短了思维之间的距离,但是增加了学习难度.后来学习了一段时间的vim,看到了知乎上关于吴军博士提出的五笔打字会打断思维的讨论,发现他们之间都有一个共性就是缩短了思维距离,增加了学习难度,熟练之后却能极大的提高效率. vim学习下来所有的体会就是快捷键太多了,所有的文本操作的都可以直接用左半区的键盘完成.但是快捷键之间都有共性,一旦学会之后很容易记住.作为一个初学者,用到某个功能时好像会在脑

Unity3D中灵活绘制进度条

有时我们需要在Unity3D中绘制进度条,如:           或        如果使用4.6版本以下的unity绘制环形的进度条可能需要费点劲.我搜到的大多数方法都是用NGUI插件,但有时只是为了简单的画一个环形UI,使用NGUI反而还增加了学习成本.有一个利用CutOut材质的方法能够利用alpha值,灵活的控制进度条中需要显示的部分,以环形进度条为例,方法如下: 1.在PS中制作一张如下所示的图,RGB为进度条想要的颜色,alpha值从5-250环形渐变(如果从0-255,在进度为0

iOS9系列专题一——3D Touch

新的触摸体验--iOS9的3D Touch 一.引言 在iphone6s问世之后,很多果粉都争先要体验3D Touch给用户带来的额外维度上的交互,这个设计之所以叫做3D Touch,其原理上是增加了一个压力的感触,通过区分轻按和重按来进行不同的用户交互. 二.在模拟器上学习和测试3D Touch 3D Touch是一个很新颖的设计,可是苹果文档有言: With Xcode 7.0 you must develop on a device that supports 3D Touch. Simu