标签:
关于这些技巧
流程
1、避免Assets分支
3、考虑使用外部的关卡编辑工具
4、考虑把关卡保存为XML,而非scene
5、考虑编写通用的自定义Inspector代码
场景组织6、使用命名的空Game Object来做场景目录
7、把控制对象和场景目录(空Game Objec)放在原点(0,0,0)
8、尽量减少使用GUI组件的offset
9、把世界的地面放在Y=0
10、使游戏可以从每个Scene启动
1
2
3
4
5
6
|
myObject = FindMyObjectInScene ( ) ; if ( myObjet = = null ) { myObject = SpawnMyObject ( ) ; } |
美术11、把角色和地面物体的中心点(Pivot)放在底部,不要放在中间
12、统一所有的模型的面朝向(Z轴正向或者反向)
13、在开始就把Scale搞正确
14、为GUI组件或者手动创建的粒子制作一个两个面的平面模型
15、制作并使用测试资源
Prefabs16、所有东西都使用Prefab
17、对于特例使用单独的Prefab,而不要使用特殊的实例对象
如果你有很多敌人的类型,那么也不要在编辑器中使用特殊的实例。一种可选的方案是程序化处理它们,或者为所有敌人使用一个核心的文件/Prefab。使用一个下拉列表来创建不同的敌人,或者根据敌人的位置、玩家的进度来计算。
18、在Prefab之间链接,而不要链接实例对象
19、如果可能,自动在实例对象之间产生链接关系
20、使用安全的流程来处理Prefab分支
不要把新复制的命名为Player_New,然后修改它。
扩展和MonoBehaviourBase21、扩展一个自己的Mono Behaviour基类,然后自己的所有组件都从它派生
22、为Invoke, StartCoroutine and Instantiate 定义安全调用方法
1
2
3
4
|
public void Invoke ( Task task , float time ) { Invoke ( task.Method.Name , time ) ; } |
23、为共享接口的组件扩展
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/ / Defined in the common base class for all mono behaviours public I GetInterfaceComponent < I > ( ) where I : class { return GetComponent ( typeof ( I ) ) as I; } public static List < I > FindObjectsOfInterface < I > ( ) where I : class { MonoBehaviour[] monoBehaviours = FindObjectsOfType < MonoBehaviour > ( ) ; List < I > list = new List < I > ( ) ; foreach ( MonoBehaviour behaviour in monoBehaviours ) { I component = behaviour.GetComponent ( typeof ( I ) ) as I; if ( component ! = null ) { list .Add ( component ) ; } } return list ; } |
24、使用扩展来让代码书写更便捷
01
02
03
04
05
06
07
08
09
10
11
|
public static class CSTransform { public static void SetX ( this Transform transform , float x ) { Vector 3 newPosition = new Vector 3 ( x , transform. position .y , transform. position .z ) ; transform. position = newPosition; } ... } |
25、使用防御性的GetComponent()
01
02
03
04
05
06
07
08
09
10
11
12
|
public static T GetSafeComponent < T > ( this GameObject obj ) where T : MonoBehaviour { T component = obj.GetComponent < T > ( ) ; if ( component = = null ) { Debug.LogError ( "Expected to find component of type " + typeof ( T ) + " but found none" , obj ) ; } return component; } |
风格26、避免对同一件事使用不同的处理风格
几组风格的例子:
时间27、维护一个自己的Time类,可以使游戏暂停更容易实现
生成对象28、不要让游戏运行时生成的对象搞乱场景层次结构
类设计29、使用单件(Singleton)模式
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
public class Singleton < T > : MonoBehaviour where T : MonoBehaviour { protected static T instance; / * * Returns the instance of this singleton. * / public static T Instance { get { if ( instance = = null ) { instance = ( T ) FindObjectOfType ( typeof ( T ) ) ; if ( instance = = null ) { Debug.LogError ( "An instance of " + typeof ( T ) + " is needed in the scene, but there is none." ) ; } } return instance; } } } |
30、在组件中不要使用public成员变量,除非它需要在inspector中调节
1
|
public float __aVariable; |
31、把界面和游戏逻辑分开
32、分离状态控制和簿记变量
实现方法之一是为每个游戏逻辑定义一个”SaveData“类,例如:
01
02
03
04
05
06
07
08
09
10
11
12
13
|
[Serializable] PlayerSaveData { public float health; / / public for serialisation , not exposed in inspector } Player { / / ... bookkeeping variables / / Don’t expose state in inspector. State is not tweakable. private PlayerSaveData playerSaveData; } |
33、分离特殊的配置
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
public class BaseTemplate { ... } public class ActorTemplate : BaseTemplate { ... } public class Entity < EntityTemplateType > where EntityTemplateType : BaseTemplate { EntityTemplateType template; ... } public class Actor : Entity < ActorTemplate > { ... } |
34、除了显示用的文本,不要使用字符串
35、避免使用public的数组
01
02
03
04
05
06
07
08
09
10
11
|
public void SelectWeapon ( int index ) { currentWeaponIndex = index ; Player.SwitchWeapon ( weapons[currentWeapon] ) ; } public void Shoot ( ) { Fire ( bullets[currentWeapon] ) ; FireParticles ( particles[currentWeapon] ) ; } |
1
2
3
4
5
6
|
public class Weapon { public GameObject prefab; public ParticleSystem particles; public Bullet bullet; } |
这样代码看起来很整洁,但是更重要的是,在Inspector中设置时就不容易犯错了。
36、在结构中避免使用数组
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
public void FireAttack ( ) { / / / behaviour Fire ( bullets[ 0 ] ) ; } public void IceAttack ( ) { / / / behaviour Fire ( bullets[ 1 ] ) ; } public void WindAttack ( ) { / / / behaviour Fire ( bullets[ 2 ] ) ; } |
使用枚举值可以让代码看起来更好一点:
1
2
3
4
5
|
public void WindAttack ( ) { / / / behaviour Fire ( bullets[WeaponType.Wind] ) ; } |
1
2
3
4
5
6
|
public class Bullets { public Bullet FireBullet; public Bullet IceBullet; public Bullet WindBullet; } |
这里假设没有其他的Fire、Ice、Wind的数据。
37、把数据组织到可序列化的类中,可以让inspector更整洁
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
public class MovementProperties / / Not a MonoBehaviour! { public float movementSpeed; public float turnSpeed = 1 ; / / default provided } public class HealthProperties / / Not a MonoBehaviour! { public float maxHealth; public float regenerationRate; } public class Player : MonoBehaviour { public MovementProperties movementProeprties; public HealthPorperties healthProeprties; } |
文本38、如果你有很多的剧情文本,那么把他们放到一个文件里面。
39、如果你计划实现本地化,那么把你的字符串分离到一个统一的位置。
测试与调试40、实现一个图形化的Log用来调试物理、动画和AI。
41、实现一个HTML的Log。
42、实现一个你自己的帧速率计算器。
43、实现一个截屏的快捷键。
44、实现一个打印玩家坐标的快捷键。
45、实现一些Debug选项,用来方便测试。
46、为每一个足够小的团队,创建一个适合他们的Debug选项的Prefab。
47、维护一个包含所有游戏元素的场景。
48、定义一些Debug快捷键常量,并把他们保存在统一的地方。
文档
命名规则和目录结构50、遵从一个命名规范和目录结构,并建立文档
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
Materials GUI Effects Meshes Actors DarkVampire LightVampire ... Structures Buildings ... Props Plants ... ... Plugins Prefabs Actors Items ... Resources Actors Items ... Scenes GUI Levels TestScenes Scripts Textures GUI Effects ... |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
Cameras Dynamic Objects Gameplay Actors Items ... GUI HUD PauseMenu ... Management Lights World Ground Props Structure ... |
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
ThirdParty ... MyGenericScripts Debug Extensions Framework Graphics IO Math ... MyGameScripts Debug Gameplay Actors Items ... Framework Graphics GUI ... |
标签:
原文地址:http://www.cnblogs.com/harlan1009/p/4206523.html