❶ unity 导出安卓工程怎么编译成apk
1.android端代码可以在Eclipse中开发(AndroidStudio没有试,应该也可以)
2.Unity3D端代码要在Unity中开发
3.Android和Unity3D端,两边都需要加入一些代码从而可以使之关联交互。
4.将Android端代码编译成jar文件以插件形式放入到Unity端中
5.在Unity中将整个项目Build成apk文件,然后安装到手机或模拟器里运行
本文主要讲解1,2,3。对于4,5建议大家去看雨松MOMO的Unity博客的第17篇和第18篇。
UnityPlay:
在编写Android端和Unity3d端代码前,有必要先了解一下可以使两部分交互的类UnityPlay。
个人理解UnityPlay是个Unity提供给外部交互的一个接口类。
为什么是“个人理解”?这我不得不爆粗口了,TMD官网根本就没有相关的API和文档(如果大家有谁找到一定给我来一份,就当我骂自己了)。
在关联Android时,想拿到UnityPlay以及相关类的jar包可以从下面的地址找到:Unity安装路径\Editor\Data\PlaybackEngines\androidplayer\bin在bin文件夹下有一个classes.jar的jar文件,它就是我们想要的。
而在bin同目录下有一个src文件,点击到最后有3个类,分别是UnityPlayerActivity.java,UnityPlayerProxyActivity.java,UnityPlayerNativeActivity.java。前两个打开个后只有一行代码,说的是UnityPlayerActivity和UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity。而打开UnityPlayerNativeActivity中居然有代码,而且我估计这应该是UnityPlayerNativeActivity的源码。
由于关于UnityPlay的资料我只找到这么一个,所以我把UnityPlayerNativeActivity中的代码都贴出来,如果我注解有不对的地方希望大家指正。
/**
* UnityPlayerActivity,UnityPlayerProxyActivity都继承自UnityPlayerNativeActivity
* 而UnityPlayerNativeActivity继承自NativeActivity
* 在该类里定义了一些和ANDROID生命周期相同的回调方法,留给自定义的Activity子类重写。
*/
public class UnityPlayerNativeActivity extends NativeActivity
{
//UnityPlayer的引用,并且我们不能改变这个引用变量的名字,它被native code所引用
protected UnityPlayer mUnityPlayer;
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_565);
// 创建一个UnityPlayer对象,并赋值给全局的引用变量
mUnityPlayer = new UnityPlayer(this);
//为UnityPlayer设置一些参数
if (mUnityPlayer.getSettings ().getBoolean ("hide_status_bar", true))
getWindow ().setFlags (WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
int glesMode = mUnityPlayer.getSettings().getInt("gles_mode", 1);
boolean trueColor8888 = false;
// UnityPlayer.init()方法需要在将view附加到layout之前调用。它将会调用native code
mUnityPlayer.init(glesMode, trueColor8888);
// 从UnityPlayer中获取到Unity的View视图
View playerView = mUnityPlayer.getView();
// 将Unity视图加载到根视图上
setContentView(playerView);
// 使Unity视图获取焦点
playerView.requestFocus();
}
protected void onDestroy ()
{
// 当Activity结束的时候调用UnityPlayer.quit()方法,它会卸载之前调用的native code
mUnityPlayer.quit();
super.onDestroy();
}
// 下面几个方法都是ANDROID相关回调方法,确保在ANDROID执行相应方法时UnityPlayer也需调用相应方法
protected void onPause()
{
super.onPause();
mUnityPlayer.pause();
}
protected void onResume()
{
super.onResume();
mUnityPlayer.resume();
}
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
mUnityPlayer.configurationChanged(newConfig);
}
public void onWindowFocusChanged(boolean hasFocus)
{
super.onWindowFocusChanged(hasFocus);
mUnityPlayer.windowFocusChanged(hasFocus);
}
public boolean dispatchKeyEvent(KeyEvent event)
{
if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
return mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
return super.dispatchKeyEvent(event);
}
}
❷ 在Unity里面怎么运行代码
摘要 在Game视图的上侧有三个按钮,分别是“运行”按钮、“暂停”按钮,和“逐帧”按钮。
❸ 如何用unity3d编写javascript
Unity中的JS,也称UnityScript,和基于浏览器的JS有比较大的区别,因为UnityScript是基于Mono的.net 的IL语言规范,CLR运行环境(Mono虚拟机)上设计的语言。
0.基本概念:
Unity3d中的脚本可以与游戏对象链接,变量数值的修改以及实时预览脚本修改后的游戏效果,节省了很多脚本调整和调试的时间,提高了开发效率。
简单的项目和Unity中的大量例子和脚本资源包都是用JS。商业项目基本都用C#,因为C#和C/C++交互方便,丰富的数据结构和面向对象的架构利于大型程序的编写,很多强大的第三方插件是用C#开发的,方便工作流程。
编译过程:
UnityScript运行环境使用Mono 的.NET Framework。实际上,UnityScript是用Boo实现的,Boo是运行在Mono虚拟机上的一种语言,并且编译成本机代码。JavasScript很多典型的运行环境如String和Math库由Mono提供。你也就知道了为什么UnityScript中方法名要大写了,因为要与Mono中相同。
Unity中的脚本和传统的解释型(JIT解释)语言不同,都是需要经过编译的,因此速度都一样快。
这三种语言的代码最后都会被编译执行,而且脚本可以互相访问。
库的调用:
Unity的脚本基于Mono的.net平台上运行,脚本都可以使用.net库,为xml,数据库,正则表达式提供了良好的解决方案。
Unity中js想调用mono的.net库,直接import即可。
import System;
import System.IO;
否则,你带指定完整的命名空间来调用函数,如System.IO.File.Open(),而不是File.Open()。
1.基本类型和语句:
1)数据类型:
数值类型:char,byte,sbyte;short, ushort, int, uint, long, ulong; float,double; decimal.
布尔值:boolean
字符串:String,[index]符号
字符串[0]是字符串取下标为0的字符。
var s: String = "Whatever_it_may_be";
s =s.Replace("_"[0], " "[0]); // replace all the underscoreswith spaces
2)变量声明:
变量必须先声明[必须](编译缘故,且声明类型有利于减少太多常量,避免内存泄露发生),可以定义类型[可选]:
var playerName:String;
函数的参数也要声明类型:
function Test( playerName:String, baseInfo:Object )
{
}
如果声明时候定义或赋值了类型,那么不能再改变类型,除非声明时候不定义类型。
var a= "test";
a =5;// 报错
var a;
a ="test";
a =5;//正确
变量前面可以加public,protected, private来修饰;不写默认是public的,public的变量可以在Inspector视图中查看和编辑。
3)数组:
内建自定义数组(快功能简单):
var values : int[] = {1,2,3};
转换到Array数组(需要对数组处理),var arr = new Array(values);
Array对象数组(慢动态增长排序合并功能):
var arr = new Array(); arr.Push("good");
转换到内建数组(需要比较高的性能时候),var bArray : int[] = arr.ToBuiltin(int);
4)链表和泛型:
UnityScript可以使用泛型,所以当用到动态大小的数组时,最好用List来替代Array。基本上就没有什么理由要用到Array了,List更快并且功能更多。如果你需要混合类型的数组,你可以用Object List。UnityScript中泛型的语法与C#中接近,除了要加一个额外的“.”符号在“<>”之前。如C#中的"varmyList = new List<int>();"在UnityScript中对应的写法为:"var myList = new List.<int>();"。
5)运算符和表达式:
和C一样。
6)语句:
每行必须写分号; 比C多了for in 用于遍历对象元素,for(var i:int = 0; i < 10; i++)。
switch可以使用String变量。
2.函数
声明规则:
function函数名(参数1:参数类型, 参数2:参数类型...):返回值类型
{
}
unityScript中的函数可以视为Function类型对象,可以像变量一样进行赋值比较等操作。
不能写匿名函数。
Math需要用Mathf。
3.类(DOM js中没有类):
在Unity里,一个js文件就是一个类,unity引擎会为js文件自动生成一个类。
对于UnityScript脚本,Unity编译该文件时会自动的为脚本添加一个与脚本文件名相同的类,并自动地继承于MonoBehaviour。但对于C#或Boo,则需要在脚本中显式的写出类名和继承关系。要创建不继承自MonoBehaviour的类,用C#语言,或者从外部添加js脚本资源(就可以自己直接new对象出来了)。
//SayHello.js
#pragma strict // 严格类型检测,尽早生成错误,禁用动态类型,强制用静态类型(强类型)
function sayHello()
{
}
等价于C#中:
#pragma strict
public class SayHello extends MonoBehaviour
{
function sayHello()
{
}
}
但是,你可以在同一个文件中声明多个类,尤其是当你需要使用一些辅助工具类时非常有用,一般这种辅助类没有继承自MonoBehaviour。
如
class ButtonState {
var currentState : int;
var offset : Vector2;
}
如果你在一个文件中声明了MonoBehaviour的子类,但类名与文件名不匹配的话,即使是大小写不一致,你也会碰到麻烦。
一定要理解,当你在js文件中编写行为脚本是,你实际上在编写一个类:
a) 类及其对象:文件名就是类名,如果文件名是foo.js,你就可以在其他地方以var x = new foo()的格式进行调用;
b)类的方法和预定义方法:有一些特定的方法是实现系统预先定义的一些事件处理器,如Start、FixedUpdate等。任何事件中,声明的一个函数就是这个文件所代表的类的一个方法。
c) 类的属性:文件中在函数定义之外编写的代码都在该类的范围之内执行,声明的变量也是该类的成员变量。类中的静态函数、变量本质上是类的方法与属性。
实例:
/*whenyou drag the behavior onto a gameobject, these values will be visible andeditable
*/
public name : String;
/*otherscripts which have a reference to this object (e.g. if they're attached to thesame object) can see public functions
*/
publicage : int;
/*privatemembers are NOT visible to other scripts, even if they have a reference to thisobject
*/
private favoriteColor : Color;
/*youcan assign a value to bestFriend by dragging a gameObject with an attached of the foo behavior to this property. This will give you access to bestFriend'spublic methods and members
*/
public bestFriend : foo;
/*this function will be called every frame by Unity, so it's actually an eventhandler
*/
function Update(){
/*transform is a property inherited from thegameObject the behavior is attached to*/
var t = transform;
}
function Bar(){
// this is just a function, if you don't callit yourself, it will never do anything
}
4.继承
Unity里需要extends关键字:
class MyHello extends Hello
{
}
DOM js中用prototype里的bind()方法。
Unityjs里面还提供了虚拟函数。
类的继承也是不同的。在JavaScript和C#中,方法是隐型并且不可重载,除非方法声明中添加虚拟关键字。不同的是C#只重载那些包含重载关键字override的方法。而JavaScript不需要关键词,只要重载类方法就可以覆盖,其它的都可继承得到。
//Foo.js
var foo = "hello, world";
function doEet () {
// does nothing, intended to be overridden
}
将会生成:
//Foo.js
import UnityEngine;
classFoo extends MonoBehaviour {
public var foo = "hello, world";
public function doEet () {
// does nothing, intended to be overridden
}
}
子类写法:
//PrintingFoo.js
class PrintingFoo extends Foo {
function doEet() {
print( foo );
}
}
创建虚函数:
classFoo
{
virtual function DoSomething ()
{
Debug.Log("from baseclass");
}
}
//SubFoo.js
class SubFoo extends Foo
{
virtual function DoSomething()
{
Debug.Log("from subclass");
}
}
//Elsewhere
varfoo : Foo = new SubFoo();
foo.DoSomething();//printsfrom sub class
如果你要调用父类的方法,用关键字super。示例如下:
class SubFoo extends Foo
{
virtual function DoSomething()
{
super.DoSomething();// 不是虚函数,应该不需要super修饰就可以直接调用。
Debug.Log("from sub class");
}
}
//Elsewhere
varfoo : Foo = new SubFoo();
foo.DoSomething();//prints"from base class" and "from sub class"
类间通信:Use-a方式(关联关系)比继承耦合度底得多,易于修改维护
/*Foo.js */
varbar : Bar;
function Start(){
bar = gameObject.GetComponent(Bar);
}
function doEet(){
// do my own thing
if( bar ){
bar.doEet();
}
}
/*Bar.js */
function doEet(){
// do something special
}
5.对象
Unity中不一定可以用new 创建对象(普通类可以,特殊类不行,各种脚本都一样)。特殊类:用编辑器工程视图右键或者组件Create js 或者C#的类都是继承自MonoBehaviour类,对这种类型的类不能new出来一个对象,原因是Unity会为这种类自动创建对象,并调用被重载的方法。
使得用Unity非常有趣的一件事是,它的类采用了非常自由的mixin策略。通常你可以非常快速简单的查到你所需要的类。最通用的一个例子是Transform类,对于你正在处理的一个对象,所有被附加到该对象的相关联的类,都可以简单快速的获取它的属性和方法。
比如,典型的动作就是你会访问名叫"transform"的变量,它代表与该对象关联的Transform类的实例。如果你需要相关的位置坐标,就访问transform.position(一个 Vector3对象);如果你需要它的GameObject,就访问transform.gameObject;如果你需要它的渲染器,就访问transform.renderer。等等。一般如果你一个对象的主要属性,你就可以快速获取该对象所有其他的属性。
6.js和C#单向通信,不能双向通信,因为编译问题
js访问C#脚本组件:
//createa variable to access the C# script
private var csScript : CSharp1;
function Awake()
{
//Get the CSharp Script
csScript =this.GetComponent("CSharp1");//Don't forget to place the 'CSharp1'file inside the 'Standard Assets' folder
}
//rendertext and other GUI elements to the screen
function OnGUI()
{
//render the CSharp1 'message' variable
GUI.Label(new Rect(10,30,500,20),csScript.message);
}
C#访问js脚本组件:
using UnityEngine;
using System.Collections;
public class CSharp2 : MonoBehaviour
{
//create a variable to access the JavaScriptscript
private JS1 jsScript;
void Awake()
{
//Get the JavaScript component
jsScript = this.GetComponent<JS1>();//Don'tforget to place the 'JS1' file inside the 'Standard Assets' folder
}
//render text and other GUI elements to thescreen
void OnGUI()
{
//render the JS1 'message' variable
GUI.Label(newRect(10,10,300,20),jsScript.message);
}
}
7.使用第三方库:
第三方.NET库如XML-RPC可以以新建资源Asset的方式引入。
8.调试
可以用print函数,Log()函数或者Debug.Log(),想设置断点,用Debug.Break()函数。
print() 函数将会生成消息,并输出到状态栏及控制台中,但仅限MonoBehavioour类范围内。
更好的办法是使用Debug.Log("insert messagehere");,该方法到处都可使用。还可用Debug.LogWarning 和 Debug.LogError生成警告和错误消息。
Debug.Break(); 可以将游戏暂停在一个精确的点。当一种特定的情条件发生时,如果你想检查对象的状态的时候,这个特性非常有用。
开发环境运行项目时,编辑界面也是完全实时更新的,你可以查看对象实例的内部状态。
❹ Unity打包好的游戏可以反编译得到源码和资源吗
在Unity3D中,代码会编译到Assembly-CSharp.dll。基于以上两点,代码的保护有以下两种:
第一种是对代码进行混淆,诸如混淆软件CodeGuard、CryptoObfuscator、de4dot
第二种是对Assembly-CSharp.dll进行加密后,重新对mono进行编译。
Virbox Protector直接进行加壳后,无需手动编译mono,能防止反编译。
❺ unity 游戏 运行时 怎么娼代码
C#代码的编译与执行
CLR:[Common Language Runtime] 公共语言运行时
Metadata:元数据。
IL:[Intermediate Language] .Net 框架中间语言
CLI:Common Language Interface 公共语言基础结构
2
什么是L#?
L# (CLRSharp)是一个在C#层实现的用IL做脚本的解释器
3
CLRSharp 代码框架
4
当L#遇上多线程
必须在新的线程中初始化一个ThreadContext然后就可以通过它访问L#代码了
5
L#实现方式导致的问题:
L#的类型不是真正的C#类型
L#代码中的类型不能继承于C#代码类型
TryGetValue 之类的 out 关键字的代码就不
❻ unity使用什么编译器好
打开软件后如下图:直接写Lua代码,并且可以直接运行,关键字也有高亮显示。个人认为:适合刚开始学习Lua语法的时候使用,不适合后期开发时使用,
❼ unity3d中写代码需要用c#自己的编译器么
都可以,unity只是解析代码文件而已,和编译器没有关系,比如说用visual studio结合其插件可以快速进行开发,用unity自带的编译器可以调试等等
❽ 如何使用dnSpy反编译unity代码并修改
unity项目打包后的代码都在Assembly-CSharp.dll里,直接使用dnSpy打开即可修改,并且编译
❾ unity3D里面的脚本编写是什么样的原理运行起来是怎么样的呢
非常好的问题,这个涉及到引擎的脚本系统,我自己都没有完全弄清楚。你只需要知道unity脚本是基于组件的,引擎负责管理组件对象的生命周期,因此你在unity脚本中看到的Awake,Start,Update等方法都会由引擎所调用。
而脚本虽然是C#写的,但是会被mono编译成IL,然后目前unity可以选择IL2CPP,也就是说最终代码被编译为C++。这样的好处是mono的runtime是有缺点的,而且JIT本身是影响性能的。而且还有一个很重要的原因是unity本身是C++写的,直接编译成C++比较方便的调用引擎内部的函数。
❿ 如何编写Unity原生插件
unity可以导入其它语言编写(和编译)的代码,称为原生插件(Native Plugins)。今天为大家分享如何创建Unity原生插件。
Unity中的托管和非托管插件
连接不同的代码并非Unity首创的。若你是Windows用户,可能听说过DLL,动态链接库的缩写。与单机应用类似,它们是编译过的软件。不同的是,它们不能直接执行,因为它们是被专门设计为供其它应用使用的。
Unity支持两种插件:托管(Managed)和非托管(Unmanaged)的。前者是用C#编写并编译为通用中间语言(CIL)的字节码语言。托管插件与C#脚本一样强大,且带有编译过的源码。非托管(或原生)插件,是使用其它语言编写的软件,典型是C++。它们在功能上几乎没什么限制,而且因为都被编译为机器码所以通常比传统的脚本要快。
第一步:新建C++项目
本例中,我用的是Visual Studio 2015;你可以选择任意IDE编译C++代码。首先创建一个非托管C++库也就是新建项目。打开Visual Studio,依次点击File | New Project ,选择Visual C++ | Win32 Console Application。
在给项目命名后(本例中为TestDLL),确保将应用类型(Application type)设为DLL,附加选项(Additional options)下选择空项目(Empty project)。
至此,Visual C++解决方案已经准备好,我们可以开始编写代码了。
第二步:编写库
C++代码通常分为两个文件。函数定义(头文件)和函数实现(实现文件)。实现文件为.cpp文件,放在ResourceFiles目录下,头文件为同名.h放在HeaderFiles目录下。本例中我们创建一个头文件和一个实现文件;实现文件将包含所有要保存到DLL的功能。可以在相应的文件夹上单击右键新建文件,然后依次选择Add(添加)>NewItem(新选项)。
实现部分:TestDLLSort.cpp
开始编码,实现给数组排序。
[AppleScript] 纯文本查看 复制代码?
#include "TestDLLSort.h" #include extern "C" { void TestSort(int a[], int length) { std::sort(a, a+length); } }
5~7行使用了algorithm 库里的数组排序函数std:sort。如果熟悉C++11就会知道。只增加了extern "C"块,必须用它将TestSort的引用导出到DLL。
头文件:TestDLLSort.h
实现文件中的定义必须与头文件保持完全一致。它必须包含TestSort原型也就是函数签名。
[AppleScript] 纯文本查看 复制代码?
123456 #define TESTDLLSORT_API __declspec(dllexport) extern "C" { TESTDLLSORT_API void TestSort(int a[], int length); }
其余部分是创建DLL必须的代码。TESTDLLSORT_API可以是任意名字,用来标记所有的导出函数。在更复杂软件中,TESTDLLSORT_API应该根据需要绑定到 __declspec(dllimport) 上。但是在本例中,没有必要。
第三步:编译
最后一步是在Visual Studio中编译我们的DLL。请确保发布平台设置正确(32位或64位)。然后依次选择Build>Build Solution。
在屏幕下方的控制台上会看到输出日志如下:
[AppleScript] 纯文本查看 复制代码?
1>------ Rebuild All started: Project: TestDLL, Configuration: Release x64 ------ 1> TestDLLSort.cpp 1> Creating library C:\Users\Alan Zucconi\Documents\Visual Studio 2015\Projects\TestDLL\x64\Release\TestDLL.lib and object C:\Users\Alan Zucconi\Documents\Visual Studio 2015\Projects\TestDLL\x64\Release\TestDLL.exp 1> Generating code 1> All 30 functions were compiled because no usable IPDB/IOBJ from previous compilation was found. 1> Finished generating code 1> TestDLL.vcxproj -> C:\Users\Alan Zucconi\Documents\Visual Studio 2015\Projects\TestDLL\x64\Release\TestDLL.dll ========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
若发现有警告如:warning C4273: inconsistent dlllinkage,这可能表示编译器不确定使用__declspec(dllimport) 还是 __declspec(dllexport)。若想为Unity创建原生插件,就使用后者。
第四步:导入Unity
根据上面的编译日志,在工程文件中找到编译好的DLL。本例中,它在文件夹x64\Release中。我们只要这个文件。在Unity中使用它的第一步是把它拷贝到Plugins文件夹下。
原生插件通常与操作系统或平台相关。可以查看右侧的检视面板确保每个DLL被包含到正确的平台。
第五步:在Unity中使用
导入后,使用DLL就相对简单了。第一步是使用DLLImport定义入口(EntryPoint)。你需要指定DLL名和函数名。会提供别名让它可以像其它函数一样被调用。
[AppleScript] 纯文本查看 复制代码?
using UnityEngine; using System.Runtime.InteropServices; public class TestDLL : MonoBehaviour { // The imported function [DllImport("TestDLL", EntryPoint = "TestSort")] public static extern void TestSort(int [] a, int length); public int[] a; void Start() { TestSort(a, a.Length); } }
入口的字符串必须与C++库中的名字一样。但你可以使用如下方法调用函数;以后C#就这样调用它。
你应该注意到Unity在编辑器中不能检测非托管DLL;必须运行游戏来检测是否成功连接。对于托管的DLL,则可以静态检测。