unity 怎么往生成的cs工程里面添加unityassetsexplorer

「Unity」与iOS、Android平台的整合:1、导出的Xcode工程
时间: 00:08:12
&&&& 阅读:936
&&&& 评论:
&&&& 收藏:0
标签:本文属于之一。
本文主要讲解Unity导出的Xcode工程的目录结构。
我所用软件的版本:
  Unity 5.3.5f1
  Xcode 7.3
第一步,创建一个新的工程 Build_to_iOS_Android
第二步,创建一个新文件 CSharpToCPP.cs
using UnityE
public class CSharpToCPP
public void Func(int num)
if (num & 1)
Debug.Log("Log:Time" + num);
第三步,创建Plugins/iOS/iOS_EmptyMM.mm、StreamingAssets/ALL_EmptyTxt.txt
第四步,保存一下场景,如下图
第五步,选择iOS平台,Build导出Xcode工程
第六步,打开所导出的Xcode工程
1、程序入口
任何程序都有一个入口,Unity导出的Xcode工程中也不例外,通过下图我们可以看到,在应用的入口中创建了UnityAppController的对象。
&通过下图我们可以看到,UnityAppController是继承了UIApplicationDelegate,至于它是什么我就不赘述了,大家可以看一下这一篇文章:
&下图为一个UIApplication的声明周期,我们可以看到系统事件存在着非常有用的监听,在UnityAppController.mm里面我们也可以看到对应的函数,这意味着在Unity中一样可以收到这些事件,以后我们将继承UnityAppController,并重写这些监听。
2、C# -& C++:
在Unity中,我们用的是C#、JS进行编程(我是C#党),但是导出Xcode工程后,这些代码都转换成了C++代码。
在Player Settings里面我们可以看到脚本的运行模式有两种,一种是IL2CPP,另一种是Mono2x(以后肯定会被CPP替代,我就不讲了),通常我们会选择IL2CPP,因为效率高。
选择IL2CPP我们的逻辑代码将全部转换为C++代码,下图为CSharpToCPP.cs转换成的C++代码。
以下代码是上图中的翻译代码,对比我们一开始写的CSharpToCPP.cs里逻辑,应该能够看懂其中的逻辑。
// System.Void CSharpToCPP::Func(System.Int32)
extern Il2CppClass* Int32_t_il2cpp_TypeInfo_
extern Il2CppClass* String_t_il2cpp_TypeInfo_
extern Il2CppClass* Debug_t_il2cpp_TypeInfo_
extern Il2CppCodeGenString* _stringLiteral;
extern const uint32_t CSharpToCPP_Func_m_MetadataUsageId;
extern "C"
void CSharpToCPP_Func_m (CSharpToCPP_t * __this, int32_t ___num0, const MethodInfo* method)
static bool s_Il2CppMethodI
if (!s_Il2CppMethodIntialized)
il2cpp_codegen_initialize_method (CSharpToCPP_Func_m_MetadataUsageId);
s_Il2CppMethodIntialized = true;
int32_t L_0 = ___num0;
if ((((int32_t)L_0) &= ((int32_t)1)))
goto IL_0008;
int32_t L_1 = ___num0;
int32_t L_2 = L_1;
Il2CppObject * L_3 = Box(Int32_t_il2cpp_TypeInfo_var, &L_2);
IL2CPP_RUNTIME_CLASS_INIT(String_t_il2cpp_TypeInfo_var);
String_t* L_4 = String_Concat_m(NULL /*static, unused*/, _stringLiteral, L_3, /*hidden argument*/NULL);
IL2CPP_RUNTIME_CLASS_INIT(Debug_t_il2cpp_TypeInfo_var);
Debug_Log_m(NULL /*static, unused*/, L_4, /*hidden argument*/NULL);
由于C++代码是机器自动生成的,可读性催人尿下,所以最好参照自己的C#代码进行阅读。
由于Unity -& Xcode&-& 设备,编译时间太过漫长了,所以在问题排查时,我会尝试注释或简单修改C++代码,实现问题定位等。
3、资源&StreamingAssets -& Data/Raw
Unity导出Xcode工程后,原工程中的各种资源都被压缩、打包、加密后存放在Data文件夹中,这一点和Android是一致的,网上也有很多资源解密的方法,大家有需要可以自行搜索。
我们重点说一下Unity中的StreamingAssets文件夹,关于这个文件的作用,大家可以看一下这篇文章:
通过下图我们可以看到,StreamingAssets文件夹中的ALL_EmptyTxt.txt文件被完整地拷贝到Data/Raw文件夹中,实际上不光是文件,文件夹也会原封不动地拷入该文件夹。
至于这有什么用,比如说,配置文件放在这里,上手机调试的话可以在Xcode工程中直接修改配置,而不需要到Unity里重新导出Xcode工程。
4、Plugins/iOS -&&Library/Plugins/iOS
Plugins/iOS文件夹中通常会放一些*.a、*.h、*.m文件,这些文件将拷贝至在Xcode工程的Library/Plugins/iOS文件夹中,在Xcode编译时也将被编译。
实际操作过程中,我会把自己为iOS写的OC、C、C++代码、SDK提供的.a文件放到里面,以避免每次编译后都要在Xcode工程里重新导入。
在Unity的Player Settings是中,我们可以添加相应的Icon
这些Icon图片将被重新压缩、命名最后放入下图中的位置。
由于Icon在Unity内将占据一定的内存,所以一般我会在Xcode中替换Icon文件,效果一致且不占用Unity的内存。
Unity在iOS有很多种闪屏方案,具体方案效果大家可以自行搜索~
下图为常见的单图片闪屏导出位置,与Icon一样,我一般在这边替换,哦对,不要忘了取消ShowUnitySplashScreen的勾选。
7、Framework
在Unity的Plugins/iOS/中文件可以为自身简单勾选配置一些Framework依赖,见下图。
这些依赖将自动添加到Xcode工程中,我们可以在Frameworks文件夹检查是否添加。&
8、Player Settings -& 设置
在Unity的Player Settings中存在着大量的配置,这些配置将反应到Xcode工程中,在下图中圈出了部分,这些东西并不复杂,我也就不赘述了。
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!使用Unity创建2D游戏
本文主要译自。
简介在这篇文章中,将讲解怎样使用C#和Unity创建移动2D游戏。将使用Unity杜比音频插件展示游戏音频体验。游戏很简单,到达另外一边,躲避敌人,收集金币。
在这篇文章中,将学习Unity游戏开发的以下方面:
在Unity中设置2D项目
创建Prefabs(预设)
移动和动作的按钮
运用物理碰撞
使用sprite sheet(精灵表)
集成杜比音频API
步骤和说明以下一共34个步骤。
我使用的Unity版本是:4.3.4f1
1. 创建新的Unity项目打开Unity,在File菜单中选择New Project,打开新项目对话框:
设置项目保存的路径
设置为2D项目
2. 构建设置创建项目后,会进入Unity用户界面。
在File菜单中选择Build Settings,然后选择Android作为目标平台。
3. 设备当开发2D游戏的时候,第一件事情是选择平台,之后就是选择艺术素材的尺寸。因为Android是开放的平台,因此市场上,有各种设备,它们有各不相同的屏幕分辨率和像素密度。比如以下是比较常见的:
Samsung Galaxy SIII: 720px x 1280px, 306 ppi
Asus Nexus 7 Tablet: 800px x 1280px, 216 ppi
Motorola Droid X: 854px x 480px, 228 ppi
虽然本文使用的是Android平台,但使用相同代码,可构建到Unity支持的其他目标平台上。
4. 导出图为了适应使用的设备,你可能需要将艺术素材转换为推荐的尺寸和像素密度。这件事情可以用你喜欢的图片编辑器完成。
我使用Mac OSX,预览就有这个功能,菜单项在这里:
然后在这个对话框里设置转换的参数:
5. Unity用户界面在开始之前,还需要调整一下Unity界面。
设置场景为2D(默认是3D的):
另外,可在Game控制面板里设置分辨率:
6. 游戏界面
游戏界面和直白。上面截图,可让你了解到艺术粗才最终在游戏界面的样子。后续文章将给出艺术素材的源文件。
7. 编程语言在Unity中,可选的编程语言有3种:
UnityScript,一个JavaScript的变种
以上语言各有利弊,你需要根据自己喜好选择其中的一种。
文章作者选择了C#,我打算先按照作者的C#过一遍,然后再用UnityScript替代。
如果选择其他语言,可参阅。
8. 2D图Unity是一个在不同平台上创建3D游戏的著名平台,比如微软的Xbox360,任天堂的Wii,Web,以及其他移动平台。
不过,在Unity4.3版本以后,它也可用于2D游戏开发。因为是2D游戏,我们将使用图片作为精灵表,而不是使用3D游戏中的材质。
9. 音效本文将使用一系列声音创建良好的游戏音效。本文中使用的音效来源于:
10. 导入Assets在写代码之前,需要加入asserts到Unity项目中。可使用以下几种方式之一:
在Assets菜单中选择Import New Asset
将assets条目加入到项目的assets文件夹中
将assets拖拽到项目窗口中
我一般用最后一种。
这一步做好,就可在Project面板的Assets文件夹中看到这些assets。
11. 创建场景将对象拖拽到Hierachy面板或者Scene面板中,就会创建默认场景。
另外,只要在创建项目后command+s保存,也可以创建默认场景。
12. 背景将背景图片拖拽到Hierarchy面板中,会自动显示在Scene面板中。
我在操作的时候,怎么拽图片,也无法放在Hierarchy面板里去。
后来借助文章,找到问题了:
The Default Behavior Mode defines the default import settings for your project’s art assets. When set to 3D, Unity assumes you want to create a Texture asset from an imported image file (e.g. a .PNG file); when set to 2D, Unity assumes you want an asset of type Sprite. You’ll read more details about Sprite assets and import settings throughout this tutorial.
需要设置:
然后,如果你之前就没有设置项目的这个属性,重新将图片拽到Assets面板中,然后再拖拽到Hierarchy面板中。
另外,需要将Main Camera在Inspector面板中的属性做下修改,透视投影改为正交投影,Size设置为1.58。
13. 地面将地面的素材图,导入到Assets,然后,拖拽到Scence面板中,再微调拼接好。
看起来效果是这样的:
14. 地面碰撞为了让人物在接触到地面时被检测到,我们需要为地面增加Component,Box Collider 2D。
在Scene面板中选择地面,然后打开Inspector面板,点击Add Component按钮,在Component列表中的Physics 2D中选择Box Collider 2D,见下面图:
15. 跳跃按钮我们将使用按钮控制游戏中的主要人物。拖拽跳跃按钮图到Scene面板,然后为它加上Circle Collider2D组件。
完成这步后,可在Game面板看到类似这样的效果:
做到这里碰到了问题,跳跃按钮会在运行时,会隐藏在当前图的后面,我现在的解决办法是:
Order in layer默认都是0,设置为1,就可见了。
16. 跳跃的声音在Scene面板里选择跳跃按钮,然后在Inspector面板里点击Add Component按钮。在Audio里选择Audio Source。
然后需要取消Play on Awake勾选项。再然后做如下操作,见图:
17. 跳跃脚本现在需要创建脚本来控制人物。选择跳跃按钮,点击Add Component按钮,选择New Script,命名脚本为Jump,不要忘记选择C#语言,默认的脚本语言是JavaScript。
系统将自动呼出MonoDevelop作为脚本的IDE。将下面代码粘贴进去:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465using UnityEusing System.Cpublic class Jump : MonoBehaviour{ public float jumpF private GameO
void Start() {
hero = GameObject.Find("Hero");
void Update() {
if (Application.platform == RuntimePlatform.Android)
if (Input.touchCount & 0)
if (Input.GetTouch(0).phase == TouchPhase.Began)
CheckTouch(Input.GetTouch(0).position, "began");
} else if (Input.GetTouch(0).phase == TouchPhase.Ended)
CheckTouch(Input.GetTouch(0).position, "ended");
if (Application.platform == RuntimePlatform.OSXEditor)
if (Input.GetMouseButtonDown(0))
CheckTouch(Input.mousePosition, "began");
if (Input.GetMouseButtonUp(0))
CheckTouch(Input.mousePosition, "ended");
} }
void CheckTouch(Vector3 pos, string phase) {
Vector3 wp = Camera.main.ScreenToWorldPoint(pos);
Vector2 touchPos = new Vector2(wp.x, wp.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if (hit.gameObject.name == "JumpButton" && hit && phase == "began")
hero.rigidbody2D.AddForce(new Vector2(0f, jumpForce));
audio.Play();
} }}
这部分代码很直白。获取hero对象,这是一个GameObject类的实例。我们后面会用到它。然后,我们检测用户是否点击了跳跃按钮,如果是这样,就给hero对象一个力,最后,我们播放跳跃的声音。
为了能立即执行这个代码,比如在andorid下,我屏蔽了部分还用不上的代码,比如创建hero对象。
做到这一步,我们就可以通过Build & Run部署到Android设备上运行了。或者直接在Game视图中运行。目前的一个问题是,只要点击了跳跃按钮,声音就开始不停的重复播放。需要做如下设置:
18. 移动按钮在界面中添加按钮asserts,左和右。
其实2个按钮是同一个图片asserts,需要将图形做一个转换:
19. 移动脚本创建一个新的脚本,名为MoveLeft,附加在向左移动的按钮上:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677using UnityEusing System.Cpublic class MoveLeft : MonoBehaviour{
public Vector3 moveSpeed = new Vector3();
private bool moving = false;
private GameObject[]
private GameO
void Start()
scene = GameObject.FindGameObjectsWithTag("Moveable");
bg = GameObject.Find("Background");
void Update()
if (Application.platform == RuntimePlatform.Android)
if (Input.touchCount & 0)
if (Input.GetTouch(0).phase == TouchPhase.Began)
CheckTouch(Input.GetTouch(0).position, "began");
} else if (Input.GetTouch(0).phase == TouchPhase.Ended)
CheckTouch(Input.GetTouch(0).position, "ended");
if (Application.platform == RuntimePlatform.OSXEditor)
if (Input.GetMouseButtonDown(0))
CheckTouch(Input.mousePosition, "began");
if (Input.GetMouseButtonUp(0))
CheckTouch(Input.mousePosition, "ended");
if (moving && bg.transform.position.x & 4.82f)
for (int i = 0; i & scene.L i++)
if (scene [i] != null)
scene [i].transform.position += moveS
void CheckTouch(Vector3 pos, string phase)
Vector3 wp = Camera.main.ScreenToWorldPoint(pos);
Vector2 touchPos = new Vector2(wp.x, wp.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if (hit.gameObject.name == "LeftButton" && hit && phase == "began")
moving = true;
if (hit.gameObject.name == "LeftButton" && hit && phase == "ended")
moving = false;
} }
这里要提到,tag(标签),是操作多个GameObject(游戏对象)的方法。我们可以在Unity界面中给多个游戏对象,比如floor(地面)和Background(背景)对象标识为Moveable的标签。
这样,如果我们需要Hero(英雄)移动的时候,可以反方向移动floor(地面)和Background(背景)。
tag是需要添加的:
添加后就可以这样设置tag:
类似的,我们可以创建MoveRight脚本,将它附加在向右移动的按钮上。代码类似这样:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126using UnityEusing System.Cpublic class MoveRight : MonoBehaviour{
public Vector3 moveSpeed = new Vector3();
private bool moving = false;
private GameObject[]
private GameO
public AudioClip completeS
private GameObject[]
private GameObject completeT
private bool ended = false;
public Font goodD
void Start()
scene = GameObject.FindGameObjectsWithTag("Moveable");
bg = GameObject.Find("Background");
buttons = GameObject.FindGameObjectsWithTag("Buttons");
void Update()
if (Application.platform == RuntimePlatform.Android)
if (Input.touchCount & 0)
if (Input.GetTouch(0).phase == TouchPhase.Began)
CheckTouch(Input.GetTouch(0).position, "began");
} else if (Input.GetTouch(0).phase == TouchPhase.Ended)
CheckTouch(Input.GetTouch(0).position, "ended");
if (Application.platform == RuntimePlatform.OSXEditor)
if (Input.GetMouseButtonDown(0))
CheckTouch(Input.mousePosition, "began");
if (Input.GetMouseButtonUp(0))
CheckTouch(Input.mousePosition, "ended");
if (moving && bg.transform.position.x & -4.8f)
for (int i = 0; i & scene.L i++)
if (scene [i] != null)
scene [i].transform.position -= moveS
if (bg.transform.position.x &= -4.8f && ended == false)
Alert("complete");
void CheckTouch(Vector3 pos, string phase)
Vector3 wp = Camera.main.ScreenToWorldPoint(pos);
Vector2 touchPos = new Vector2(wp.x, wp.y);
Collider2D hit = Physics2D.OverlapPoint(touchPos);
if (hit.gameObject.name == "RightButton" && hit && phase == "began")
moving = true;
if (hit.gameObject.name == "RightButton" && hit && phase == "ended")
moving = false;
public void Alert(string action)
ended = true;
completeText = new GameObject();
completeText.AddComponent("GUIText");
completeText.guiText.font = goodD
completeText.guiText.fontSize = 50;
completeText.guiText.color = new Color(255, 0, 0);
if (action == "complete")
AudioSource.PlayClipAtPoint(completeSound, transform.position);
completeText.guiText.text = "Level Complete!";
completeText.guiText.transform.position = new Vector3(0.24f, 0.88f, 0);
} else
completeText.guiText.text = "Game Over";
completeText.guiText.transform.position = new Vector3(0.36f, 0.88f, 0);
bg.GetComponent&AudioSource&().Stop();
for(int i = 0; i & buttons.L i++)
buttons[i].renderer.enabled = false;
Invoke("restart", 2);
void restart()
Application.LoadLevel(Application.loadedLevel);
}}
这里的Alert函数用来创建提示玩家的信息,并播放附加在对应背景对象的声音。然后让所有按钮隐藏,然后间隔2秒后重新开始游戏。
TODO 这里播放声音需要解释
20. 精灵表我们将使用精灵表(sprite sheet)展现游戏的其他元素。Unity有一个精灵表编辑器,使得设置精灵表变得很容易。
精灵表是一张图:
这张图来源于:
需要将它导入到Unity,成为asserts。然后,在Inspector面板中设置它为Multiple,默认是Single:
然后,点击Sprite Editor按钮,在弹出的对话框里点击Slice,这是自动识别精灵表的每个元素:
这之后,精灵表看起来就是这样的了:
21. 英雄然后,我们就可以从精灵表中将英雄拖拽到Scene视图中:
然后,给它加上Collider 2D组件,这是原文的写法,不过有多种Collider 2D组件,我先使用Box Collidar 2D组件,如果以后发现不妥再修改。
22. 英雄2D刚体为了能对英雄检测碰撞,需要至少给碰撞的一方设置位RigidBody 2D组件。也就是2D刚体。我们给英雄设置一下这个组件。
我们不希望英雄在碰撞后发生角度变化,因此需要勾选Fixed Angle:
如果地面当时忘记设置Box Collider 2D,那么设置RigidBody 2D后,英雄会掉落而不是站在地面上。
这时候,可以运行一下这个游戏,看是否能借助前面跳跃的脚本,让英雄跳跃起来。
23. 英雄的声音当英雄被敌人击中,我们要为游戏玩家播放另外一个声音。首先需要加入这个声音,和跳跃按钮添加声音类似。
24. 收集金币收集金币,是很多2D游戏有的需求。我们需要在游戏中多次使用金币。后面我们会将金币转换为Prefab(预设),这样就可以在所有需要的地方添加它了。
在这一步,我们还是将金币的图,从Assets中拖拽到游戏场景中,然后像上面类似的为它添加Box Collider2D组件。
25. 金币的声音和添加英雄声音类似,给金币设置声音。
26. 金币的脚本和Prefab(预设)和跳跃脚本的添加方式类似,代码是:
123456789101112131415161718using UnityEusing System.Cpublic class GrabCoin : MonoBehaviour{
void OnTriggerEnter2D(Collider2D other) {
Debug.Log("play sound....");
if (other.gameObject.name == "Hero")
audio.Play();
Destroy(gameObject.collider2D);
gameObject.renderer.enabled = false;
Destroy(gameObject, 0.47f);
} }}
另外,别忘记给金币设置为trigger:
否则当英雄碰撞金币的时候不会触发OnTriggerEnter2D方法。
然后是将这个金币生成为Prefab,操作很简单,只需要将Hierarchy面板中的coin拖拽到下面的Assets中即可。
27. 敌人和上面操作类似,添加敌人:
需要为敌人创建2个Collider 2D,下面的是检测敌人碰到英雄的(失败),另外一个放在敌人头上,用于检测英雄从上面下来碰撞到敌人(敌人被杀死)
不要忘记勾选Is Trigger
然后是添加脚本,见下面
最后,将敌人设置为Prefab
123456789101112131415161718192021222324252627282930313233343536373839404142using UnityEusing System.C public class Enemy : MonoBehaviour{
public Vector3 moveS
public AudioClip hitS
public GameObject alertB
void Start()
void Update()
transform.position -= moveS
void OnCollisionEnter2D(Collision2D other)
if (other.gameObject.name == "Hero")
AudioSource.PlayClipAtPoint(hitSound, transform.position);
Destroy(gameObject);
void OnTriggerEnter2D(Collider2D other)
if (other.gameObject.name == "Hero")
other.gameObject.audio.Play();
Destroy(other.gameObject.collider2D);
other.gameObject.renderer.enabled = false;
Destroy(other.gameObject, 0.626f);
alertBridge.GetComponent().Alert("gameover");
}}
28. 砖头砖头的逻辑比较简单,无非是:
添加Collider 2D组件
转换为Prefab
29. 结束最后,我们需要创建一个重点游戏对象。当英雄碰到它触发完成游戏。
30. 杜比音频插件略。
31. 测试略。
32. 播放器设置略。
33. 图标和开场画面略。
34. 构建和播放略。Unity3D 学习从简单开始-AssetDatabase的使用 - Cici_coach的博客 - CSDN博客
Unity3D 学习从简单开始-AssetDatabase的使用
& & & 今天,为大家分享一下AssetDatabase的功能点,AssetDatabase是一个对资源进行读写和各种操作的接口;
然而因为这是一个编辑类,当需要使用的时候把他放在工程目录下的Assets/Editor 文件夹下,编辑器类还需要
在UnityEditor 的命名空间下。欢迎加我的学习交流群:。
& & & 好吧!废话不多讲,我直接用AssetDatabase中的一些常用的知识点进行浅析。
& & &官方文档:
& & &1.创建一个unity3d项目,首先在工程项目中新建一个Editor文件夹,并且附加一个编辑器测试类CreateTestMaterial.
& & & & &CreateTestMaterial.cs代码如下:
using UnityE
using UnityE
public class CreateTestMaterial : Editor {
[MenuItem(&Example/Create Asset&)]
static void CreateMaterial()
var material = new Material(Shader.Find(&Specular&));
AssetDatabase.CreateAsset(material, &Assets/Materials/TestMaterial.mat&);
Debug.Log(AssetDatabase.GetAssetPath(material));
[MenuItem(&Example/Delete Asset&)]
static void ImportMaterial()
AssetDatabase.DeleteAsset(&Assets/Materials/TestMaterial.mat&);
[MenuItem(&Example/Copy Asset&)]
static void CopyMaterial()
AssetDatabase.CopyAsset(&Assets/Materials/TestMaterial.mat&, &Assets/NewMaterials/TestMaterial.mat&);
& & &2.在编辑器上面Example上点击Create Asset,我们会发现在Materials文件夹下会生成一个.mat文件;
& & &3.在编辑器上面Example上点击Delete Asset,我们会发现Materials文件夹下.mat 会被删除掉;
& & &4.在编辑器上面Example上点击Copy Asset,我们会发现NewMaterials文件夹下也会生一个和Materials一样的.
& & &PS:其实AssetDatabase 还有其他的很多的方法和功能,感兴趣的同学可以更深入的研究一下哈!
我的热门文章
即使是一小步也想与你分享XUPorter项目Github链接
为什么想要自动添加
由于Unity是全平台的游戏开发环境,在开发中针对特定平台的特定功能时,很难避免根据对象平台的不同而引入不同的依赖。包括源码,需要的库和框架等。
为什么想要自动添加
由于Unity是全平台的游戏开发环境,在开发中针对特定平台的特定功能时,很难避免根据对象平台的不同而引入不同的依赖。包括源码,需要的库和框架等。在使用各种插件后这种情况愈发严重:比如想加入内购功能,StroreKit.framework必不可少,而且也需要相应的处理代码。按照一般的Unity插件开发流程,在完成.cs的接口声明和Unity侧的调用实现后,最重要的当然是在iOS native侧完成实现。而在以前,包括依赖库和所有源码文件,都只有在Unity生成Xcode工程之后,再手动添加。如果工程小依赖少的话花不了太多时间,但是如果项目很大,很可能折腾一次就要十来分钟,严重影响了工作效率,必须加以解决。
Unity开发团队也意识到了这个问题,在Unity编译的最后加入了一个脚本调用的命令,会自动搜索Editor文件夹下的PostprocessBuildPlayer,并进行调用,在该文件中可以自己加入脚本来向Xcode中添加库和文件。关于PostprocessBuildPlayer的详细信息,可以参看,关于向Xcode中添加文件或库,gonzoua的也许是不错的选择。但是似乎xcs只能针对Xcode3来添加,在Xcode4中,主工程文件的结构发生了改变,导致xcs失效,而这个项目也迟迟没有更新(也许有时间我会考虑接手继续这个项目,但肯定不是现在...)。因此不得不打其他主意。
在Unity3.5中,加入了一个很棒的标签——,被该标签标注的函数将自动在build player后被调用,这为大家提供了一个不需要用脚本和命令行就能添加或修改编译得到的工程的绝好的入口。darktable用python实现了一个Xcode4工程文件读写的接口,但是对于Unity来说,更需要的是C#的实现。Cariola完成了,但是存在一些错误和不太好用的地方,代码也很乱。我在其基础上进行了一些改进和整理。但是因为变动的还是比较大,很难merge回去,所以决定自己开一个项目来继续推进这个项目。
我把它叫做XUPorter,a dependency porter from Unity to Xcode。XUPorter可以读取Xcode工程文件并进行解析(再次感谢darktable的工作),之后在Unity工程的Assets目录下寻找所有的.projmods文件,并根据文件内容向工程中添加文件或库。
将Github项目中的所有文件copy到Unity工程文件夹下的/Assets/Editor目录中,XUPorter使用一个来进行。如果你的项目中已经在使用这个MiniJSON了的话,可以直接将XUPorter文件夹下的MiniJSON文件夹删掉;如果不一样的话,你可以选择其中一个重构一下或者加上命名空间来解决类名冲突。接下来,Mods文件夹下是示例文件以及需要导入Xcode的文件。在看完以后你需要把Mods文件夹下的所有.projmods文件以及Mods/iOS文件夹下的内容删除或者替换为你所需要的内容。
在提供了.unitypackege格式文件的下载,你也可以选择下载打包好的文件并导入你的工程,之后的步骤和上面一样。
.projmods文件是一个JSON格式的配置patch文件,定义了要如何设置Xcode工程。举个基本的例子,比如KKKeychain.projmods:
"group": "KKKeychain",
"libs": [],
"frameworks": ["Security.framework"],
"headerpaths": [],
"folders": ["iOS/KKKeychain/"],
"linker_flags": [],
"excludes": ["^.*.meta$", "^.*.mdown$", "^.*.pdf$"]
各参数定义如下:
group:所有由该projmods添加的文件和文件夹所属的Xcode中的group名称
libs:在Xcode Build Phases中需要添加的动态链接库的名称,比如libz.dylib
frameworks:在Xcode Build Phases中需要添加的框架的名称,比如Security.framework
headerpaths:Xcode中编译设置中的Header Search Paths路径
files:加入工程的文件名
folders:加入工程的文件夹,其中所有的文件和文件夹都将被加入工程中
linker_flags:添加到工程linker flag中的链接配置,比如-ObjC
excludes:忽略的文件的正则表达式,匹配的文件将不会被加入工程中
更多的例子可以参看Mods文件夹中的其他projmods文件。所有的定义路径都是基于当前projmods文件位置的相对路径。 最后,在完成projmods后,Unity会在编译完成后,调用XCodePostProcess的OnPostProcessBuild来对编译得到的Xcode工程进行修改。
之后进一步要做的是为MiniJSON添加一个namespace,这样可以避免不必要的冲突。另外如果您有什么好的想法,也欢迎fork这个项目并给我pull request。项目的github链接请。.
版权声明:本文内容由互联网用户自发贡献,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至: 进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
用云栖社区APP,舒服~
【云栖快讯】阿里云数据库MySQL金融版发布,实现日志多副本同步复制,提供金融级可靠性!8月10日,阿里云数据库掌门人褚霸等大牛直播,揭开它的背后故事!赶紧报名吧&&
面向阿里云ECS实例、HPC和Docker的文件存储服务。
是将源站内容分发至全国所有的节点,缩短用户查看对象的延迟,提高用户访问网站的响应速度与网站的可用性,解决网络带宽...
以阿里云成熟的商业化云服务为基础,为游戏开发者、运营企业提供专属集群、尊享VIP服务、专项扶持基金、及多场景多类...
为您提供简单高效、处理能力可弹性伸缩的计算服务,帮助您快速构建更稳定、安全的应用,提升运维效率,降低 IT 成本...
2017杭州云栖大会火热抢票
Loading...}

我要回帖

更多关于 unitystandardassets 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信