app暂停 unity3d

2016-12-28 15:38:48 APupilofUnity 阅读数 717
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

简单的Android程序退出脚本如下:

//按Esc键退出程序
void Update ()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Application.Quit();
}
}

可以将按键改为任意键或者按钮。
在我的程序中,使用到的是点击UI上的Button实现退出程序。
在程序中用到的是射线检测,并点击button。
代码如图:这里写图片描述

然后在unity中,添加一个Button,在Button上添加一个点击事件,如图:
这里写图片描述
在On Click上添加一个挂有该脚本的Object,然后选择点击事件调用的方法,就可实现。

2014-10-22 14:59:10 baijiajie2012 阅读数 960
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

首先,我也是第二天学习Unity3D,所以这篇系列也是算作我的学习笔记,同时也是我第一篇系列文章,有写不对的地方希望大家多多包涵,并且指正出来。

先是界面,Unity3D采用的是编辑器+MonoDevelop的组合,当然,也可以用编辑器加上VS2013,这个看个人喜欢。

主界面如下:(这个界面经过了我的调整,当然你也可以调整自己的界面)

Unity3d编辑器的主界面


编辑器有一些预设的界面提供给我们使用,在右上角的Layout下拉框。可以试着调一下

有一个地方非常常用,就是中间的非常像播放器按钮的三个按键 如下:


第一个按钮是播放,也就是运行游戏的意思,第二个按钮是暂停,第三个是运行到下一帧。

Unity3D支持实时调试,实时编译的,也就是你可以在运行的时候修改代码,然后直接看到结果。但是不建议这么做,因为可能在复杂的情况下会导致一些问题使游戏崩溃。

下面说一说Unity3D的基本概念:

Scene:游戏中的场景,和cocos2dx中的场景的概念一致,没什么区别,比如登陆界面是一个场景,游戏界面是一个场景。

GameObject:场景中的最小元素,所有的显示在界面上的东西都叫GameObject,空的GameObject加上各种组件之后 就可以组成一个一个的方块,光源,地图等控件

Component:组件,类似于GameObject的附加元素,组合起来就是各种各样的控件

2017-02-14 09:59:01 ybhjx 阅读数 2668
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

原文: http://www.cnblogs.com/kuangwu/archive/2013/06/18/3141865.html


做移动互联网类型的开放,很多情况得考虑移动设备的暂停与退出时,做某些数据操作或UI。

1,退出事件,Unity3d,InPut就包含了:

Input.GetKey(KeyCode.Escape) 、 Input.GetKey(KeyCode.Home) 、Input.GetKey(KeyCode.Menu);

2,暂停事件,Unity3d的

OnApplicationFocus、OnApplicationPause两者结合起来

如:

[AddComponentMenu("WuKk/Public/Game Pause Quit")]

publicclass GamePauseQuit : MonoBehaviour {

public  delegate  void GameQuitDelegate();

public  static  event GameQuitDelegate gameQuitDelegate;

 

public  delegate  void GamePauseDelegate();

public  static  event GamePauseDelegate gamePauseDelegate;

bool isPause=false;

void OnEnable(){

isPause=false;

}

void  Update(){

    if (Input.GetKey(KeyCode.Escape) || Input.GetKey(KeyCode.Home) ||Input.GetKey(KeyCode.Menu))

{

  if(gameQuitDelegate!=null)

gameQuitDelegate();

else 

  Application.Quit();

}

void OnApplicationFocus(){

#if UNITY_IPHONE || UNITY_ANDROID

  isPause=true;

#endif

}

 

void OnApplicationFocus(){

#if UNITY_IPHONE || UNITY_ANDROID

if(isPause)

{

isPause=false;

if(gamePauseDelegate!=null)

gamePauseDelegate();

}

#endif

}

}



2014-07-19 12:26:37 s10141303 阅读数 3032
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

很多开发者对OC语言、C语言并不熟悉,自行封装API存在困难,故我特地编写本文让大家可以更快更好的进行SDK接入 本文是参照http://bbs.18183.com/thread-456979-1-1.html的解决方案对SDK常用API进行了封装,有兴趣的同学可以在完成DEMO后了解一下API封装原理。

    本文所用到的91SDK版本号为3.3。该版本SDK并未发布。如是新游需要试用,请联系技术支持。 此UNITY3D的DEMO工程项目( U3DPRJDEMOFORSDK33.zip (148.46 KB, 下载次数: 215) ),大家下载后修改少量代码即可用在目前91SDK上。

     运行起来的DEMO如下图,我封装了91SDK常用API,如还需其他不常用API,大家看本文后可以自行添加。DEMO的场景中有2个文件夹,Code是放游戏脚本的,Plugins是放封装SDK-API的.h和.m文件。



    Test.cs是我用做DEMO界面的问题代码文件,模拟游戏脚本对SdkConector类进行调用;

    SdkConector.cs是游戏脚本对SDK-API进行调用,和实现一些SDK回调的必要文件。游戏项目要调用这个脚本,任意找个生效的场景进行绑定,本例中我是Create Empty,任意取个名字,将该脚本绑定。





     DEMO相当简单,代码注释我也写的很全,大家花几分钟看看代码后就可以进行Player Setting了。91渠道对软件标示符有要求,必须包含91字段。这里特别说明一点:接入SDK的UNITY3D项目不能在模拟器中进行运行的,只能在真机上进行调试。



    Build生成iOS游戏项目后,把DEMO中的
Plugins文件夹拉进iOS项目中的Classes文件夹下,将91SDK的SDK文件夹整个拖入Frameworks文件夹,完成后,应如下图。




    找到Other linker Flags,在第1列加入-ObjC,注意大小写。



    按照SDK包内的客户端文档,进行环境配置,加入必要的系统类库。



    按照要求,加入
URL Schemes,如下图。



    91SDK有一个规定要加入暂停页功能,我没有找到
UINTY3D的从前台进入后台的事件,所以我采用的是91SDK客户端文档的做法,在AppController的文件头部引入头文件后,在如下图位置加入SDK暂停页API的调用。




    连上手机后,RUN一下这个iOS项目就可以看见DEMO了。


附上很重要的帖子: 
91SDK接入及游戏发布、更新流程 http://bbs.18183.com/thread-99382-1-1.html
91SDK必须接入的功能规定  http://bbs.18183.com/thread-529673-1-1.html




2015-12-18 17:36:40 foreverhyh58 阅读数 12636
  • Unity 值得看的500+ 技术内容列表

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏、建筑可视化、实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎。

iOS与Unity3d的交互实现

最近在公司写的项目是基于iOS与Unity3d的,之前也写了不少的iOS与Unity的项目,但是这次将两者结合开发还是第一次。项目的第一条功能需求就是:实现从iOS原生界面到Unity的跳转。

看似简单,但是却不知道怎么下手,修改Unity导出到iOS的封装好的代码是肯定的,但是至于改哪里,怎么改却是比较难。和一般的coding一样,一上来先是各种找解决方案和样例,不管是国内大神雨松momo的博客,还是墙外的社区都是搜刮了一番,运气挺好,在某岛国的博客中有人写了一种解决方案。链接戳这里:
https://github.com/mythosMatheWG/unityIntoIOSSample

这里提供的解决方案并没有给出完整的解释,原博主也只是一步步教你在哪里改代码,虽然能运行,但是却不知所以然。而且,这套解决方案有Bug,后来才知道:如果没有处理好ViewController与Unity之间的关系,会导致跳转到Unity之后出现如下错误:

opengles-error-0x0502

然后你的Unity界面内容就糊掉了==!

——继续找,在另外一篇帖子里面看到了比较完整的另外一种解决方案,链接戳这里:
http://game.ceeger.com/forum/read.php?tid=20533

这篇博客的教程就是在这两种解决方案的基础上进行的。旨在提供一套”你跟着做了就能够实现”的较为完整的解决方案。当然,前提是我们假设你会Unity,iOS的一些基础知识


开发环境

  • xcode 7.2
  • Unity4.6.3 (这个无所谓,因为build出来的OC代码没有太大变化)

开发语言

  • OC

正餐

先让了解一下Unity build出来的iOS工程项目的整个框架以及运行流程
Unity导出的工程项目结构图

Main.mm作为整个项目的入口主要做了如下的事情

const char* AppControllerClassName = "UnityAppController";


int main(int argc, char* argv[])
{
    NSAutoreleasePool* pool = [NSAutoreleasePool new];

    UnityInitTrampoline();
    if(!UnityParseCommandLine(argc, argv))
        return -1;

#if INIT_SCRIPTING_BACKEND
    InitializeScriptingBackend();
#endif

    RegisterMonoModules();
    NSLog(@"-> registered mono modules %p\n", &constsection);
    RegisterFeatures();

    // iOS terminates open sockets when an application enters background mode.
    // The next write to any of such socket causes SIGPIPE signal being raised,
    // even if the request has been done from scripting side. This disables the
    // signal and allows Mono to throw a proper C# exception.
    std::signal(SIGPIPE, SIG_IGN);

    UIApplicationMain(argc, argv, nil, [NSString stringWithUTF8String:AppControllerClassName]);

    [pool release];
    return 0;
}
  • 初始化各个模块
  • 将UnityAppController作为控制类来实现Unity在iOS上显示的功能,换句话说,就是在main之后紧接着就要执行这个类里面的函数

所以视线转移到UnityAppController.mm这里,可以看到这里的代码结构和OC的一般类的代码结构类似,除此之外还有一些C语言程序,作为相对底层中Unity与iOS交互的桥梁,不用管。我们需要关注的是:
UnityAppController.mm中函数执行的顺序以及我们能够在哪里加上我们自己的代码实现”项目入口”的修改,从而做到整个程序一上来先显示我们自己的View,然后通过自定义事件再来跳转到Unity部分。
所以整个项目看起来就像把Unity导出的工程剖开,将我们自定义的部分”塞”进去,从而实现iOS与Unity3d的交互。

操作步骤

1.修改项目入口

从运行项目看到的输出可以知道,UnityAppController.mm函数的执行顺序为:

void UnityInitTrampoline()
- (id)init
-(BOOL)application:(UIApplication*)application willFinishLaunchingWithOptions:(NSDictionary*)launchOptions
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
void AppController_SendUnityViewControllerNotification(NSString* name)
- (NSUInteger)application:(UIApplication*)application supportedInterfaceOrientationsForWindow:(UIWindow*)window
- (void)preStartUnity
- (void)applicationDidBecomeActive:(UIApplication*)application
- (UIWindow*)window                 { return _window; }
...
- (void)startUnity:(UIApplication*)application

执行了StartUnity,会让Unity的界面就会显示出来。
如果要修改项目入口,让Unity界面显示之前先显示我们需要的界面,就需要

在StartUnity函数执行之前实现入口修改,当我们需要跳转到Unity部分的时候再调用StartUnity

通过继承我们可以利用子类来复写UnityAppController中的函数,从而实现入口修改。我这里的做法是,创建一个UnitySubAppDelegate类(因为其作用与一般iOS工程项目中的AppDelegate类似,所以这么叫),这个类是继承自UnityAppController,能够对其函数进行复写。在这里我对StartUnity函数复写:

- (void)startUnity:(UIApplication *)application {

    self.myDataManager = [MyDataManager sharedManager];
    //myDataManager是一个单例,存放一些全局变量,用来进行跳转判断
    if(!self.myDataManager.isInMyHomeView)
    {
        //程序启动时判断是否进入了自定义界面,如果没有则跳转到自定义界面
        viewController= [EnterUnityPartViewController new];
        viewController.appDelegate = self;//将当前类传过去,用于实现从自定义界面启动unity
        viewController.window = self.window;
        self.window.rootViewController = viewController;
        self.myDataManager.myWindow = self.window;//将当前window存放为全局变量,用于后续原生界面与unity的来回切换(因为跳到unity界面之后系统会释放window指针)
    }
    else{
        [super startUnity:application];
    }
}

代码中可以看到,实现修改程序入口的本质就是对window进行修改:

  • 将window指针传给自定义的VC
  • 将自定义的VC作为当前window的rootViewController

进行这样的操作,程序就会在启动后跳转到我们自定义的View上了。

2.从自定义界面启动Unity

我们已经知道,启动Unity的函数是

- (void)startUnity:(UIApplication *)application

那么在我们自定义的VC中我们就能利用这个方法实现从自定义界面启动Unity:

 [self.appDelegate startUnity:UIApplication.sharedApplication];//利用UIApplication.sharedApplication获取当前application

这里的appDelegate就是在步骤1中传过来的值,所以我们需要在当前VC的头文件中定义一个appDelegate:

@property (strong, nonatomic) UnitySubAppDelegate *appDelegate;

3.从Unity界面返回自定义界面

返回自定义的方法有很多,我这里用的方法是在当前window的rootView上面加上一个button来实现跳转(这部分代码同样是加在自定义的VC中,我这里的实现思路是在startUnity函数调用之后就加上按钮)

    UIView *pauseUnityView = [[UIView alloc] initWithFrame:CGRectMake(10, 25, 40, 40)];
    UIButton *backBtn = [[UIButton alloc] initWithFrame:CGRectMake(5, 5, 30, 30)];
    pauseUnityView.backgroundColor = [UIColor whiteColor];
    backBtn.backgroundColor = [UIColor redColor];
    [backBtn addTarget:self action:@selector(doExitSelector) forControlEvents:UIControlEventTouchDown];
    [pauseUnityView addSubview:backBtn];
    [self.window.rootViewController.view addSubview:pauseUnityView];

跳转实现函数为

- (void)doExitSelector{
    UnityPause(true);//跳走之前需要将unity停掉

    MyDataManager *myDataManager = [MyDataManager sharedManager];
    MyDataManager.unityViewController = self.window.rootViewController; //跳走之前需要将当前Unity所在的界面存放在单例中的全局变量内,以便后面再次跳转回Unity能够获取到界面。如果不保存,则根据ARC机制Unity跳转回来之后地址会自动释放,无法获取到界面

    [[[UnityGetMainWindow() rootViewController] view] setHidden:YES];

//    EnterUnityPartViewController *enterVC = [[EnterUnityPartViewController alloc]init];

    self.window.rootViewController = self;//由于当前的跳转函数是写在EnterUnityPartViewController里的,所以当unity再次跳转回来就直接将rootViewController赋值self即可。如果你想跳到其它界面,可以仿照上面注释的语句来实现界面跳转

    [UnityGetMainWindow() makeKeyAndVisible];
}

之前我在找的第二个方案中提到的unity跳回自定义View方法是在Unity导出来的UnityAppController+ViewHandling.mm修改的。但是这样会挺麻烦,每次都要在项目导出后修改这部分代码。

4.从自定义界面跳转Unity

和步骤2不同,在Unity跳转回来后,Unity没有关闭,只是呈现挂起状态。所以Unity界面仍然存在,这也是我们为何在步骤3中需要把Unity界面保存在单例中。这里我们也只需要再进行一次界面跳转就能把Unity呈现出来:

if(self.myDataManger.isRestartInUnity)
        {
            if(!self.window)
            {
            //判断当前window是否为空,这个window是在subAppDelegate中赋值过来的,有可能在界面跳转过程中UnityAppController的window指针被置为空
                self.window = self.myDataManger.myWindow;
            }
            self.window.rootViewController = self.myDataManger.unityViewController;
            [self.window bringSubviewToFront: self.myDataManger.unityViewController.view];//把UnityView放到最前面
            [[[UnityGetMainWindow() rootViewController] view]setHidden:NO];
            [UnityGetMainWindow() makeKeyAndVisible];
            UnityPause(false);//取消暂停
        }

至此,iOS与Unity3d的交互就在这四个步骤中实现。说到底并不难,主要搞懂了几个界面的关系以及iOS的Window,rootView的层级结构就行。
项目文件

有任何问题及不足请指出

Unity3D 脚本参考

阅读数 14367