首先要道歉。
非常抱歉,本来答应前几天回复,不过最近每天真是太忙了,计划表中每天都要实现一个功能,所以直到今天早上才查看并修改。
代码功能先放在一边,首先有几个问题要说明。
1.代码不可运行。
不知道是不是Unity版本不对,
或是什么别的原因,
代码拷进来之后根本无法运行,
提示错误连篇。
于是我开始大幅度修改,
直到成功运行。
不过版本问题先放在一边,
话说发过来的版本中Init方法中的Window都没有调用Show方法,
不知道原本是如何运行的。
2.在半个小时的修改过程中,
我主要做了以下几件事:
-----------------------------
①.重命名变量。
比如说那个map_a,
非局部变量应使用骆驼峰式命名。
②.抽取方法。
当看到OnGUI中格式代码(StartHorizontal)和功能代码混在一起,
一个方法就有三四十行的时候,
我有些失去耐心了。
提取方法我使用了以下几种方法:
(1).删除重复代码。比如说那个DestroyImmediately,提取成了assertNull,
还顺便取消原来的"gobj"变量。
(2)化繁为简。比如说我将两个Button的功能提取为两个方法,简明扼要。
(3)便于理解。将长代码拆分成不同的功能部分,一来简化代码,其次将不同的
功能区域区分开,便于阅读。
③.减少花括号数目。
这一点你在编程时也能感受到,
当五六七八个花括号叠在一起时,
无论是阅读还是欣赏都毫无意义。
如果你之前习惯Java或是Android编程,
那我要提醒一句,
在Unity或是C#中,
这么玩可不行。
双重for循环无法精简,那就将里面的if和else拆分开就可以了。
使用continue或是break什么的代替,
很容易就能减少花括号的数量。
④.减少临时变量数目。
obj和gobj的命名问题先放在一边,
但这两个临时变量多次出现在不同方法,
这一点就足以证明程序不够精简,
运行起来也会毫无疑问效率较低。
尽最大可能减少临时变量的出现,
尤其是重复出现时,
就该思考是否有什么方法可以弥补这一点。
⑤.取消多余行数/添加符号空格。
这一点如果你之前习惯使用成熟的编译器可能无法体会,
但在脚本编程中,
符号是否有空格就决定了其旁边的变量名是否可以被搜索到,
也就决定了是否可以使用Ctrl + H来重命名。
要知道脚本语言大部分无法被Refactor。
成千上万行的脚本,如果无法使用Ctrl+H来重命名,
那修改代码的效率自然可以想象。
至于行数的作用,
最主要的就是分隔功能块。
如果这一点无法保证,
那代码注释再多也无济于事。
⑥.添加/取消注释。
之前你跟我说我的代码的注释太少,
我承认这一点。
在一个人编程的时候,
我并不太过在意注释问题,
因为我崇尚一条真理:
——最好的注释就是没有注释。
为什么?
因为将所有注释应该写明的东西,
用完整的命名,有条理的顺序,以及规范的格式就可以表现。
脱离这一点,
试图使用注释来弥补其他方面的弊端,
那自然是欲盖弥彰。
除此之外,
代码中尽量不要出现中文,
这也是成熟团队的一个默认标准。
-----------------------------
这只是一个检验,
我并不只是想看看应试者是否能够"实现"什么东西,
更重要的是希望看到你们如何来"实现"。
你们每个人并不是对Unity都非常了解,
正因如此,
类似as关键词的使用或是接口选择之类的问题我并未列在上述表单之中。
但编程能体现的是一个编程者对于程序的理解,
以及他的经验。
功能在我看来是最简单不过的东西,
一个功能,研究一天,一星期或是一个月一年总该有结果,
但实现的过程,
却并非一朝一夕可以完善的。
团队编程最重要的就是相互之间的默契,
而代码,就是程序员之间的交流语言,
一注释一空格之间就足以表明诸多要素。
我自己热爱编程,
每次编程都能够乐在其中,甚至大多数情况都无法自拔。
因为我将编程的过程看作是写诗,
如何去构造,如何去描述,如何选词酌句,
都是需要大量的实践与思考才能至善至美的。
在这个过程中,
我可以很明显地可以感受到沉浸其中所带来的快乐的。
抛开这一点不提,
程序员最讨厌的莫过于Bug。
而绝大多数的Bug并非在于逻辑错误,
而是在于编程规范。
如何减少Bug,
也是编程水平提升的重要一步。
至此,
再次为我迟到的回复致以歉意。
并推荐几本书,供你日后编程作为参考:
《Clean Code》
《Refactoring To Patterns》
《敏捷编程系列》
更改后代码:
using UnityEngine;
using UnityEditor;
using System.Collections;
public class MapGenerator: EditorWindow
{
/// <summary>
/// The height of the meta prefab.
/// </summary>
int prefabHeight = 1;
int prefabWidth = 1;
const int horizontalNumber = 8;
const int verticalNumber = 8;
/// <summary>
/// The map array.
/// </summary>
public Object[,] mapArray = new Object[verticalNumber,horizontalNumber];
[MenuItem ("MyTools/MapGenerator")]
static void Init ()
{
MapGenerator window = (MapGenerator)EditorWindow.GetWindow(typeof (MapGenerator));
window.Show();
}
void OnGUI ()
{
// setting of prefab
GUILayout.Label ("Basic Settings", EditorStyles.boldLabel);
prefabHeight = EditorGUILayout.IntField ("PrefabHeight:",prefabHeight);
prefabWidth = EditorGUILayout.IntField ("PrefabWidth:",prefabWidth);
EditorGUILayout.Space();
// the area of map editor
GUILayout.Label ("MapEditor", EditorStyles.boldLabel);
for(int j = 0;j < horizontalNumber;j++)
{
EditorGUILayout.BeginHorizontal();
for(int i = 0;i < verticalNumber;i++)
mapArray[i,j] = EditorGUILayout.ObjectField(mapArray[i,j],typeof(Object), true);
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.Space();
// the area of button
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Create"))
Create();
if (GUILayout.Button("Reset"))
Reset();
EditorGUILayout.EndHorizontal();
}
private void Create()
{
for(int j = 0;j < horizontalNumber;j++)
{
for(int i = 0;i < verticalNumber;i++)
{
if(null == mapArray[i,j])
continue;
assertNull(GameObject.Find("Tile" + j + i));
Vector3 pVector = new Vector3(i*prefabWidth, (horizontalNumber-j)*prefabHeight, 0);
generateObject(pVector,j,i);
}
}
}
private void Reset()
{
prefabWidth = 1;
prefabHeight = 1;
for(int j = 0;j < horizontalNumber;j++)
{
for(int i = 0;i < verticalNumber;i++)
{
if(null == mapArray[i,j])
continue;
assertNull(GameObject.Find("Tile" + j + i));
mapArray[i,j] = null;
}
}
}
/// <summary>
/// Generate object and assign some properties
/// </summary>
/// <param name='pos'>
/// Generate position.
/// </param>
/// <param name='h'>
/// Index of height
/// </param>
/// <param name='w'>
/// Index of weight.
/// </param>
protected void generateObject(Vector3 pos,int h,int w)
{
Object obj = Instantiate(mapArray[h,w],pos, Quaternion.identity);
obj.name = "Tile" + h + w;
(obj as GameObject).transform.localScale = new Vector3(prefabWidth,prefabHeight,1);
}
/// <summary>
/// Asserts the gameObject is null.
/// </summary>
/// <param name='gameObject'>
/// Game object.
/// </param>
protected void assertNull(GameObject gameObject)
{
if(gameObject)
DestroyImmediate(gameObject);
}
}
By Elezor 2013.8.24

浙公网安备 33010602011771号