问题集锦
本节列举了在Unity使用中可能遇到的问题,按平台分别列出.
桌面版
MonoDevelop中“调试”按钮为灰色!
这意味着MonoDevelop没有找到Unity执行程序。在MonoDevelop preferences(Tools->Preferences,译者注,下同)菜单中,在Unity区Debugger选项中指定Unity执行程序位置。
有无办法使MonoDevelop不显欢迎界面?
当然。在MonoDevelop preferences中,在“Visual Style”去中,取消选中“Show welcome page on startup”(Tools->Preferences->Visual Style->Welcome Page)。
OSX 10.6.4系统中Geforce 7300GT显卡问题
因OSX10.6.4系统使用Geforce 7300显卡不能正确显示材质,延迟渲染不可用。这是因为显卡驱动有bug。
在Windows 64位系统中,当脚本抛出一个NllReferentException(引用值为空异常)Unity崩溃。
该问题请参照Windows Hotfix #976038解决
图形图像问题
低帧数和/或显示问题
如果显卡驱动老旧可能会发生。确保已经从显卡厂商获得最新的官方驱动
阴影
完全看不到阴影
阴影是Unity Pro版本拥有的特性,如非Unity Pro版本就无法看到阴影。当然一些简单的阴影还是可以获得,例如使用Projector。
阴影需要一定的显卡硬件支持,请参看Shadow以获取详细信息。
检测在Quality 设置(Edit->Project Setting->Quality,注意编辑器和发布出来的版本设置可能不相同)中是否完全禁止了shadows。
目前在Android和iOS移动平台中尚未支持阴影。
一些物体不产生也不显示阴影
Object的Renderer组件必须选中Receive Shadows才显示阴影(其他物体的影子),选中Cast Shadow才能产生在产生阴影(投射在其他物体上),这两个选项默认都是选中的。
只有不透明物体产生和显示阴影。也就意味着使用内置的Transparent和Particle shader将不能产生阴影。在多数情况下可以使用Transparent Cutout shader来处理栅栏,植被的。如果使用非内置的Shader,必须是pixel-lit(象素发光)和几何渲染队列。使用顶点发光shader的物体不接受但是可以产生影子。
只有象素光可以产生影子。无论场景中有多少灯光,要确保确定灯光产生影子,请设置它为强制象素渲染模式(参看Light参考页)。
iOS
iOS设备疑难集锦
iOS上有经常会出现程序在Unity编辑器中工作正常但在设备上无法工作甚至不能启动,这个问题通常跟代码或内容质量有关.本节展示了最常见的几种情况.
Xcode 3.2.x编译失败并提示"libiPhone-lib.a, missing required architecture i386 in file Undefined symbols: "Register_UnityEngine_Input_GetMouseButtonDown()", referenced from: RegisterAllStrippedInternalCalls() in RegisterMonoModules.o
这中编译错误通常是在Player Settings中选择了non-simulator SDK(非模拟器SDK),在Xcode中选择了simulator SDK(模拟器SDK)。Unity和Xcode选择SDK应该保持一致。
Xcode4.x编译失败并提示"No architectures to compile for (ARCHS=armv6, VALID_ARCHS=i386)."
目前Unity对Xcode4.x支持有限,并且在编译最终程序时需要进行一些人工设置。Build&Run命令会自动打开Xcode工程但不会设置好编译目标平台和设备。如果要在设备上测试需要选择“Unity-iPhone”平台并将iOS设备连接到Mac机(也即开发机)。如果要在模拟器里测试需要选择正确的SDK(如前所述),应该选择“Unity-iPhone-simulator”平台,并使用模拟器设备。
程序停止反应,Xcode状态栏提示“interrupted”(中断)
这种情况可能有多种原因造成,典型问题包括:
脚本错误,如使用未初始化的变量等。
使用第三方Thumb编译的本地库文件。这些库在iOS SDK连接器中有已知问题并可能产生随机崩溃。
在托管代码剥离(managed code stripping )的情况下使用反射。
本地插件接口出错——托管代码方法和本地代码函数签名不匹配(参数类型不对)。
XCode Debugger 控制台(XCode 菜单 Run-> Console,也即运行->控制台)输出信息通常有助于诊断这些问题。
Xcode 控制台提示"Program received signal: “SIGBUS” 或者 EXC_BAD_ACCESS 错误.
这种错误通常是程序收到一个引用为空的错误.通常有两种方法用以寻找错误发生的原因:
托管堆跟踪:
从3.4版本开始,Unity包含了对空引用的处理(software-based,我认为翻译出来没有意义,愚见)。AOT编译器(AOT,Ahead-of-time,相对JIT而言)在一个对象的方法或者变量被访问时拥有快速检测是否为空引用的能力。这个特性影响了脚本的性能,这就为什么它只在开发版中被打开的(在basic授权中——unity的basic授权,用户可以在Build Setting对话框中打开,但iOS pro授权中用户需要另外选中“script debugging”选项)。如果一切顺利,在.NET中产生的错误就再不会产生EXC_BAD_ACCESS错误了,而是在Xcode控制台中显示.NET异常信息(或者代码在catch代码段处理)。典型的输出可能是:
Unhandled Exception: System.NullReferenceException: A null value was found where an object instance was required.(没有处理的异常:System.NullReferenceException——错误名字,在需要一个实例的地方出现了一个空值)。
at DayController+$handleTimeOfDay$121+$.MoveNext () [0x0035a] in DayController.js:122
这提示错误发生在DayController 类的handleTimeOfDay方法中,在一个coroutine调用中。
如果有源代码,就会提示出错误所在的行号(例如:“DayController.js:122 ”)。问题语句可能如下:
Instantiate(_imgwww.assetBundle.mainAsset);
在脚本访问一个资源包而没有首先确定它被已正确下载时上述语句就可能出现。
本地堆跟踪:
在诊断错误时,本地堆跟踪是很有利的工具,也需要一些技术。同时在一些本地错误(例如硬件内存访问)发生时就无法继续.要进行本地堆跟踪需要在XCode调试控制台中输入"thread apply all bt"。要认真大的审查显示的堆跟踪信息,它们可能包括了错误来源信息。如可看到如下信息
...
Thread 1 (thread 11523):
#0 0x006267d0 in OptionsMenu_Start ()
#1 0x002e4160 in wrapper_runtime_invoke_object_runtime_invoke_void__this___object_intptr_intptr_intptr ()
#2 0x00a1dd64 in mono_jit_runtime_invoke (method=0x18b63bc, obj=0x5d10cb0, params=0x0, exc=0x2fffdd34) at /Users/mantasp/work/unity/unity-mono/External/Mono/mono/mono/mini/mini.c:4487
#3 0x0088481c in MonoBehaviour::InvokeMethodOrCoroutineChecked ()
...
首先在跟踪信息中看到"Thread 1",这是主线程。接下来的信息指出了错误发生的位置。在本例中,跟踪显示空引用错误发生在"OptionMenu"脚本的Start函数中,在初始化是赋予了错误的值。在一些情况下只有少量的跟踪信息
Thead 1(thread 11523)
# 0x0062564c in start()
这是因为在程序编译Release版本是调试符号被移除了。执行以下步骤即可以显示全部调试信息。
在Xcode 项目中选择Debug 设置(也即设置项目为debug模式)
清理所有对象
重新编译运行
再次得到跟踪信息即可
Xcoce控制台显示“警告->程序收到内存警告”,然后程序很快崩溃了。
程序有时会收到类似于“程序收到信号:xxx”,这种警告信息多半是非致命的,通常也意味着iOS可用内存较少要求程序释放一些内存。典型情况下,后台运行的程序像Mail等会释放一些内存,程序得以继续运行。但是如果程序继续占有内存或请求更多。系统就会开始结束一些程序,程序本身也可能被结束(这些拗口)。Apple没有明确的文档来说使用多少内存是安全的,以经验来说使用25MB(对三代产品来说80M)通常没有任何内存使用问题。使用40M内存在1~2代设备上会遇到内存使用个问题并可能导致设备重启。需要主要考虑的是程序使用了多少内存。程序对内存的使用主要有以下3点:
1、代码,系统需要加载并驻留程序代码在内存中
2、本地堆,引擎使用以保存状态,资源等
3、托管堆,Mono运行时用来管理C#或Javascript对象
可以使用2个Xcode命令工具来跟踪内存使用信息:Activity Monitor和Object Allocation。可以通过 Run > Start with Performance Tool > Activity Monitor and Run > Start with Performance Tool > Object Allocations二者。第一个工具显示了所有进程的状态包括实时内存,可以看做程序使用的总内存。
Android
Android开发问题集锦
Unity无法将程序安装到设备上
1.确认计算机可以查看到,并且能和设备交互。更多细节请参看Publishing Builds。
2.查看Unity console窗口中的错误信息,它通常有助于帮助诊断问题
例如在编译中出现错误提示“Unable to install APK, protocol failure”(无法安装APK,协议失败),这意味着设备连接到USB供电不足,例如键盘或其他周边设备的USB。请将其直接连接到电脑USB端口。
在运行后立刻崩溃
1.确认没有调用设备不支持的本地行为
2.试着移除本地插件
3.试着禁用stripping(build setting->Player Setting中设置string level为disable)
4.使用adb logcat(Android SDK工具)获取设备崩溃报告
DEX编译失败
这种错误会产生类似以下信息:
Building DEX Failed!
G:\Unity\JavaPluginSample\Temp/StagingArea> java -Xmx1024M
-Djava.ext.dirs="G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/"
-jar "G:/AndroidSDK/android-sdk_r09-windows\platform-tools/lib/dx.jar"
--dex --verbose --output=bin/classes.dex bin/classes.jar plugins
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.
通常是因为计算机上安装了错误的java版本。升级java版本通常可以解决这一问题
播放视频时很快崩溃
确认设备(原文是phone,愚见)Settings->Developer Options->Don't keep activities(设置->开发者选项->不保持活动状态)没有被选中。视频播放有自己的活动状态,所以在视频播放器激活后程序就会被摧毁。
按下休眠键程序会退出
改变AndroidManifest.xml(程序编译时会自动生成)中
示例activity标签如下:
android:label="@string/app_name"
android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen">