Unity项目开发中C#使用小技巧

内容会持续更新,有错误的地方欢迎指正,谢谢!

本文是博主在用Unity开发游戏时的小技巧总结,以防忘记。

1.C#属性的作用:其实,和public差不多,但是,如果需要对某个private字段(比如:age)有什么限制啥的,就很有用了:在set中,先判断age是否符合要求,符合要求再赋值。如果开发到后面,需要你去修改age的可取值的范围,这时,你外部用到这个age的地方都不需要改动,只需要修改这个属性操作即可。在绝大多数情况下,还是使用属性好,即使仅仅是一个简单的值,说不定哪天就需要你或别人去维护了!如此看来,属性主要就是用于封装,以便于今后的扩展,多用属性!

那么字段和属性有啥关系?
字段:字段是类内部用的,private类型的变量。一般的字段都是设为私有的,字段的访问便是由属性来实现。
属性中包含两个块:set和get,set块负责属性的写入工作,get块负责属性的读取工作。在两个块中都可以做一些其他操作,如在set中验证赋的值是否符合要求并决定是否进行赋值。

所以,属性的作用:

  1. 能满足字段只能读或只能写或读写都行;
  2. 需要限定字段的取值范围;
  3. 在改变一个字段的值时,希望改变对象的其它一些状态。
//私有字段和属性的例子:
pulic class User  
{  
    private string _name;//_name为字段  
    public string Name   //Name为属性,它含有代码块  
     {  
       get  
       {  
          return _name;//读取(返回_name值)  
        }  
       set   
       {  
          _name = value;//为_name赋值  
        }  
}  

所以,属性和字段算是C#中的基础知识,掌握好基础知识,建造的高楼大厦才更好的扎实稳固。

2.索引器的作用:格式:类或结构体的对象名[ ]。可以像访问数组一样,去访问类或结构体里面的数组或集合。经常结合泛型集合List和foreach一起使用,可以实现:输入 按钮类型,返回按钮的预制体 等类似的功能,多用索引器!例子如下:

[System.Serializable]
public class PrefabsOfColor
{
        public GameObject prefab;
        public ColorList.ColorStyle color;
}

public List list;
public GameObject this[ColorList.ColorStyle index]
{
        get
        {
                foreach(PrefabsOfColor poc in list)
                {
                    if(poc.color==index)
                        return poc.prefab;
                }
                return null;
        }
        set
        {
                foreach(PrefabsOfColor poc in list)
                {
                    if(poc.color==index)
                        poc.prefab=value;
                }
        }
}

3.如果按钮在运行时,才会生成(在场景中实例化出来),也就是俗话说的对象池概念,那么怎么绑定Onclick的事件呢?当然是按钮的动态监听呐,button.onClick.AddListener() 只能绑定没有参数的函数,或者使用匿名委托:

m_btn_try.onClick.AddListener(OnButRetry); 

若要使用匿名委托,这句应改成:

m_btn_try.onClick.AddListener(delegate(){
OnButRetry(m_btn_try.gameObject);
});

4.SubString()的作用:截取字符串中的一部分
string res = stringTemp.SubString(int index,int length)
index:开始下标,从0开始计数
length:你要取的子字符串的长度

5.若把对象当作参数进行传递,那么传递的就是对象的引用(同一个对象的别名),在函数体内对该对象进行的修改,都会影响函数体外的对象。

6.C#中类为什么要实例化?
类是一个抽象体,是对一类事物的抽象,而对象是一个具体的事物。
在使用类的静态方法或属性时,不需要将该类实例化;在使用类的非静态方法或属性时,需要将该类实例化。

7.如何将自定义的类中的元素显示在Inspector面板上:用[System.Serializable] :

[System.Serializable]
public class MyClass
{
    public int val;
    public string str;
}

再在继承自MonoBehaviour的类中实例化该类:

public MyClass myClass;

8.为什么Inspector视图中脚本前面的勾选框没了?
Unity项目开发中C#使用小技巧_第1张图片

凡事脚本没有勾选项的,都是因为你的脚本没有Start、Update、LateUpdate、FixedUpdate、OnGUI 也都可以让勾选框出来。。。但是Awake不行。

9.Unity对象池是什么?
将对象存储在一个池子中,也就是用完之后不要Destroy,而应把对象隐藏起来SetActive(false),当需要再次使用时取出,而不需要每次都实例化一个新的对象,将对象循环利用起来。就不需要重复执行很多次Instantiate和Destroy方法。
第一次创建的时候就将对象存储在一个池子中,当需要销毁的时候不直接销毁而是隐藏,当需要再次使用时,就不需要再次实例化一个新的对象,直接把隐藏的对象显示出来并直接用。如果对象池中已经被隐藏的物体太久没有被重新使用,应该被真正的销毁。

10.Unity3D GUI按钮的使用方法:

    void OnGUI()
    {
        // 文本
        GUI.Label (new Rect (50, 200, 200, 50), info);

        // 按钮
        GUI.color = Color.yellow;  //按钮文字颜色  
        GUI.backgroundColor = Color.red; //按钮背景颜色
    }

11.读取本地txt文件,将文件中的数据转化为string

TextAsset textAsset = Resources.Load("4-1") as TextAsset;
if (textAsset == null)
    return;
string s = textAsset.text;

12.写入数据到本地文件:需要导入System.IO。

StreamWriter sw;
FileInfo fi = new FileInfo("Assets/Resources/4-1.txt");
if(!fi.Exists)//不存在该文件就新建一个
{
    sw = fi.CreateText();
}
else//存在该文件就把新增的字符串添加到文件框中文本的后面
{
    sw = fi.AppendText();
}
sw.WriteLine ("123string");//写什么内容
sw.Close();

13.以下是不常用的但面试问到过的知识点:

1.强引用与弱引用:当一个对象不再有strong类型的指针指向它的时候,它就会被释放,即使该对象还有_weak类型的指针指向它,此时会清除掉所有剩余的weak指针。
2.有三种放在形参处的关键词,前两种经常用,最后一种我没用过,它是用于传递数组型参数的。
按引用传递参数:ref
输出参数:out
参数数组:params//params的应用:public static int Plus(params int[] values){}
3.C#显示资源释放的方法:Dispose、Close(Close方法调用了Dispose方法)、析构方法(析构方法只能由垃圾回收机制进行调用的)
4.什么是语法糖:就相当于汉语里的成语。用更简练的言语来表达较复杂的含义,能提高编码效率也更容易理解。例如:经过两次变异的委托写法:

class MyClass
{
    public delegate void DoSomething(int a);

    //定义方法委托
    private void DoIt(int a) {
        Console.WriteLine(a);
    }

    private void HowtoDo(DoSomething doMethod,int a) {
        doMethod(a);
    }

    public static void Main(string[] args) {
        MyClass mc = new MyClass();
        //调用定义的方法委托
        mc.HowtoDo(new DoSomething(mc.DoIt), 10);
        int x = 10;
        //使用匿名委托
        mc.HowtoDo(delegate(int a){
            Console.WriteLine(a + x);
        },10);
        //使用lamda表达式
        mc.HowtoDo(a=>Console.WriteLine(a+x),10);
        Console.ReadLine();
    }
}

5.C# const与readonly 关键字的比较
相同点:const 与 readonly 定义的数据成员在初始化后都不能被改变。
不同点:

  1. 定义为const的数据成员,隐式包含了static的含义,而定义为readonly的数据成员没有包含static的含义,比如可以在类级别直接调用const字段,而不能直接调用readonly字段。
  2. const成员在定义时必须初始化,不能通过构造函数为其初始化。也即是说const成员的值必须的编译时就知道,而不能在运行时赋值;而readonly的成员,如果在定义时没有初始化,那么可以在构造函数中进行初始化。

你可能感兴趣的:(Unity,C#,Unity,C#)