不解

将博客搬至CSDN

将博客搬至CSDN

最好用的 unity3d Json数据传输,插件JsonFx !!

之前用过一些插件,都是根据取key值来得value。感觉操作起来很麻烦,特别是在unity3d游戏数值比较多的情况下。


比如一个得到Json,先序列化,然后["name"] =  xxx, ["hp"] = xxx, ["fuck"] = XX,


麻烦,效率低,字符串不能批量改名,代码写出来有一堆,恶心!


之下介绍一个插件。JSONFX,百度一下,你找不到,Google一下,你能知道,原因不解释。


下面直接用代码来、文字、和截图来分析JsonFx的用法与妙处:


我的工程目录:


自己封装了一个类,用来读取文件,名字为ReadFileTool。 代码有注释可以自己看。

[csharp] view plaincopy

  1. /****************************************************************************** 
  2.  * 
  3.  * Maintaince Logs: 
  4.  * 2013-01-06   WP      Initial version.  
  5.  * 2013-01-10   WP      Added:FetchLevelByTXTFile(),FetchLevel(),FetchItem() 
  6.  * *****************************************************************************/  
  7.   
  8. using UnityEngine;  
  9. using System.Collections;  
  10. using System.Collections.Generic;  
  11. using JsonFx.Json;  
  12.   
  13. /// <summary>  
  14. /// use for external call  
  15. /// </summary>  
  16. public class ReadFileTool : MonoBehaviour  
  17. {  
  18.   
  19.     /// <summary>  
  20.     /// 根据一个JSON,得到一个类  
  21.     /// </summary>  
  22.     static public T JsonToClass<T>(string json) where T : class  
  23.     {  
  24.         T t = JsonReader.Deserialize<T>(json);  
  25.         return t;  
  26.     }  
  27.   
  28.     /// <summary>  
  29.     /// 根据一个JSON的文件地址,得到一个类  
  30.     /// </summary>  
  31.     static public T AddressToClass<T>(string txtAddress) where T : class  
  32.     {  
  33.         TextAsset jsonData = Resources.Load(txtAddress) as TextAsset;  
  34.         return JsonToClass<T>(jsonData.text);  
  35.     }  
  36.   
  37.     /// <summary>  
  38.     /// 将JSON转换为一个类数组  
  39.     /// </summary>  
  40.     static public T[] JsonToClasses<T>(string json) where T : class  
  41.     {  
  42.         //Debug.Log(json);  
  43.         T[] list = JsonReader.Deserialize<T[]>(json);  
  44.         return list;  
  45.     }  
  46.   
  47.     /// <summary>  
  48.     /// 给Json文件的地址。转换为一个类数组  
  49.     /// </summary>  
  50.     static public T[] AddressToClasses<T>(string txtAddress) where T : class  
  51.     {  
  52.         TextAsset jsonData = Resources.Load(txtAddress) as TextAsset;  
  53.         return JsonToClasses<T>(jsonData.text);  
  54.     }  
  55.   
  56. }  


一个Json文件:

目录下的players.txt文件内容为:

[{"name":"ant","health":20,"maxHealth":20,"speed":1,"attackPower":6,"attackRate":1.5,"attackRange":1,"lastAttackTime":0},
{"name":"goblin","health":60,"maxHealth":60,"speed":0.5,"attackPower":7,"attackRate":1.5,"attackRange":1,"lastAttackTime":0},
{"name":"groundArrow1","health":10,"maxHealth":10,"speed":1,"attackPower":3,"attackRate":1,"attackRange":1,"lastAttackTime":0},
{"name":"groundArrow2","health":50,"maxHealth":50,"speed":1,"attackPower":3,"attackRate":1,"attackRange":6,"lastAttackTime":0}]


Player类:

[csharp] view plaincopy

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. /// <summary>  
  5. /// 玩家的属性类  
  6. /// </summary>  
  7. public class PlayerStat  
  8. {  
  9.     public string name = "";  
  10.     public int health;  
  11.     public int maxHealth;  
  12.     public int speed;  
  13.     public int attackPower;  
  14.     public float attackRate;  
  15.     public int attackRange;  
  16.     public int lastAttackTime;  
  17.   
  18.     //友情提示,这个是JsonFx必须要的  
  19.     public PlayerStat() { }  
  20. }  

准备工作就已经做好,现在开始要读取Json。。


GM类,新建一个场景,将这个类放到任意物品上。

[csharp] view plaincopy

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class GM : MonoBehaviour  
  5. {  
  6.     //放了所有的player的属性  
  7.     public static PlayerStat[] players;  
  8.   
  9.     const string addressPlayer = "data/players";  
  10.   
  11.     //第一次进入游戏  
  12.     public static bool isFirst = true;  
  13.   
  14.     void Awake()  
  15.     {  
  16.         if (isFirst)  
  17.         {  
  18.             isFirst = false;  
  19.             players = ReadFileTool.AddressToClasses<PlayerStat>(addressPlayer);  
  20.         }  
  21.     }  
  22.   
  23.     void Start()  
  24.     {  
  25.         foreach (PlayerStat p in players)  
  26.         {  
  27.             Debug.Log("名字:" + p.name + "  health:" + p.health);  
  28.         }  
  29.     }  
  30. }  

运行与结果:




OK。如此简单,json里面的内容就全部放到了自己的静态类之中。


另外友情提示,JsonFx支持把Class 序列化为 Json。


个人觉得非常方便。


目前已知Bug:比如传一个float值为2的,可能会变成1.99999999.。。虽然知道unity3d的浮点型运算也有错,这里大胆猜测是jsonfx的原因。

LitJson也有浮点型的问题。不过不算硬伤。


转载时请注明出处

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用


【干货】Unity3d的2D骨骼动画插件Puppet2D的使用

开发Cocos2D的程序员都知道,Cocostudio其中一个动画编辑组件中的。骨骼动画对于游戏开发的性能上是很好的,有些时候和序列帧动画相比。
强大的unity3d虽然也可以开发2D游戏,可以序列帧实现动画。 还是没有2d的骨骼动画编辑功能。
最近开发了一个第三方的插件,专门对unity实现这个功能。 那就是Puppet2D。

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

Walkthrough演练

Introduction:

这是一个快速的演练,如何使用Puppet2D设置一个角色的动画。首先打开一个新的场景,在Scene视图中的 2D 按钮上单击。可以在窗口顶部的菜单中找到window-> Puppet2D


Createthe Character:

在Project面板中你会发现在Puppet2D/Textures/PuppetMan文件夹中的puppet2d角色精灵。展开它,将每个身体部位拖动到场景视图排列它们,所以它看起来像图像bellow。(移动的 z 分量以使胳膊和腿出现在正确的绘制顺序)

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月


CreateLayers:

现在我们想要将角色放到锁定的图层上,所以,我们不要无意中选择他当我们画的骨头。要选择层屏幕右顶部下拉选择,去编辑图层和自由层插槽中键入Character。锁定该图层,然后选择所有精灵在你的场景中,并从在检查器中的层下拉列表中选择该Character。

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

现在我们可以制作bones骨骼和control sortinglayer控制排序图层。在屏幕顶上Layer中下拉,添加两个排序图层----叫一个Bones和一个Controls。现在,我们已准备好去取出骨头的功能。

BoneCreation:

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月




首先骨层到Puppet2D窗口中的Bones设置。单击"Create Bone Tool"按钮可启动该工具。现在,您可以单击到Scene视图开始绘图骨头。1、从hip臀部开始和spine脊柱骨骼和head头部的骨头,2、然后 右键单击以结束当前的骨。3、点击顶部的spine脊柱joint和开始绘制的左的手臂leftarm、 手肘elbow,然后手hand,4、右键单击要结束的骨。5、现在做相同的right arm右手臂。6、hip骨单击鼠标左键,开始画thigh大腿、knee膝盖,然后foot脚,7、右键单击并重复另一条leg腿。现在要退出骨创作单 击"Finish Bone"按钮。


现在我们应该命名所有的骨头,让事情清楚。您的层次结构如下所示。


【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

RiggingSetup:操纵设置


现在我们要创建的控制,我们可以用来制作角色动画。

首先选择控制在下拉中,因此控制在排序图层上创建" Controls "。

选择 handL 骨,然后单击“CreateIK Control”。这将创建要进行动画处理,将容易的手动控制。对于 handR,footL,footR,重复此操作。

接下来我们需要创建身体控制----选择臀部,然后单击“CreateParent Control”。这将使一个control来移动和旋转臀部。

若要创建spine controls脊柱控制,选择spine脊柱,然后单击“CreateOrient Control”。如果你注意到在我们的 heierachy 我们有全局的控制-----这是所有控制的父级。选择 spine_CTRL_GRP,并将它拖到 hip_CTRL。下一步选择头部骨骼并单击“Create Orient Control”。选择 head_CTRL_GRP,并将它拖到spine_CTRL。

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

Skinning:

控制已设置我们需要加入到角色的骨头。有两种方法做到这一点------父精灵关节和皮肤:

Parenting:

hierarchy中选择PuppetMan_armBottom,PuppetMan_armTopand,和 PuppetMan_gunTop,以及所有的骨头。现在单击"Parent Objects to bones"。

Skin Binding:

皮肤的身体部位的骨头,我们首先需要将它们转换为可更换皮肤的网格。要做到这一点选择其余的网格,然后单击“Convert Sprites to Mesh”.。选择它们并将它们添加到Character层。

Now select legL,kneeL,footL,hip, spine and PuppetMan_body_GEO and click “Bind smooth Skin”.

Selecthip,legR,kneeR,footR and PuppetMan_leg_GEO and click “Bind smooth Skin”.

Select Spine,armR, elbowR,handR and PuppetMan_armR_GEO and click “Bind smooth Skin”.

Select Spine ,head and PuppetMan_head_GEO and click “Bind smooth Skin”.

FinalSetup

它差不多准备好了要进行动画处理。但首先,我们需要清理scene和修复一些skin weights皮肤权重。

hierarchy中将臀部和所有的网格拖动到Global_CTRL。现在,选择全局控制,把它打开和关闭来刷新它。现在,您可以将可见性的骨头-------因为你不需要看到他们要进行动画处理的character。

尝试移动圆形控件------那里也许加权的几个问题喜 欢footarea。要修复选择PuppetMan_leg_GEO 和 PuppetMan_body_GEO,然后单击" Edit skin weights "。您应该注意出现的小顶点手柄。选择它们,你会看到您可以更改inspector中的权重。如果你想要一次更新多个重量-单击inspector中的 “Update Skin Weights”按钮。

一旦你已经调整了他们让您满意,请单击“FinishEdit Skin Weights”要删除的顶点手柄。

现在的v应该是准备要进行动画处理。


Animating:


动画 Puppet2D character在一切动画在 Unity 中以同样的方式工作。选择Global_CTRL,在动画窗口中创建一个新的剪辑clip。移动控制并设置关键帧,随便哪里只要你喜欢----快乐动画!

Introduction:

Puppet2D 是一种工具允许您快速设置你的 2D 角色动画的。使用此工具可以创建 2D 骨骼、皮肤你的人物的骨头,并创建真的很容易使用的控件,使动画角色一阵微风。

要打开 Puppet2D 窗口,选择Puppet2D 菜单,转到Window>Puppet2DWindow。在此窗口中包含所有创作工具。

若 要开始创建你的被操纵东西,你要准备好你的角色被“rigged”。在unity进入场景视图并单击 2D 的按钮,在视图的顶部。在你的 2D 角色精灵中拖动并放入锁定的图层。这是有用的所以你不要到头来不小心点击它当你试着画骨头或控制。现在你准备好开始创建骨骼。

Bone& Control Layers and scale:

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

你就能够更改控制和骨头顶部的Puppet2D 窗口的大小。您还可以指定排序骨头将创建下一层。一旦他们已经被创建,所以请确保你在你的骨骼和控制在创建之前开始处设置这,这不会改变他们的层。

Skeleton骨架:

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

BoneCreation:

骨骼是将控制你的小木偶是如何移动的支点。

若要开始创建一根骨头,请单击“Create Bone Tool”按钮。这会设置你中骨创建模式。

你会留在这种模式下,直到您按输入或单击“Finish Bone”按钮。

2D 视图中开始使用鼠标左键,你会开始绘图的骨头。每个骨骼会到父级无论您选择了。

Create Bone Tool按钮------开始创建骨骼

鼠标左键单击------绘制的骨头

退格键------删除选定的骨骼

按住 shift 键------移动选定的骨骼只

按住 ctrl 键------移动选定的骨骼和它的孩子

Alt 单击鼠标左键------选定的骨骼和它的孩子之间插入骨

单击鼠标右键------取消选择骨骼

按 enter 键/点击“Finish Bone”-----------完成在中创建的骨头。

SplineCreation:

这是一种特殊的表现为一条贝塞尔曲线的骨链。当您绘制的控件而不是骨头,它是比正常骨骼以不同的方式创建。

若要开始创建一根骨头,请单击“CreateSpline Tool”按钮。这将设置你在样条创建模式下。你会留在这种模式下,直到您按输入或单击“Finish Spline”按钮。在这一点上,我们也须待骨头。

2D 视图中开始使用鼠标左键,你会开始绘制SplineControls。

使用滑块可以指定将每个控件之间作出多少块骨头。设置此之前启动此工具。

鼠标左键单击-----------绘制控件

持有 Shift 或 Ctr----------移动控件

按 enter 键/点击"完成样"-----------完成在中创建样条控件

RiggingSetup:

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

尽管它可能只是按直接旋转关节动画显示您的角色,这可能是棘手的方式来进行动画处理,特别是当它来到保持双脚在地面上的。使用 Puppet2D 创建一些自定义的控件,为你的角色是一个非常快速的过程,和真的使进行动画处理的工作,更直观、更容易。

Global Control全局控制

当您首次创建控件时,您将看到gloabl_ctrl 也会创建在层次结构中。这是从所有控件的脚本得到执行的基础。关闭此脚本将禁用所有控件。你会想要在这个游戏物体上添加您的动画并移动它,移动你的角色。

Start Rotation Y –允许你改变你的角色的 y 轴平面

IK handles –此角色所有 Ik 句柄,(按执行顺序)

Parent Controls – all the Parent &Orient for this character (in execution order)

Control Visibility – Turns controlsvisibility ,打开和关闭

Bones Visibility -这将切换所有的骨头,这global_Ctrl(使确信你按你父骨的刷新按钮第一个时间)的父级的可见性

Combine Meshes –这结合成一个网格共享一个纹理,(所以 1次draw call)的所有网格

Flip翻转– use this to flipthe character in the x-axis

Auto Refresh – auto orders the executionorder of the controls

Refresh Global Control – click this whenyou change something in the rig – such as delete a control or change thehierarchy in some way.

通过使用flip翻转复选框,可以在 x 轴翻转角色。

IKControls(IK 管制)

是您需要为任何你的人物四肢 (IE 胳膊或腿) 的控件。这给你一个单端控制,您可以使用动画显示他们的肢体。这将意味着你的脚会停留在地面,当你移动它的身体。

若要创建 IK 控制,选择三个骨链的末端,然后单击“Create IK Control”按钮。例如,如果您有腿部的骨头,比如thighBone>kneeBone>footBone。选择这脚骨相吻合并单击按钮

通过单击检查器中的"翻转"复选框,可以翻转哪些方式膝盖“flip” 脸。这也可以进行动画处理。

如果你想你可以有“stretchy limbs”通过单击“Squash and Stretch”复选框。

Parent& Orient Controls

与 直接对骨骼进行动画处理的一个问题是他们开始从尴尬的rotations和positions。这就意味着你不能迅速通过零位调整他们重置他们。 Puppet2D 允许您创建控件更容易选择和起步在零的位置和旋转,所以可以轻松地重置。Parents控件影响的位置和旋转,orient的控制影响只旋转。

若要创建parent控件中选择一根骨头,控制,然后单击“Create Parent Control”

若要创建一个orient的控件选择一根骨头,控制,然后单击“Create Orient Control”

通过将滑块移动到所需的规模,可以调整控件大小在你的场景。

在下拉菜单底部的索具安装程序中,您可以选择哪些排序的层,以将控件放在上。它是一个好主意,有一个“Control”排序图层,所以你能直观地在字符和骨头。

Skinning

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

有三种方法得到的骨头来影响你的精灵;由parenting,parenting,或FFD。

Parenting

您可以手动parent你的精灵的骨头,但加快了Puppet2D 的这份工作有一个按钮,所有的你一次过的对象。选择所有的骨头和所有精灵或对象,然后单击“Parent Object to bones”.。这将父您最近的骨头的所有对象。

Skinning

Skinning允许单个的对象,将会受到更多于一根骨头。为了做到这一点的精灵需要转换为一个网格。

要做此选择您的精灵(确保它没有父级),然后单击“Convert Sprite To Mesh”。你可以选择如何细分你想要从“Typeof Mesh”下拉菜单中的网格。

您可以通过第一次将一个 polygon2Dcollider 组件添加到精灵更改的网格中顶点的数量。您可以使用此删除并添加之前将其转换为一个网格的顶点。

要 将网格绑定到骨头,选择所有的骨头和皮肤,然后单击“Bind Smooth Skin”.。您可以选择您希望默认皮肤要绑定到使用“num Skin Bones”下拉菜单中的骨头的数量。您的网格现在应该对它有皮肤网格渲染器组件。~ 如果你移动骨骼网格应随之移动。

要绘制皮肤权重选择您的网格并单击“PaintSkin Weights”.。现在,您可以通过选择所需的骨绘制网格顶点上每个骨骼的强度,并单击鼠标左键绘制权重的那块骨头。

通过使用滑块来更改画笔大小和强度或持有 B 画笔大小和 N 的强度。

Left Click – Add Weights

Hold ALT – Subtract weights

Hold SHIFT – Smooth Weights

Hold B – change brush size

Hold N – Change brush strength

通过单击“Finish Edit Skin Weights”完成绘画权重

您 还可以手动编辑皮肤权重通过单击“EditSkin Weights”按钮。你会看到一堆父级到网格的顶点物体。如果你选择你将看到的骨骼影响的顶点,紧接着他们的权重列表的顶点。若要编辑的权重值或影响, 只需更改检查器中的值。如果您想要更改多个顶点一次,更改的值,然后单击检查器中的“Update Skin Weights”按钮

完成编辑权重单击Finish Edit Skin Weights”按钮和顶点将被删除。

通过将滑块移动到所需的规模,可以调整 vertexHandles 大小在你的场景。

FFD

这是最灵活的方法,因为它允许您以变形角色。以及动它的骨头。

若要创建 FFD,选择你的精灵并单击“CreateFFD Tool” .。你现在可以开始画在你的人物FFD。首先,你应该开始并条机的角色四周。之后,您可以添加任何内部的部件,如果你需要它。单击“Finish FFD”完成创建它并进行新的FFD Mesh。

Create FFD Tool – start creating FFDControls

Left Click – draw FFD Controls

Hold Shift or Ctrl – move selected FFDControl

Right Click – Close Current FFD loop andstart creating a new loop

Press Enter/Click “Finish FFD” - Finishescreating FFD

要获得FFD控件以动的骨头你可以parent他们,或者skin他们。(基本上你可以对待他们好像他们是一个网格。)

FFD Parenting

parent他们选择 FFD 控件和骨头,然后单击“ParentObject to bones”——FFD父母将父级的骨头。

FFD Skinning

要剥他们的皮,选择 FFD 控件和骨头,然后单击“BindSmooth Skin”。您也可以选择剥皮的值为 1 或 2 (不要使用 4(FFD),这需要另一个功能)。

Using the FFD on another Mesh

你也可以嵌入到同一 FFD 其他网格。做到这一点,您需要设置 Num 皮肤骨骼为 4(FFD)。请确保新的网格正好落在FFD。选择 FFD 控件和网格,然后单击“Bind Smooth Skin”。

必须要意识到,为了使这项工作上,你需要要创建与FFD可见原始网格。你应该把这周围为未来剥皮。

Animation:

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

【干货】Unity3d的2D骨骼动画插件Puppet2D的使用 - 无名 - 半月

要开始做动画只需在 global_Ctrl上创建动画剪辑,你可以移动/缩放旋转控件和在动画窗口中设置关键帧。

如果你想要通过移除所有的控制来优化动画脚本-你可以bakes到骨骼动画。

若 要bake动画与有你想要bake的动画 global_ctrls 打开了一个场景。单击bake动画------这将使你所有的动画与重复bake里面的Puppet2d>Animation>Baked文 件夹。这些将作为骨头而不是控件上的关键帧动画。您还将注意后,你这 Puppet2d 将禁用 globalCtrl 脚本。现在,您可以添加论文动画到您的动画控制器和他们可以替换所有控制动画。

你可以使用呈现动画和渲染的Alpha,使你的动画一个 png 序列。您可以使用 alpha 与composite的背景在外部编辑包中。

帮助动画你可以保存姿势并加载它们。

若要保存选择,选择在你的场景中的东西并单击“Save Selection”.。

要加载选择右键点击一个负载广场和悬停在“Select Objects”.

删除加载插槽右键单击并选择“Remove Selection”

添加到负载广场,选择您想要添加,然后选择"追加选择"

加载“Load Pose”一个姿势点击

要保存“Save Pose”一个姿势点击

TowerDefenseToolKit——前言

TowerDefenseToolKit(塔防插件)

_____Documentation & API Reference for Unity3D


Version: 2.1.3f3

Author: K.Song tan 

LastUpdated: 18st December 2012 

Forum: http://goo.gl/ZX4OA 

AssetStore: http://goo.gl/8vAFU 

感谢使用TDTK。这个工具包是一个集合的编码框架Unity3D的c#。此工具包旨在涵盖最常见的塔防游戏机制(“TD”)。记住TDTK不是一个框架来创建一个完整的游戏本身,而是,框架试图覆盖大多数(如果不是全部)的TD游戏力学。框架不包括其他游戏方面,如菜单场景,选择等。

工具箱设计自定义资产的集成。虽然有一些少量的模范的示范资产中包含的工具箱,用户将整合自己的音频和艺术资产。

TDTK应该兼容和性能友好的Unity3D的平台支持。请注意,这没有测试在Android平台。


对于一系列快速视频教程,请访问以下链接:

http://www.youtube.com/watch?v=xI-z6DCOt0w 

http://www.youtube.com/watch?v=tVcfI7Km2tY 

http://www.youtube.com/watch?v=39libqKnDvs 

之前的版本(1. x)的用户:

从TDTK1.x TDTK2不是一个更新。这是一个全新的和重新设计的框架。因此它不是向后兼容的。有一些关键的差异,例如整个构建配置被置于一个组件,不再使用“标签”,等等。但是你会发现,从以前版本的所有特性TDTK仍然可用。我相当有信心,你会发现这个版本比之前任何版本更好。


目录:

434898.png




C# using的三种使用方法

原文地址http://www.cnblogs.com/fashui/archive/2011/09/29/2195061.html,感谢心茶前辈的总结。

1.原文地址http://www.cnblogs.com/fashui/archive/2011/09/29/2195061.html,感谢心茶前辈的总结。1.using指令

using+命名空间,这种方法基本学习过C#的都用过,好处在于,写代码的时候不需要指定详细的命名空间

using System.Windows.Media; using System.Windows.Media.Imaging;

2.using语句

是用来简化资源释放的,在一定的范围内有效,除了这个范围时,自动调用IDisposable释放掉,当然并不是所有的类都适用,只有实现了IDisposable接口的类才可以使用

using (SqlConnection conn=new SqlConnection("Data Source=.;Initial Catalog=imageprocess;Integrated Security=True")) { conn.Open(); using(SqlCommand cmd=conn.CreateCommand()) { cmd.CommandText = "select count(*) from [user]"; int i = (int)cmd.ExecuteScalar(); MessageBox.Show(i.ToString()); }//这个括号结束的时候自动释放SqlCommand }//这个括号结束的时候自动释放SqlConnection

除了using可以达到这个目的意外,try catch也是可以的。

3.using别名

using+别名=包括详细命名空间信息的具体类型,这种做法有个好处就是当同一个cs引用了两个不同的命名空间,但两个命名空间都包括了一个相同名字的类型的时候。当需要用到这个类型的时候,就每个地方都要用详细命名空间的办法来区分这些相同名字的类型。而用别名的方法会更简洁,用到哪个类就给哪个类做别名声明就可以了。注意:并不是说两个名字重复,给其中一个用了别名,另外一个就不需要用别名了,如果两个都要使用,则两个都需要用using来定义别名的。

using System; using aClass = NameSpace1.MyClass; using bClass = NameSpace2.MyClass; namespace NameSpace1 { public class MyClass { public override string ToString() { return "You are in NameSpace1.MyClass"; } } } namespace NameSpace2 { class MyClass { public override string ToString() { return "You are in NameSpace2.MyClass"; } } } namespace testUsing { using NameSpace1; using NameSpace2; /// <summary> /// Class1 的摘要说明。 /// </summary> class Class1 { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { // // TODO: 在此处添加代码以启动应用程序 // aClass my1 = new aClass(); Console.WriteLine(my1); bClass my2 = new bClass(); Console.WriteLine(my2); Console.WriteLine("Press any key"); Console.Read(); } } }

至今第三种情况个人还没有用到过。指令

using+命名空间,这种方法基本学习过C#的都用过,好处在于,写代码的时候不需要指定详细的命名空间

using System.Windows.Media; using System.Windows.Media.Imaging;

2.using语句

是用来简化资源释放的,在一定的范围内有效,除了这个范围时,自动调用IDisposable释放掉,当然并不是所有的类都适用,只有实现了IDisposable接口的类才可以使用

using (SqlConnection conn=new SqlConnection("Data Source=.;Initial Catalog=imageprocess;Integrated Security=True")) { conn.Open(); using(SqlCommand cmd=conn.CreateCommand()) { cmd.CommandText = "select count(*) from [user]"; int i = (int)cmd.ExecuteScalar(); MessageBox.Show(i.ToString()); }//这个括号结束的时候自动释放SqlCommand }//这个括号结束的时候自动释放SqlConnection

除了using可以达到这个目的意外,try catch也是可以的。

3.using别名

using+别名=包括详细命名空间信息的具体类型,这种做法有个好处就是当同一个cs引用了两个不同的命名空间,但两个命名空间都包括了一个相同名字的类型的时候。当需要用到这个类型的时候,就每个地方都要用详细命名空间的办法来区分这些相同名字的类型。而用别名的方法会更简洁,用到哪个类就给哪个类做别名声明就可以了。注意:并不是说两个名字重复,给其中一个用了别名,另外一个就不需要用别名了,如果两个都要使用,则两个都需要用using来定义别名的。

using System; using aClass = NameSpace1.MyClass; using bClass = NameSpace2.MyClass; namespace NameSpace1 { public class MyClass { public override string ToString() { return "You are in NameSpace1.MyClass"; } } } namespace NameSpace2 { class MyClass { public override string ToString() { return "You are in NameSpace2.MyClass"; } } } namespace testUsing { using NameSpace1; using NameSpace2; /// <summary> /// Class1 的摘要说明。 /// </summary> class Class1 { /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main(string[] args) { // // TODO: 在此处添加代码以启动应用程序 // aClass my1 = new aClass(); Console.WriteLine(my1); bClass my2 = new bClass(); Console.WriteLine(my2); Console.WriteLine("Press any key"); Console.Read(); } } }

至今第三种情况个人还没有用到过。

Unity使用GPS 的API

Unity使用GPS 的API


在unity的官方文档中,与设备定位(GPS经纬度、水平精度等等)相关的API,目前我只找到两个:LocationService 和 LocationInfo 。

先来个简单的理解:

LocationService 负责启动和关闭定位服务。

LocationInfo  在服务启动后,获取定位数据信息。


LocationService

官方说明链接:

http://docs.unity3d.com/Documentation/ScriptReference/LocationService.Start.html

LocationService 中有三个属性,和两个方法:

(1)isEnabledByUser   -- 用户设置里的定位服务是否启用。(实测发现,都为true,似乎不大起作用)

(2)lastData   -- 最近一次测量的地理位置(LocationInfo lastData; 也就是要和 LocationInfo 关联了)

(3)status   -- 定位服务的状态。

定位服务的状态包括:

Stopped
Location service is stopped. 定位服务已经停止
Initializing
Location service is initializing, some time later it will switch to.  定位服务正在初始化,在一段时间后,状态会切换回来。
Running
Location service is running and locations could be queried.  位置服务正在运行,位置可以获取。
Failed
Location service failed (user denied access to location service).  位置服务失败(用户拒绝访问位置服务)。


(4)Start ( )   -- 启动定位服务,更新定位数据。可以获取最近更新的位置坐标。

     数据接收,是通过 Input.location.lastData 来实现的。服务不能马上获得定位数据。代码必须检查Input.location.status以获取当前的定位服务状态。

看一下函数定义:

void Start(float desiredAccuracyInMeters = 10f, float updateDistanceInMeters = 10f); 

参数详解:

desiredAccuracyInMeters  服务所需的精度,以米为单位。如果使用较高的值,比如500,那么通常不需要打开GPS芯片(比如可以利用信号基站进行三角定位),从而节省电池电量。像5-10这样的值,可以被用来获得最佳的精度。默认值是10米。

updateDistanceInMeters  最小距离(以米为单位)的设备必须横向移动前Input.location属性被更新。较高的值,如500意味着更少的开销。默认值是10米。


(5)Stop ( )  -- 停止定位服务的定位更新。这对节省电池的电量非常有用。void


LocationInfo

属性如下:

(1) altitude -- 海拔高度 

(2) horizontalAccuracy -- 水平精度 

(3) latitude -- 纬度 

(4) longitude -- 经度 

(5) timestamp -- 最近一次定位的时间戳,从1970开始 

(6) verticalAccuracy -- 垂直精度 


这些属性,除了timestamp为double外, 其余全为 float 型。



下面是Unity使用GPS 的例子

1,新建一个项目。

2,编写脚本 GetGPS.cs ,挂到主摄像机上。

[csharp] view plaincopy

  1. using UnityEngine;  
  2. using System.Collections;  
  3.   
  4. public class GetGPS : MonoBehaviour {  
  5.   
  6.     public string gps_info = "";  
  7.     public int flash_num = 1;  
  8.   
  9.     // Use this for initialization  
  10.     void Start () {  
  11.       
  12.     }  
  13.       
  14.     void OnGUI () {  
  15.         GUI.skin.label.fontSize = 28;  
  16.         GUI.Label(new Rect(20,20,600,48),this.gps_info);   
  17.         GUI.Label(new Rect(20,50,600,48),this.flash_num.ToString());   
  18.           
  19.         GUI.skin.button.fontSize = 50;  
  20.         if (GUI.Button(new Rect(Screen.width/2-110,200,220,85),"GPS定位"))  
  21.         {  
  22.             // 这里需要启动一个协同程序  
  23.             StartCoroutine(StartGPS());  
  24.         }  
  25.         if (GUI.Button(new Rect(Screen.width/2-110,500,220,85),"刷新GPS"))  
  26.         {  
  27.             this.gps_info = "N:" + Input.location.lastData.latitude + " E:"+Input.location.lastData.longitude;  
  28.             this.gps_info = this.gps_info + " Time:" + Input.location.lastData.timestamp;  
  29.             this.flash_num += 1;   
  30.         }  
  31.     }  
  32.   
  33.     // Input.location = LocationService  
  34.     // LocationService.lastData = LocationInfo   
  35.   
  36.     void StopGPS () {  
  37.         Input.location.Stop();  
  38.     }  
  39.   
  40.     IEnumerator StartGPS () {  
  41.         // Input.location 用于访问设备的位置属性(手持设备), 静态的LocationService位置  
  42.         // LocationService.isEnabledByUser 用户设置里的定位服务是否启用  
  43.         if (!Input.location.isEnabledByUser) {  
  44.             this.gps_info = "isEnabledByUser value is:"+Input.location.isEnabledByUser.ToString()+" Please turn on the GPS";   
  45.             return false;  
  46.         }  
  47.   
  48.         // LocationService.Start() 启动位置服务的更新,最后一个位置坐标会被使用  
  49.         Input.location.Start(10.0f, 10.0f);  
  50.   
  51.         int maxWait = 20;  
  52.         while (Input.location.status == LocationServiceStatus.Initializing && maxWait > 0) {  
  53.             // 暂停协同程序的执行(1秒)  
  54.             yield return new WaitForSeconds(1);  
  55.             maxWait--;  
  56.         }  
  57.   
  58.         if (maxWait < 1) {  
  59.             this.gps_info = "Init GPS service time out";  
  60.             return false;  
  61.         }  
  62.   
  63.         if (Input.location.status == LocationServiceStatus.Failed) {  
  64.             this.gps_info = "Unable to determine device location";  
  65.             return false;  
  66.         }   
  67.         else {  
  68.             this.gps_info = "N:" + Input.location.lastData.latitude + " E:"+Input.location.lastData.longitude;  
  69.             this.gps_info = this.gps_info + " Time:" + Input.location.lastData.timestamp;  
  70.             yield return new WaitForSeconds(100);  
  71.         }  
  72.     }  
  73. }  

3,导出到手机,运行,即可看到效果。

Xamarin.Android学习

Xamarin.Android快速入门
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_quickstart.html


Xamarin.Android多界面
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_multiscreen.html


Xamarin.Android活动的生命周期
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_lifecycle.html


Xamarin.Android下获取与解析JSON
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_get_and_parse_json.html


Xamarin.Android服务的实现
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_service.html


Xamarin.Android通知详解
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_notification.html


Xamarin.Android广播接收器与绑定服务
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_broadcastreceiver_and_bindservice.html


Xamarin.Android其他类型的服务
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_other_service.html


Xamarin.Android之ActionBar与菜单
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_actionbar_and_menu.html


Xamarin.Android之SQLiteOpenHelper
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_sqliteopenhelper.html


Xamarin.Android之使用百度地图起始篇
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_baidumap_quickstart.html


Xamarin.Android之ContentProvider
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_contentprovider.html


Xamarin.Android之SQLite.NET ORM
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_sqlite_net_orm.html


Xamarin.Android之ListView和Adapter
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_listview_adapter.html


Xamarin.Android学习之应用程序首选项
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_sharedpreference.html


Xamarin.Android之Fragment Walkthrough
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_fragment_walkthrough.html


Xamarin.Android之定位
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_location.html


Xamarin.Android之SlidingMenu
http://www.cnblogs.com/yaozhenfa/p/xamarin_android_slidingmenu.html


本人亲自发的,坚持不断更新!

Unity3d 与 iOS 的SDK交互

原地址:http://blog.csdn.net/zhao_yin/article/details/18401989

前言废话:开发手机游戏都知道,你要接入各种平台的SDK。那就需要Unity3d与iOS中Objective-C的函数有交互,所以你就需要用到如下内容:

 

一、Unity3d  To  iOS:

 

1、创建一个C#文件 SdkToIOS.cs 这是调用iOS函数的接口:

 

  1. public class SdkToIOS: MonoBehaviour  
  2. {  
  3.     //平台接入开关  
  4.     public static bool isOpenPlatform = false;  
  5.       
  6.     //导入定义到.m文件中的C函数  
  7.     [DllImport("__Internal")]  
  8.     private static extern void _PlatformInit();  
  9.       
  10.     //定义接口函数供游戏逻辑调用  
  11.      public static void InitSDK()  
  12.     {  
  13.         if (isOpenPlatform)  
  14.         {  
  15.             _PlatformInit();  
  16.         }  
  17.     }     
  18. }  

 

2、编写与接口对应的Objective-c函数:

 

 

  1. //  MyIOSSdk.h  
  2.   
  3.   
  4. #import <Foundation/Foundation.h>  
  5.   
  6. @interface MyIOSSdk : NSObject  
  7.   
  8. @end  

 

  1. //  MyIOSSdk.m  
  2.   
  3. #import "MyIOSSdk.h"  
  4.   
  5. //这里引用SDK的头文件  
  6. #import "SDKPlatform.h"  
  7.   
  8. #if defined(__cplusplus)  
  9. extern "C"{  
  10. #endif  
  11.     extern void UnitySendMessage(const charchar *, const charchar *, const charchar *);  
  12.     extern NSString* _CreateNSString (const char* string);  
  13. #if defined(__cplusplus)  
  14. }  
  15. #endif  
  16.   
  17. //*****************************************************************************  
  18.   
  19. @implementation MyIOSSdk  
  20.   
  21. //**********************  
  22. //message tools  
  23.   
  24. + (void)sendU3dMessage:(NSString *)messageName param:(NSDictionary *)dict  
  25. {  
  26.     NSString *param = @"";  
  27.     if ( nil != dict ) {  
  28.         for (NSString *key in dict)  
  29.         {  
  30.             if ([param length] == 0)  
  31.             {  
  32.                 param = [param stringByAppendingFormat:@"%@=%@", key, [dict valueForKey:key]];  
  33.             }  
  34.             else  
  35.             {  
  36.                 param = [param stringByAppendingFormat:@"&%@=%@", key, [dict valueForKey:key]];  
  37.             }  
  38.         }  
  39.     }  
  40.     UnitySendMessage("SDK_Object", [messageName UTF8String], [param UTF8String]);  
  41. }  
  42.   
  43. //**********************  
  44. //SDK fun  
  45.   
  46. //初始化SDK  
  47. -(void)SDKInit  
  48. {  
  49.     SDKcfg *cfg = [[[SDKcfg alloc] init] autorelease];  
  50.     cfg.appid =123456;  
  51.     cfg.appKey =@"aoaoaoaoaoaoaoaoaoaoaoaoaaoaoaoaoaoaoao";  
  52.     cfg.orientation = UIDeviceOrientationLandscapeLeft;  
  53.     //调用SDK的初始化函数  
  54.     [[SDKPlatform defaultPlatform] SDKInit:cfg];  
  55.     //添加回调监听  
  56.     [[SDKPlatform defaultPlatform] addObserver:self selector:@selector(SNSInitResult:) name:(NSString *)kInitNotification object:nil];  
  57. }  
  58.   
  59. //获取用户ID  
  60. -(NSString*)SDKGetUserID  
  61. {  
  62.     [[SDKPlatform defaultPlatform] SDKGetUserID];  
  63. }  
  64.   
  65. //**********************  
  66. //call back fun  
  67.   
  68. //初始化更新回调  
  69. - (void)SNSInitResult:(NSNotification *)notify  
  70. {  
  71.     [MyIOSSdk sendU3dMessage:@"SDKMsgInit" param:nil];  
  72. }  
  73.   
  74. @end  
  75.   
  76.   
  77. //*****************************************************************************  
  78.   
  79. #if defined(__cplusplus)  
  80. extern "C"{  
  81. #endif  
  82.       
  83.     //字符串转化的工具函数  
  84.       
  85.     NSString* _CreateNSString (const char* string)  
  86.     {  
  87.         if (string)  
  88.             return [NSString stringWithUTF8String: string];  
  89.         else  
  90.             return [NSString stringWithUTF8String: ""];  
  91.     }  
  92.       
  93.     char* _MakeStringCopy( const char* string)  
  94.     {  
  95.         if (NULL == string) {  
  96.             return NULL;  
  97.         }  
  98.         char* res = (char*)malloc(strlen(string)+1);  
  99.         strcpy(res, string);  
  100.         return res;  
  101.     }  
  102.       
  103.     static MyIOSSdk *mySDK;  
  104.   
  105.   
  106.     //供u3d调用的c函数  
  107.     
  108.     void _PlatformInit()  
  109.     {  
  110.         if(mySDK==NULL)  
  111.         {  
  112.             mySDK = [[MyIOSSdk alloc]init];  
  113.         }  
  114.         [lsSDK SDKInit];  
  115.     }  
  116.       
  117.     //注意这个函数是返回字符串  
  118.     const char* _PlatformGetUin()  
  119.     {  
  120.         if(lsSDK==NULL)  
  121.         {  
  122.             lsSDK = [[MyIOSSdk alloc]init];  
  123.         }  
  124.         return _MakeStringCopy([[lsSDK SDKGetUserID] UTF8String]);  
  125.     }  
  126.       
  127. #if defined(__cplusplus)  
  128. }  
  129. #endif  


值得一提的是在上面的代码中特意写了一个返回字符串的例子,因为你要获取用户ID 、昵称什么的。对应在cs文件中导入函数如下:

 

 

  1. [DllImport ("__Internal")]  
  2. private static extern string _PlatformGetUin();  

这里的const char* 会被C#自动转换成string因为在m文件中使用了内存申请,该段内存自然是处在堆内存中,这样转成string符合c#的内存管理机制,我们不用担心它的释放问题。

 

 

3、在你的工程目录中找个地方保存iOS的文件

打包出XCode工程后导入进去,加入你的SDK就可以了。

有一点需要说明,如果存放目录为\Assets\Plugins\iOS,那么Unity3d会自动将该目录下的所有文件(暂不支持子文件夹)当做插件文件打包到Xcode工程下的Libraries目录下,这样你就不需要在手动添加了,否则会报错重复声明什么的。

这种文件各个平台会有多个,可以使用同一头文件且定义的C函数名也都相同,这样更有利于多版本管理。

 

二、iOS To  Unity3d:

这个在上面的 MyIOSSdk.m 文件中已经有剧透了,就是利用unity3d 的UnitySendMessage函数,其中参数1是场景中接受消息的对象,参数2是要执行的函数名,参数3为传入参数,只要按照如下步骤就可以实现这个机制:

1、在场景中创建一个对象用于接受iOS消息,或者用现有的也可以;

2、为SDK消息写一个脚本,里面包含各种消息函数;

3、将脚本挂到之前创建的对象上完事;

需要注意:这个对象在场景切换时候要始终存在,或者你在每个场景中都加个这玩意也可以,总之只要能收到消息就行了;

另外,针对参数的传递对应上面的sendU3dMessage函数,我还在消息接受脚本中写过一个消息参数的解析:

 

  1. void ParseMsg(string msg, out Dictionary<string, string> dicMsg){  
  2.     if( null == msg || 0 == msg.Length ){  
  3.         dicMsg = null;  
  4.         return;  
  5.     }  
  6.     dicMsg = new Dictionary<string, string>();  
  7.     string[] msgArray = msg.Split('&');  
  8.     for( int i=0; i<msgArray.Length; i++){  
  9.         string[] elementArray = msgArray[i].Split('=');  
  10.         dicMsg.Add(elementArray[0],elementArray[1]);  
  11.     }  
  12. }  


这个我自己都还没有实际使用过,有错误自行解决大致是这样。

MenuItem 菜单项


Inherits from System.Attribute

The MenuItem attribute allows you to add menu items to the main menu and inspector context menus.

MenuItem属性允许你添加菜单项到主菜单和检视面板上下文菜单。

Note: This is an editor class. To use it you have to place your script in Assets/Editor inside your project folder. Editor classes are in the UnityEditor namespace so for C# scripts you need to add "using UnityEditor;" at the beginning of the script.
注意:这是一个编辑器类,如果想使用它你需要把它放到工程目录下的Assets/Editor文件夹下。编辑器类在UnityEditor命名空间下。所以当使用C#脚本时,你需要在脚本前面加上 "using UnityEditor"引用。

The MenuItem attribute turns any static function into a menu command. Only static functions can use the MenuItem attribute.

MenuItem属性把任意静态函数变成为一个菜单命令。仅静态函数能使用这个MenuItem属性。

To create a hotkey you can use the following special characters: % (ctrl on Windows, cmd on OS X), # (shift), & (alt), _ (no key modifiers). For example to create a menu with hotkey shift-alt-g use "GameObject/Do Something #&g". To create a menu with hotkey g and no key modifiers pressed use "GameObject/Do Something _g". A hotkey text must be preceded with a space character ("GameObject/Do_g" won't be interpreted as hotkey, while "GameObject/Do _g" will).

可以使用一下指定字符创建快捷键:% (Windows上为ctrl, OS X上为cmd), # (shift), & (alt), _ (无修改键)。例如创建一个菜单快捷键为shift-alt-g使用GameObject/Do Something #&g。创建一个菜单快捷键g并没有修改键(组合键),使用GameObject/Do Something _g。快捷键文本必须在前面加一个空格字符(GameObject/Do_g不会被解释为快捷键,而是GameObject/Do _g这样,注意_g前面有空格)。

你不可不知的Unity開發技巧


  1. Unity三種網頁發佈的方式:WebPlayer,Flash(效能低下),Chrome NaCl(Native C++,不需要Plugin)。
  2. Plugin的版本分别:Stable,Release,Beta,Alpha。可以修改网页码来指定plugin的下载版本与来源。
  3. Web缓存许可证(收费):“我们提供的统一Web播放器,可以在本地缓存的资产包的特殊扩展这是根据我们的业务开发团队取得了一项协议,授权一般是授权给开发者提供了较大的预期收益和。没有规模较小的基础“。
  4. 如何动态更新Unity产品的Source Code:透过将程式码输出为二维的TextAsset,然后在包装到AssetBundle中。
  5. Unity4已支援动态字型,nGUI2.6才支援动态字型(东亚字体)。(EZGUI目前就已支援-感谢永康ㄉㄉ堤供情报)
  6. GameObject.Destroy不会移除该物件的资源(Mesh,Texture,Material等)。
  7. Scaleform的仅支援Unity3.5.x
  8. 网路伺服器的清单:PhotonElectronSmartFoxuLinkSlimNetSlimIOCP
  9. NavMesh.Triangle()函式
  10. 王者之剑<蓝港在线>使用Unity开发的2D游戏。
  11. 开发2D游戏的插件:Sprite ManagerEx2D
  12. Unity Cache Server是开发团队用来在不同平台(资源)发布时的加速方式。
  13. Asset Server已不建議使用。
  14. 疾风,91都会自己开发对Unity的金流SDK。
  15. 透过设定优化发布的产品档案大小。
移动平台优化要点
  1. 每个动态物件(角色)的三角形面数在300到2000之间。
  2. 每个动态物件(角色)的Skinned Mesh Renderer仅用一个。
  3. 每个动态物件(角色)的材质数只用一个。
  4. 每个动态物件(角色)的骨架限制在30根以下。
  5. 使用Dynamic Batching合并那些杂类的动态物件。
  6. 静态物件设定为Static,方可进行Static Batching。
  7. 在3.5使用静态物件时移除Animation的组件。
  8. 地形(Terrain)的初始解析度設定為257以下。
  9. 地形(Terrain)筆刷貼圖數目控制在4以下。
  10. 贴图解析度大小控制在1024以下。
  11. 3D游戏开启Mipmap会增加记忆体但是可加速效能。
  12. 貼圖uv控制在0~1。
  13. 音乐档案使用ogg/mp3,短音效使用wav。
  14. 光源使用Light Map/Light Probe来取代动态光源。
  15. 使用方向光。
  16. Pixel Light控制在1~2。
  17. 控制摄影机的z-near与z-far平面。
  18. 设定物件的剔除距离。
  19. 小物件又很远得时候就不要画。
  20. 粒子系统将粒子总数控制在200以下。
  21. 粒子系统每个发射器发射粒子控制在50以下。
  22. 粒子的大小越小越好。
  23. 非常小的粒子去掉alpha channel。
  24. 不要开启粒子的碰撞。
  25. 碰撞類型不要使用Mesh Collider。
  26. 減少使用Animation組件。
  27. 不缩放的动画,去除Scale Curves的参数。
  28. 若只使用一个AnimationClip,就使用Unity 3.5的动画系统。
  29. 使用Macanim(Unity 4的動畫系統),要搭配使用Body Mask。
  30. IK選用Generic Mode。Humanoid Mode在Android上會耗費嚴重的效能。
  31. 渲染时减少使用Alpha测试与alpha混合。
  32. Draw Call Batching分为Static与Dynamic。后者点数控制在900下,若包含Position,Normal,UV,则是300。
  33. 使用Texture Packing将不同物件的材质变为相同,但必须手动修改UV。
  34. 使用遮挡剔除时谨慎设定谨慎设定封堵器(墙)与Occludee的角色。设定PVS只,PV和动态对象,自动生成门户(会改变的门)。
  35. 程式码,使用类别变数来暂存指标。
  36. 设定Fixed Delta Time在0.04到0.067之间。
  37. IOS发布时使用的快速和异常不支持的发布形式。
  38. Shader减少使用数学函式,减少使用Discard。Vertex使用Float,TextureUV使用Half,颜色与光使用Fixed。
  39. 在PowerVR的硬体下有时候使用两个Vec2反而会比较快。
  40. 使用Profiler。
  41. 使用Manager的架构来控制物件会比把每个物件都挂上脚本效率高。
资产包
  1. Resource这种读取资源的形态(有2G限制)会慢慢移除,统一改用Asset Bundle(可离线创造)
  2. Web缓存只能放资产包。
  3. Asset Bundle建出之后是有相容性的,ios与android的Asset Bundle与其他平台互不相容。
  4. BuildPipeline.BuildAssetBundle()是用来建立多个资产的资产包。
  5. BuildPipeline.BuildStreamedSceneAssetBundle()则是用来建立多个场景的资产包。
  6. BuildAssetBundleOptions.DeterministicAssetBundle来建立对资产的杂凑的ID做增量发布。
  7. 资产 assetBundleObj = WWW.AssetBundle->使用中的资产包。 新 捆绑可再进行加密动作。AssetBundle.Load() - >载入资产。
  8. 卸載流程: 
    GameObject.Destroy() AssetBundle.Unload (false)只會卸載WWW.AssetBundle,AssetBundle.Unload(true)則會卸載WWW.AssetBundle以及相關資源。true的作用相較於使用false再使用Resources.UnloadUnusedAssets ()作用並不相同。 把相同的資源基底打包為Asset捆绑 使用BuildPipeline.PushAssetDependencies()来建立资产包之间的关连性。
  9. 范例1:把共通资源打包。 
    Push 
    Build共通资源包 
    Push 
    Build物件包1 
    Pop 
    Push 
    Build物件包2 
    Pop 
    Pop
  10. 范例2:把Level所使用的资源也做成依赖形式。 
    Push 
    Build Level1 
    Push 
    Build Level2 (依赖于Level1) 
    Push 
    Build Level3 (依赖于Level2与Level2)
  11. 范例3:把场景包依赖于共通资源包
  12. 将设定各资源包依赖关系的XML设定为ScriptableObject并打包到Asset Bundle内
  13. 将场景切割为Asset Bundle的方式,等分,如切成九宫格。
  14. 将场景切割为Asset Bundle的方式,分大物件,中物件,小物件。让大物件先读入先显示。
  15. WWW.LoadFromCacheOrDownload()可设定版号。
  16. WWW.LoadFromCacheOrDownload的crc产生方式可透过错误使用同一个函式来产生真确值。
  17. 程式碼的加密過程:Assembly->Byte->TextAsset->加密->Asset Bundle->加密->TextAsset->Asset Bundle。
  18. 使用native dll来保护重要程式码,但Web应用不能使用dll。
统一着色器系统
  1. 透过Shader Name就会自动产生选择Shader的架构。
  2. SubShader可视为真正的Shader,由上而下执行。
  3. SubShader的Tag表示如何执行:可指定执行的顺序。
  4. SubShader的Tag表示如何表現。
  5. 著色方式Vertex Lit:快,限制多。
  6. 着色方式Forward:将灯光分为最重要+不重要以及其他重要。区分方式可手动,也可以依照强度与方向来自动决定。
  7. 着色方式Deferred:手机不能使用,也不支援透明。
  8. CG/HSSL会被转译为GLSL。
  9. 使用基本Shader会需要写132行的程式,使用Surface Shader来做隐藏简化:标明surfae code与light code。
  10. #pragma debug可以将隐藏的程式码显示在程式码中。
  11. 透过user define keyword将参数传入shader中。