Unity入门——脚本基础

脚本基本规则

  • 不在Vs中创建
  • 可以放在Assets文件夹的任何位置中(建议同一文件夹)
  • 类名和文件名必须一致,不然不能挂载
  • 建议不要使用中文名命名
  • 没有特殊要求不用管命名空间
  • 创建的脚本默认继承MonoBehavior

MonoBehavior基类:

  • 创建的脚本默认都继承了MonoBehavior,只有这样才能挂载在对象上
  • 继承MonoBehavior的脚本不能new只能挂
  • 继承了MonoBehavior的脚本不要去写构造函数,因为我们不会去new它,写构造函数没有意义
  • 继承了MonoBehavior的脚本可以在一个对象上挂多个脚本(如果没有加DisallowMultipleComponent特性)
  • 继承了MonoBehavior的类也可以再次被继承,遵循面向对象继承多态的规则

不继承MonoBehavior的类:

  • 不继承MonoBehavior的类不能挂载到GameObject上
  • 不继承MonoBehavior的类想怎么写就怎么写,如果要使用需要自己new
  • 不继承MonoBehavior的类一般是单例模式(用于管理模块)或者数据结构类(用于存储数据)
  • 不继承MonoBehavior的类不用保留默认出现的几个函数

可以在脚本的右上角设置execution order设置脚本执行的顺序

生命周期函数

了解帧

fps即为每秒钟的帧数
1s = 1000ms
60帧:1帧为1000 / 60 = 16.66ms
30帧:1帧为1000 / 30 = 33.33ms
人眼舒适放松时可视帧数为24帧

游戏卡顿的原因就是跑1帧的游戏逻辑的计算量过大,或者CPU不给力,不能在1帧的时间内处理完所有游戏逻辑

Unity的底层已经帮我们做好了死循环,所以我们不需要在脚本中写死循环

生命周期函数

所有继承MonoBehavior的脚本都会挂载到GameObject游戏对象上,生命周期函数就是该脚本对象依附的GameObject对象从出生到消亡的整个生命周期中会通过反射自动调节一些特殊函数
Unity帮助我们记录了一个GameObject对象依附了哪个脚本,会自动得到这些对象,通过反射执行一些固定名字的函数。

生命周期函数的访问修饰符一本都是private和protected,因为不用在外部自己调用一般都是Unity自己帮助我们调用

  • 1、Awake:出生时调用,类似构造函数,一个对象只会调用一次。(是类似构造函数的存在,可以在类刚被创造的时候进行一些初始操作)。
1
2
3
4
Debug.Log("Awake");  
Debug.LogError("oh no");
Debug.LogWarning("no");
print("Yali");
  • 2、OnEnable:依附的GameObject对象每次激活时调用(想要当一个对象被激活时,进行一些逻辑处理,就可以写在这个函数里)。
  • 3、Start:从自己被创造出来后,第一次帧更新之前调用一个对象只会调用一次(主要用于初始化信息,但是比Awake晚)
  • 4、FixedUpdate:物理帧更新,固定间隔时间执行,间隔时间可以设置(主要用于物理更新,它是每一帧执行,但是不是每一个游戏帧,使我们自己设置的帧,可以在Project Setting的Time中设置)
  • 5、Update:逻辑帧更新,每帧执行。(主要用于处理游戏核心逻辑更新的函数)
  • 6、LateUpdate:每帧执行,于Update后执行。(在Update和LateUpdate之间unity进行了一些处理,处理我们动画相关的更新)
  • 7、OnDisable:依附的GameObject对象每次失活时调用。
  • 8、OnDestroy:对象销毁时调用,衣服的GameObject被删除时调用。

生命周期函数支持继承多态

Inspector窗口可编辑变量

Inspector显示的可编辑变量就是脚本的成员变量

私有和保护变量无法被编辑,让私有和被保护的变量可以被编辑需要加上强制序列化字段特性:[SerializeField]。所谓序列化就是把一个对象保存到一个文件或数据库字段中去;方便我们进行变量的初始化。

公共变量可以显示编辑,在变量前加上[HideInInspector],就会无法显示编辑。

字典和一些自定义类型不能被显示编辑,同理在类名和自定义类型前面加上序列化特性就可以显示编辑。

分组说明特性Header:为成员分组

1
[Header("基础属性")]

悬停注释Tooltip:为变量添加说明

1
[Tooltip("闪避")]

间隔特性Space:让两个字段间出现间隔

1
[Space()]

修饰数值的滑条范围Range:可拖动变量

1
[Range(0,10)]

多行显示字符串,默认不写就是3行,写参数就是对应行数

1
[Multiline(n)];

滚动条显示字符串,默认不写参数就是超过3行显示滚动条,
最少显示3行,最多显示4行,超过4行就显示滚动条。

1
[TextArea(3,4)]

为变量添加快捷方法ContextMenuItem:参数一显示按钮名,参数二显示方法名

1
[ContextMenuItem("回复","Test")]

为方法添加特性能够在Inspector中执行

1
[ContextMenu("测试")]

Mono中的重要内容

重要成员

获取依附的GameObject

1
print(this.gameObject.name);

获取依附的GameObject的位置信息

1
2
3
print(this.transform.position);//位置
print(this.transform.eulerAngles);//角度
print(this.transform.lossyScale);//缩放大小

获取脚本是否激活

1
this.enabled = false;

重要方法

得到依附对象上挂载的其他脚本

得到自己挂载的单个脚本

1
2
3
4
5
6
//根据脚本名获取
xxx t = this.GetComponent("xxx") as xxx;//传想要获取的脚本的名字
//根据Type获取
xxx t = this.GetComponent(typeof(xxx)) as xxx;
//根据泛型获取,建议使用,因为不用二次转换
xxx t = this.GetComponent<xxx>();

得到自己挂载的多个脚本

1
xxx[] array = this.GetComponents<xxx>();

得到子对象挂载的脚本(默认会找自己身上是否挂在了该脚本)

1
2
xxx t = this.GetComponentInChildren<xxx>();
xxx[] array = this.GetComponentsInChildren<xxx>();

获取父对象挂载的脚本

1
2
xxx t = this.GetComponentInParent<xxx>();
xxx[] array = this.GetComponentsInParent<xxx>();

尝试获取脚本

1
2
3
4
5
xxx t
if(this.TryGetComponent<xxx>(out t))
{

}