前言
Unity 引擎使用C#语言作为脚本语言,所以在学习Unity之前应该先了解C#的基本语法,如果你是老道的java或者C++程序员,那么相信你大致了解一下C#的语言,就可以达到基本可使用的状态了。
Unity虽然提供了相当多的游戏组件供用户使用,但是要开发一个完整的游戏,仅仅使用组件又是不够的。
游戏脚本可以触发游戏事件,随时修改组件的属性,并以所需的任何方式响应用户的输入。
创建最简单的C#脚本
在资源窗口右键,create-> C# scrite 可以直接创建一个脚本。也可以通过从主菜单选择 Assets > Create > C# Script 来新建脚本。
比如创建一个FirstScrite的脚本,脚本中会自动生成这样的代码。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class FirstScript : MonoBehaviour { // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } }
脚本中会实现一个继承于MoniBehaviour的,与文件名相同的类。
类中会实现两个函数,这两个函数会在脚本声明周期里被自动调用
- start() 类被初始化时调用,可以在函数中初始化类中的成员变量。
- update() 在游戏的每一帧更新前会被调用。
将脚本附加到游戏对象
拿精灵对象举例,精灵的Inspector Window 中有一个 Add Component 的选项,点击之后选择Script就可以看到新建的脚本。
当然也可以直接将脚本拖拽致Inspector Window中。
当然,因为脚本里什么都没有,所以运行时不会看到跟之前有什么区别。
可以在脚本中添加一段改变精灵位置的代码,看一下精灵在场景中的反应。
void Update() { int speed = 2; Vector3 endPos = transform.position + Vector3.left * speed; transform.position = Vector3.Lerp(transform.position, endPos, Time.deltaTime); }
这段代码写到Update()中,游戏每一帧更新前都会被调用。代码的功能是线性的改变精灵的位置,每一秒的速度是2。
需要注意的是,将脚本附加到游戏对象时,脚本文件名必须与类名一致,如果文件中有多个类,也只会附加与脚本名称相同的类。
Inspector Window
C# 的public 成员都会被显示到Inspector Window中,可以在Inspector Window中编辑这些成员的值,十分方便。如果不想public 成员被显示到Inspector Window,需要额外配置属性,下文会关于特性会详细介绍。
比如上文的脚本中,将speed 声明为一个public 成员。
public int speed = 2;
在Inspector Window中就可以看到Speed 这个变量,甚至可以修改它的值,修改了之后,精灵移动的速度也会跟着改变。
细看会发现 Inspector Window中的变量似乎跟脚本中的有点不一样,是的s被改成了大写。
这是因为在显示名称时有一套固定的规则来处理变量名,具体如下:
- 删除变量名开头的”m_“
- Removes “k” from the beginning 官方文档是这么写的,我理解的是删除变量名开头的k字母,但是经过测试好像不是这样的,我也搞不懂。
- 删除变量名开头的“_”
- 首字母改为大写
- 在小写字母和大写字母之间添加空格
- 如果是连续的大写字母,会在最后的两个大写字母之间增加空格(其实就是分割简写词)
来测试一下,为脚本添加这些public成员:
public int m_name_m; public int _name_; public int nameAmiao; public int GKDName;
MonoBehaviour 类
MonoBehaviour 类是一个基类,所有 Unity 脚本都默认派生自该类。从 Unity 的项目窗口创建一个 C# 脚本时,它会自动继承 MonoBehaviour,并实现Start()和Update函数。
继承它的是为了连接到Unity的架构,可以将它视作一个蓝图,用于创建可富家到游戏的对象的新组件类型。是的,如果你想你的脚本可以附加到游戏对象,那么继承Monibehaviour是必须的。
事件函数
除了Start() 和Update()之外,MonoBechaviour还有许多其他的事件函数。
Awake | Awake 在加载脚本实例时调用。 |
---|---|
FixedUpdate | 用于物理计算且独立于帧率的 MonoBehaviour.FixedUpdate 消息。 |
LateUpdate | 如果启用了 Behaviour,则每帧调用 LateUpdate。 |
OnAnimatorIK | 用于设置动画 IK(反向运动学)的回调。 |
OnAnimatorMove | 用于处理动画移动以修改根运动的回调。 |
OnApplicationFocus | 当玩家获得或失去焦点时,发送给所有 GameObject。 |
OnApplicationPause | 当应用程序暂停时,发送给所有 GameObject。 |
OnApplicationQuit | Sent to all GameObjects before the application quits. |
OnAudioFilterRead | 如果实现了 OnAudioFilterRead,Unity 将在音频 DSP 链中插入一个自定义滤波器。 |
OnBecameInvisible | OnBecameInvisible 在渲染器对任何摄像机都不可见时调用。 |
OnBecameVisible | OnBecameVisible 在渲染器变为对任意摄像机可见时调用。 |
OnCollisionEnter | 当该碰撞体/刚体已开始接触另一个刚体/碰撞体时,调用 OnCollisionEnter。 |
OnCollisionEnter2D | 当传入碰撞体与该对象的碰撞体接触时发送(仅限 2D 物理)。 |
OnCollisionExit | 当该碰撞体/刚体已停止接触另一个刚体/碰撞体时,调用 OnCollisionExit。 |
OnCollisionExit2D | 当另一个对象上的碰撞体停止接触该对象的碰撞体时发送(仅限 2D 物理)。 |
OnCollisionStay | OnCollisionStay is called once per frame for every Collider or Rigidbody that touches another Collider or Rigidbody. |
OnCollisionStay2D | 在另一个对象上的碰撞体正在接触该对象的碰撞体时发送每个帧(仅限 2D 物理)。 |
OnConnectedToServer | 成功连接到服务器后在客户端上调用。 |
OnControllerColliderHit | 当该控制器在执行 Move 时撞到碰撞体时调用 OnControllerColliderHit。 |
OnDestroy | 销毁附加的行为将导致游戏或场景收到 OnDestroy。 |
OnDisable | 该函数在行为被禁用时调用。 |
OnDisconnectedFromServer | 当连接丢失或与服务器断开连接时,在客户端上调用。 |
OnDrawGizmos | 如果您想绘制能够选择并且始终绘制的辅助图标,则可以实现 OnDrawGizmos。 |
OnDrawGizmosSelected | 如果选择了对象,则实现 OnDrawGizmosSelected 来绘制辅助图标。 |
OnEnable | 该函数在对象变为启用和激活状态时调用。 |
OnFailedToConnect | 出于某种原因连接尝试失败时,在客户端上调用。 |
OnFailedToConnectToMasterServer | 在连接到 MasterServer 时发生问题的情况下,在客户端或服务器上调用。 |
OnGUI | 系统调用 OnGUI 来渲染和处理 GUI 事件。 |
OnJointBreak | 在附加到相同游戏对象的关节断开时调用。 |
OnJointBreak2D | 在附加到相同游戏对象的 Joint2D 断开时调用。 |
OnMasterServerEvent | 在从 MasterServer 报告事件时,在客户端或服务器上调用。 |
OnMouseDown | 当用户在 Collider 上按下鼠标按钮时,将调用 OnMouseDown。 |
OnMouseDrag | 当用户单击 Collider 并仍然按住鼠标时,将调用 OnMouseDrag。 |
OnMouseEnter | 当鼠标进入 Collider 时调用。 |
OnMouseExit | 当鼠标不再处于 Collider 上方时调用。 |
OnMouseOver | 当鼠标悬停在 Collider 上时,每帧调用一次。 |
OnMouseUp | 当用户松开鼠标按钮时,将调用 OnMouseUp。 |
OnMouseUpAsButton | 松开鼠标时,仅当鼠标在按下时所在的 Collider 上时,才调用 OnMouseUpAsButton。 |
OnNetworkInstantiate | 在已通过 Network.Instantiate 进行网络实例化的对象上调用。 |
OnParticleCollision | 当粒子击中碰撞体时,将调用 OnParticleCollision。 |
OnParticleSystemStopped | 系统中的所有粒子都死亡时,便会调用 OnParticleSystemStopped,然后将不再产生新粒子。在调用 Stop 之后,或者超过非循环系统的 Duration 属性时,将停止产生新粒子。 |
OnParticleTrigger | 粒子系统中的任何粒子满足触发模块中的条件时,将调用 OnParticleTrigger。 |
OnParticleUpdateJobScheduled | 调度粒子系统的内置更新作业时,会调用 OnParticleUpdateJobScheduled。 |
OnPlayerConnected | 每当有新玩家成功连接,就在服务器上调用。 |
OnPlayerDisconnected | 每当有玩家与服务器断开连接,就在服务器上调用。 |
OnPostRender | Event function that Unity calls after a Camera renders the scene. |
OnPreCull | Event function that Unity calls before a Camera culls the scene. |
OnPreRender | Event function that Unity calls before a Camera renders the scene. |
OnRenderImage | Event function that Unity calls after a Camera has finished rendering, that allows you to modify the Camera's final image. |
OnRenderObject | 在摄像机渲染场景后,将调用 OnRenderObject。 |
OnSerializeNetworkView | 用于在网络视图监视的脚本中自定义变量同步。 |
OnServerInitialized | 每当调用 Network.InitializeServer 并且完成时,对该服务器调用该函数。 |
OnTransformChildrenChanged | 当 GameObject 的变换的子项列表发生更改时,将调用该函数。 |
OnTransformParentChanged | This function is called when a direct or indirect parent of the transform of the GameObject has changed. |
OnTriggerEnter | GameObject 与另一个 GameObject 碰撞时,Unity 会调用 OnTriggerEnter。 |
OnTriggerEnter2D | 当另一个对象进入附加到该对象的触发碰撞体时发送(仅限 2D 物理)。 |
OnTriggerExit | 当 Collider other 已停止接触该触发器时调用 OnTriggerExit。 |
OnTriggerExit2D | 当另一个对象离开附加到该对象的触发碰撞体时发送(仅限 2D 物理)。 |
OnTriggerStay | 对于接触触发器的每一个 Collider /other/,每次物理更新调用一次 OnTriggerStay。 |
OnTriggerStay2D | 在另一个对象位于附加到该对象的触发碰撞体之内时发送每个帧(仅限 2D 物理)。 |
OnValidate | Editor-only function that Unity calls when the script is loaded or a value changes in the Inspector. |
OnWillRenderObject | 如果对象可见并且不是 UI 元素,则为每个摄像机调用 OnWillRenderObject。 |
Reset | 重置为默认值。 |
Start | 在首次调用任何 Update 方法之前启用脚本时,在帧上调用 Start。 |
Update | 如果启用了 MonoBehaviour,则每帧调用 Update。 |
来自Unity官方文档,更详细的介绍可以自行前去查看。
特别注意
- 继承MonoBegaviour的类初始化成员变量时,一定要在start()函数中进行。因为脚本的调用依托于Unity框架,所以类在实例化时也是由框架完成的。Unity在生成对象时做了一些特殊的操作,所以非常不建议为类实现构造函数,会对框架造成很大的影响。
- 忘了,记起来再补。。。。。。。。。。。
特性(Attribute)
在成员变量或者函数上可以添加一些特殊行为的标记。
[HideInInspector] public int speed = 2;
[HideInInspector] 是表示下方的变量不会显示到Inspector Window中。
所以这段代码加到之前的脚本中之后,Inspector Window中就不会显示speed变量了。
Unity 提供了许多特性,详情参阅文档:
- 对于 UnityEngine 特性,请参阅 AddComponentMenu 和同级页面
- 对于 UnityEditor 特性,请参阅 CallbackOrderAttribute 和同级页面
文章评论