位置: 编程技术 - 正文

Unity3D游戏开发之在Android视图中嵌入Unity视图(Unity3D游戏开发标准教程)

编辑:rootadmin

推荐整理分享Unity3D游戏开发之在Android视图中嵌入Unity视图(Unity3D游戏开发标准教程),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:Unity3D游戏开发基础,Unity3D游戏开发(第2版),Unity3D游戏开发引擎,Unity3D游戏开发标准教程,Unity3D游戏开发标准教程,Unity3D游戏开发毕业论文,Unity3D游戏开发标准教程,unity3D游戏开发,内容如对您有帮助,希望把文章链接给更多的朋友!

转载自: 今天我们继续来研究Unity在Android平台上的扩展,通过昨天的学习,大家已经知道Unity和Android是可以互相调用的,可是相信大家从昨天的文章中可以看出,如果单纯地从调用Android接口的角度来看,我们已经可以实现这一目的。可是从实际开发的角度来看,我们只是迈出了很小的一步。为什么这么说呢,因为在实际的开发中可能我们不仅需要从接口上实现与Unity的对接,而且需要从界面上实现与Unity的对接。比如,现在主流的网游都会在游戏开始的时候给玩家一个选择创建角色的过程,通常界面上会显示各种类型的角色设定,玩家可以通过界面了解每种类型的角色的特点,从而选择合适自己的角色。从技术上来讲,这一部分我们可以完全使用Unity3D的GUI系统来实现,不过本文的目的在于探讨Unity和Android的对接问题,因此我们可以假定Android在整个对接过程中扮演着界面渲染的角色,而Unity则负责游戏逻辑的维护。那么,这样就诞生了我们今天的问题,能不能将Unity作为Android界面的一部分嵌入到Android应用中呢?答案当然是肯定的。

一、为Unity编写Android插件

首先,我们来看Unity中为Android提供的类文件UnityPlayerNativeActivity.java,该文件位于如下位置:

D:ProgramFilesUnityEditorDataPlaybackEnginesandroidplayercomunity3dplayer(在不同的计算机上可能会有所不同,大家灵活运用即可)

[java] view plaincopyprint?package com.unity3d.player; import android.app.NativeActivity; import android.content.res.Configuration; import android.graphics.PixelFormat; import android.os.Bundle; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; public class UnityPlayerNativeActivity extends NativeActivity { protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code // Setup activity layout @Override protected void onCreate (Bundle savedInstanceState) { requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); getWindow().takeSurface(null); setTheme(android.R.style.Theme_NoTitleBar_Fullscreen); getWindow().setFormat(PixelFormat.RGB_); mUnityPlayer = new UnityPlayer(this); if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true)) getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(mUnityPlayer); mUnityPlayer.requestFocus(); } // Quit Unity @Override protected void onDestroy () { mUnityPlayer.quit(); super.onDestroy(); } // Pause Unity @Override protected void onPause() { super.onPause(); mUnityPlayer.pause(); } // Resume Unity @Override protected void onResume() { super.onResume(); mUnityPlayer.resume(); } // This ensures the layout will be correct. @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); mUnityPlayer.configurationChanged(newConfig); } // Notify Unity of the focus change. @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); mUnityPlayer.windowFocusChanged(hasFocus); } // For some reason the multiple keyevent type is not supported by the ndk. // Force event injection by overriding dispatchKeyEvent(). @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_MULTIPLE) return mUnityPlayer.injectEvent(event); return super.dispatchKeyEvent(event); } // Pass any events not handled by (unfocused) views straight to UnityPlayer @Override public boolean onKeyUp(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { return mUnityPlayer.injectEvent(event); } @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } /*API*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); } } 熟悉Android开发的朋友一定对这个类觉得&#;熟吧,NativeActivity是Google在Android3.0后推出的,其目的是为了让开发者使用C/C&#;&#;在NDK环境下管理Activity的生存周期,于是我们可以大胆的猜测Unity之所以可以和Android进行交互是因为NDK提供了方便之门,果然,博主在Unity的目录下找到了libmain.so、libunity.so、libmono.so这三个文件,这证实我们的猜想是正确的。在这个类中,我们可以看到Unity做了大量的初始化工作,并且重写了NativeActvity的相关方法。不知道大家还记不记得我们在前一篇文章中定义主Activity时,我们是让它继承自UnityPlayerActivity而不是Android的Activity。那么,这个UnityPlayerActivity是什么呢?我们打开它的文件:

[java] view plaincopyprint?package com.unity3d.player; /** * @deprecated Use UnityPlayerNativeActivity instead. */ public class UnityPlayerActivity extends UnityPlayerNativeActivity { } 这时候我相信大家和博主一样都有一种恍然大悟的感觉,原来它是继承自UnityPlayerNativeActivity的,换句话说Unity在Android这部分其实做了两件事,即初始化Activity和重写相关的方法。我们注意到代码中的注释提示这个类已经deprecated建议我们使用UnityPlayerNativeActivity,这点我们暂时不用管,我们依然使用UnityPlayerActivity,因为它和UnityPlayerNativeActivity本质上是一样的。好了,到目前为止,如果大家已经理解了这里所有的内容,那么我们可以浩浩荡荡地冲向Eclipse开始编写Android项目了。

和昨天一样,我们创建一个Android项目并将其设为库,这里我们将其包名设为com.android.unityview4android。这个名称很重要,我们在Unity中将继续使用这个名字。首先我们来创建一个Android的布局文件activity_main.xml:

Unity3D游戏开发之在Android视图中嵌入Unity视图(Unity3D游戏开发标准教程)

[html] view plaincopyprint?<RelativeLayout xmlns:android=" xmlns:tools=" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" > <Button android:id="@&#;id/BtnPre" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:text="@string/BtnPre" /> <LinearLayout android:id="@&#;id/UnityView" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@&#;id/BtnNext" android:layout_below="@&#;id/BtnPre" android:orientation="vertical" > </LinearLayout> <Button android:id="@&#;id/BtnNext" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:text="@string/BtnNext" /> </RelativeLayout>

这里我们放置了两个Button按钮,分别用来控制Unity向前、向后切换模型,在屏幕中间有一个叫做UnityView的线性布局,它将作为Unity视图的父控件,即我们会将Unity的视图放到这个控件里。我们注意到在UnityPlayerNativeActivity.java类中有一个UnityPlayer类型的变量mUnityPlayer,该类型博主目前没有找到官方的相关说明,博主推测它应该是负责Unity界面渲染的一个类吧,在这个类中有一个getView()方法,它将返回一个View类型的&#;,我们便可以通过这种方法将其添加到Android视图里,因为我们已经准备好了一个UnityView的父控件,所以这一切实现起来变得相当地容易:

[java] view plaincopyprint?package com.android.unityview4android; /*导入Unity提供的类*/ import com.unity3d.player.UnityPlayer; import com.unity3d.player.UnityPlayerActivity; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; public class MainActivity extends UnityPlayerActivity { private Button BtnPre,BtnNext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //设置当前布局文件 setContentView(R.layout.activity_main); //获取显示Unity视图的父控件 LinearLayout mParent=(LinearLayout)findViewById(R.id.UnityView); //获取Unity视图 View mView=mUnityPlayer.getView(); //将Unity视图添加到Android视图中 mParent.addView(mView); //上一个 BtnPre=(Button)findViewById(R.id.BtnPre); BtnPre.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { UnityPlayer.UnitySendMessage("GameObject", "ShowPrevious", ""); } }); //下一个 BtnNext=(Button)findViewById(R.id.BtnNext); BtnNext.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { UnityPlayer.UnitySendMessage("GameObject", "ShowNext", ""); } }); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } } 好了,这样我们就完成了Jar库的编写,我们只要将Jar库导入到Unity中,并且按照上一篇文章中所述的方法构建Android插件目录组织相关资源就可以了。最后我们给出AndroidManifest.xml文件:[html] view plaincopyprint?<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="com.android.unityview4android" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="9" android:targetSdkVersion="" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.android.unityview4android.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

二、创建Unity项目 好了,现在我们来创建Unity项目,我们这里创建一个简单地场景,场景中只有一个空游戏体和摄像机,我们将通过脚本的形式来控制Unity渲染,主要的脚本代码如下:

[csharp] view plaincopyprint?using UnityEngine; using System.Collections; public class ModelManager : MonoBehaviour { //模型 public GameObject[] Models; //当前索引 private int index=0; //当前对象 private GameObject mObject; void Start () { this.name="GameObject"; //生成第一个物体 mObject=(GameObject)Instantiate(Models[index]); } public void ShowNext() { //使索引增加 index&#;=1; //范围控制 if(index>Models.Length-1){ index=0; } //销毁原来物体 Destroy(mObject); //生成新物体 mObject=(GameObject)Instantiate(Models[index]); } public void ShowPrevious() { //使索引减少 index-=1; //范围控制 if(index<0){ index=Models.Length-1; } //销毁原来物体 Destroy(mObject); //生成新物体 mObject=(GameObject)Instantiate(Models[index]); } } 这段脚本我们绑定到这个空的游戏体上,脚本的两个方法ShowNext()和ShowPrevious()相对应,通过UnitySendMessage()实现通信。好了,我们来运行项目,如图所示:

我们可以注意到当程序打开的那一瞬间,是Android视图先加载、然后Unity视图才加载的,给人整体的感觉就是在Activity里面嵌套了一个Activity。可是博主马上就发现了一个问题,这Android视图中的按钮无法取得焦点啊,点击事件无效。这是为什么呢?后来博主找到的解决方法是在AndroidManifest.xml文件中的activity子节点下增加如下两行代码:

[csharp] view plaincopyprint?<meta-data android:name="android.app.lib_name" android:value="unity" /> <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" /> 这样问题是解决了,可是我们得搞懂为什么吧,在Unity官方文档中,我们找到了答案:

请注意,NativeActivity在Android2.3以后被引入而且不支持该版本以下的设备。因为触摸/运动事件处理在本机代码,Java视图通常不会看到这些事件。然而,在统一转发机制允许将事件传播到DalvikVM。为了使用这个机制,您需要修改manifest文件如下:

[html] view plaincopyprint?<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android=" package="com.company.product"> <application android:icon="@drawable/app_icon" android:label="@string/app_name"> <activity android:name=".OverrideExampleNative" android:label="@string/app_name"> <meta-data android:name="android.app.lib_name" android:value="unity" /> <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 这段话的意思就是说Android的事件是运行在本机代码中的,Java视图是看不到这些事件的,然而我们可以通过Unity提供的统一转发机制将这些事件发送到Android虚拟机,为了使用这个机制,我们必须修改Android的AndroidManifest.xml文件。博主感觉Android插件这块官方目前做得不是很好,总是给人一种云里雾里的感觉,而且通过各种语言相互调用增加了调试的难度,关于Android更多的内容,大家可以参考官方的文档:点击这里.好了,今天的内容就是这样啦,希望大家喜欢。最后再来看看程序运行的效果吧

UnityRandom介绍 介绍UnityRandom是一个针对Unity3D的伪随机数库,使用C#语言开发。代码和文档都在Github上。UnityRandom采用Mersennetwister伪随机数发生算法,能够快速产生高质

游戏简单控制逻辑 一个轻量级的状态机 出处:

三分钟了解LOD在游戏里面的运用 性能优化

标签: Unity3D游戏开发标准教程

本文链接地址:https://www.jiuchutong.com/biancheng/384566.html 转载请保留说明!

上一篇:【猫猫的Unity Shader之旅】之简述3D图形学(猫的喵喵)

下一篇:UnityRandom介绍(unity random.value)

  • 弥补亏损的应纳税额 例子
  • 企业所得税亏损弥补的规定
  • 一般纳税人的计税方式是什么
  • 我国企业基本所得税的税率
  • 如何查询个人所有贷款记录
  • 支付的画图费没有发票要如何处理
  • 提取法定盈余公积是从净利润中提取吗
  • 兼职人员的差旅费怎么算
  • 公司承担社保能放到生产成本里吗
  • 房屋租赁合同印花税计税依据
  • 委托加工模具的费用计入什么科目?
  • 税率调整后之前签的合同用变更吗
  • 制造行业运输费包括哪些
  • 在外地的分公司可以独立核算开发票吗
  • 作业成本法的成本对象包括哪几个层次
  • 加工费可以计入管理费用吗
  • 出口企业取得失业保险
  • 工会残保金必须缴纳吗
  • 成本的分类有哪些如何分类
  • 对公汇款银行退回
  • 小规模餐饮企业增值税申报表填写
  • php数组函数大全
  • 虚拟机安装apache
  • 债券利息收入征税吗
  • PHP:mb_parse_str()的用法_mbstring函数
  • 小规模纳税人需要缴纳个人所得税吗
  • fedora23安装
  • PHP:mcrypt_create_iv()的用法_Mcrypt函数
  • 代理买卖证券款属于什么科目
  • 软件集成电路企业所得税优惠政策
  • 行走在奥卡万戈河中的大象,博茨瓦纳,非洲南部 (© Markus Pavlowsky/Getty Images)
  • 公司收到社保局的提醒函怎么办
  • ant desgin-vue
  • 工资必须走银行卡吗
  • 会计人员报销差旅费应该给谁审核呢
  • 施工项目的费用包括
  • phpcms 1064错误的解决办法
  • 外资公司股东
  • sql数据库移动
  • db2bigint
  • 电缆租赁发票开具属于什么项目
  • 个税的免税收入
  • 一张记账凭证写不下时合计怎么写
  • linux登录root用户登录
  • MySQL创建数据库语句
  • 个人所得税修改密码怎么改
  • 一般纳税人适用3%税率情况
  • 企业清算未分配利润怎么个税
  • 为什么要进行结账和对账
  • 以银行承兑汇票支付购买原材料款
  • 来料加工账务处理案例
  • 社保退休金计算方法
  • 企业流动资金的筹措应以财政拨款为主
  • 小规模纳税人企业所得税税率
  • 收到上年度企业所得税退税怎么做账
  • 利润表增加,资产负债表减少怎么回事
  • windows server 2003 sp2密钥
  • 重装windows764 位后后如何将apache mysql加入系统服务
  • os x10.11el capitan beta4更新了什么?os x10.11el capitan beta4下载地址
  • 在win7系统中如何用快捷键复制文件或文件夹
  • 查看端口信息命令
  • Windows正在启动卡死
  • win8取消开始界面
  • 升级win10系统后安装谷歌打不开
  • cocos2d-js教程
  • 批处理新建多个文件夹
  • 黑客需要学哪些
  • Lesson02_05 头元素
  • jquery监听页面刷新
  • jquery有哪些
  • Android eclipse for mac redo 快捷键
  • 怎么查询工程师名下的项目
  • 技术转让条件
  • 现在买车是不是免购置税
  • 公积金扣800一个月多少钱
  • 残疾人就业年审经办人
  • 各种税费申报日期
  • 发票真伪查询国税官网12366
  • 个体如何申请税收优惠
  • 珠海车船税的缴纳地点
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设