目录
-
一、 基础知识
-
1. 定义
- 附加在游戏物体上用于定义游戏对象行为的指令代码
- 脚本就是一个类,向物体一挂就是创建一个对象
-
2. 要求
- 使用命名空间
- 附加到游戏物体的脚本类必须从MonoBehaciour类继承
- 文件名必须和类名一致
- 写好的脚本必须附加到物体才能运行
-
3. 编译运行过程
- 源代码-(CLS)->中间语言--(Mono Runtime)->机器码
-
4. 小知识点
- 物体是GameObject的对象
- 脚本一般写字段和方法
- 不写属性(在编辑器无法显示)
- 不写构造函数(不能在子线程中访问主线程)
- 输出到控制台
- Debug.Log(“ ”)
- 如果有个组件需要重复使用
- 可以从层级面板移到项目面板做个预制件
- 预制件加粗字体不随预制件修改修改
-
-
二、 脚本生命周期
-
1. 名称
- 也叫必然事件、消息 Message
- 想要找必然事件,可以再unity手册搜索MonoBehaviour(脚本的父类)
- 执行顺序搜索脚本生命周期来看
- 也叫必然事件、消息 Message
-
2. 小方法
- 序列化字段
- [SerializeField]
- 写在字段上边
- 作用:在编辑器显示私有变量
- [SerializeField]
- 隐藏字段
- [HideInInspector]
- 限制范围
- [Range(0,100)]
- 限制到0到100
- [Range(0,100)]
- 序列化字段
-
3. 初始阶段
- Awake
- 执行时机:创建游戏对象后 立即执行1次
- 脚本禁用也会执行
- private void Awake(){}
- 优先于Start
- 两个物体同时挂脚本,也是Awake先执行
- 作用:初始化
- 代替构造函数
- 执行时机:创建游戏对象后 立即执行1次
- Start
- 执行时机:创建游戏对象后 脚本启动后 执行1次
- private void Start(){}
- 作用:初始化
- 代替构造函数
- OnEnable
- 每当脚本对象启动时调用
- private void OnEnable
- Awake
-
4. 物理阶段
- FixedUpdate
- 执行时间:脚本启动后,固定时间被调用
- 更新频率默认0.02s
- 适用于对游戏对象做物理操作
- 物体运动、移动、旋转
- 因为时间固定 所以不会受到渲染影响
- 渲染时间不固定(每帧渲染量不同、机器性能不同)
- FixedUpdate
-
5. 游戏逻辑
- Update
- 执行时间:渲染帧执行
- 执行间隔不固定
- 适用于:厨力游戏逻辑
- 更新地图
- LateUpdate
- 延迟更新在Update函数呗调用后执行
- 仅在一帧后执行,同一时间内
- 适用于跟随逻辑
- 如果写入Update,就可能跟随先执行
- 延迟更新在Update函数呗调用后执行
- Update
-
6. 输入事件
- 鼠标移入
- OnMouseEnter
- 鼠标移入到当前Collider
- 鼠标经过
- OnMouseOver
- 鼠标经过当前Collider时调用
- 鼠标离开
- OnMouseExit
- 鼠标离开当前Collider时调用
- 鼠标按下
- OnMouseDown
- 鼠标按下当前Collider时调用
- 鼠标抬起
- OnMouseUp
- 鼠标在当前Collider抬起时调用
- 鼠标移入
-
7. 场景渲染
- OnBecameVisible 当可见
- 当Mesh Renderer在任何相机上可见时调用
- OnBecameInvisible 当不可见
- 当Mesh Renderer在任何相机上都不可见时调用
- OnBecameVisible 当可见
-
8. 结束阶段
- OnDisable 当不可用
- 对象变为不可用或附属游戏对象非激活状态时此函数被调用
- OnDestroy 当摧毁
- 脚本摧毁或附属游戏对象销毁时此函数被调用
- OnApplicationQuit 当程序结束
- 应用程序退出时调用
- OnDisable 当不可用
-
-
三、 调试
-
1. 看方法执行与否
- Debug.Log("111")
- 控制台有输出就是方法调用了
- print()也可以,print是MonoBehaviour类的方法,必须要继承这个为父类
- Debug.Log("111")
-
2. 看时间变化
- 写一个time变量,然后Time.time就可以在脚本属性那边看到时间变化
- 写在Update里边
- 尽量别用Debug.Log,要不然消耗太多内存
- 写一个time变量,然后Time.time就可以在脚本属性那边看到时间变化
-
3. 启动调试
- 必须先把脚本往物体挂
- vs按F5
- 然后unity点启动
- 到想要调试的时候,按暂停
- 回vs加断点,回到unity单帧运行(暂停的右边)
- 然后回VS里按F11
-
-
四、 Animation
-
1. 录制动画
- 添加组件Animation
- 创建物理文件
- 在Animation里add组件
- 例如旋转添加Rotate
- 录制添加关键帧,改参数就行
-
2. 语句
- 播放动画
- play
- 在前一个动画播完之后,播下个动画
- PlayQueued
- 是否有任何动画播放
- IsPlaying
- 倒着播放
- 把速度变成-1
- Animation["动画名"].speed=-1
- 为了方便修改,尽量在最上边搞个public变量,来提供动画名
- 并且需要把动画时间设置为1
- 添加个语句判断是否到了最后
- 组件名.isPlaying==false
- 组件名[动画名].time=组件名[动画名].length
- 否则动画不播放,从0到0
- 添加个语句判断是否到了最后
- 把速度变成-1
- 播放动画
-
-
五、 常用API
-
1. Component 组件
- Component类提供了查找(当前物体、后代、先辈)组件的功能
- this.GetComponet<组件名>().组件内容;
- Material是MeshRenderer组件里边的内容
- 获取当前物体所有组件
- var 变量名 = this.GetComponents<Component>();
- 加s就是获得所有组件
- foreach(var item in 变量名){Debug.Log(item.GetType());}
- var 变量名 = this.GetComponents<Component>();
- 获取后代物体的指定类型组件(包括自己)
- GetComponentInChildren<MeshRenderer>();
- 获取先辈物体的指定类型组件(包括自己)
- GetComponentInParent<MeshRenderer>();
-
2. Transform
- Transform提供了查找(父子根)变换组件,操作物体的位置、旋转和缩放的功能
- 获得子物体的变换组件(不包括自己)
- foreach(Transform Child in transform){}
- 孙子也不行
- 物体相对于世界坐标系位置
- this.transform.position
- this.transform.rotation
- 物体相对于父物体轴心点位置
- this.transform.localPosition
- this.transform.localRotation
- 相对于父物体缩放比例
- this.transform.localScale
- 物体与模型缩放比例(自身缩放比例*父物体缩放比例)
- this.transform.lossyScale
- 向自身坐标系z轴移动1米
- this.transform.Translate(0,0,1)
- 旋转
- this.transform.Rotate(0,0,1)
- 围绕旋转
- this.transform.RotateAround(Vector3.zero,Vector3.up,1)
- 绕世界坐标0点的y轴转1度
- z轴为forward,x轴为
- 向世界坐标系z轴移动1米
- this.transform.Translate(0,0,1,Space.Worle)
- 旋转
- this.transform.Rotate(0,0,1,Space.world)
- 获取先辈变换组件
- 根物体
- this.transform.root
- 父物体
- this.transform.parent
- 根物体
- 设置transform的父物体
- this.transform.setParent(父物体,false or true);
- 后边false or true是否相对于世界坐标改变位置,默认是true
- 找transform的子物体
- 获取子物体个数
- int count = this.transform.childCount
- 根据名称获取子物体
- Transform childTF=this.transform.Find("子物体名称")
- 根据索引获取子物体
- Transform childTF = this.transform.GetChild(i)
- 获取子物体个数
- 层级未知的时候找子孩子
- 递归
- 知道孩子数
- Transform 父节点.childCount
- 自己本身的组件
- this.transform
-
3. GameObject
- 激活与否
- 实际是否被激活
- this.gameObject.activeInHierarchy
- 局部是否被激活(只读),物体在Insoector中是否被禁用
- this.gameObject.activeSelf
- 设置物体启动/禁用
- this.gameObject.SetActive()
- 添加组件
- 对象名.gameObject.AddComponent<Light>()
- 在场景中根据名称查找物体(不建议使用)
- GameObject.Find("游戏对象名称")
- 大海捞针,费性能
- 根据标签查找
- 获取所有使用该标签的物体
- GameObject[] allEnemy = GameObject.FindGameObjectsWithTag("标签名")
- 获取使用该标签的物体(单个)
- GameObject Enemy=GameObject.FindWithTag("标签名")
- 获取所有使用该标签的物体
- 实际是否被激活
- 激活与否
-
4. Object
- 删除游戏对象、组件或资源
- Destroy
- 根据类型找对象
- Object.FindObjectOfType<MeshRenderer>()
- 找所有对象
- Object.FindObjectsOfType<MeshRenderer>()
- 删除游戏对象、组件或资源
-
5. Time
- 计算到现在的时间(只读)
- Time.time
- 以秒计算,完成最后一帧的时间间隔(只读)
- Time.deltaTime
- 保证移动速度与渲染时间无关
- 前提:在update写代码
- 一般会用速度来乘时间,保证旋转速度不受及其性能以及渲染量影响
- 例如this.transform.Rotate(0,speed*Time.deltaTime,0)
- 旋转速度*渲染时间间隔
- 在FixedUpdate里运行可以不用乘时间间隔
- this.transform.Rotate(0,speed,0)
- 前提:在update写代码
- 游戏暂停
- 时间缩放
- timeScale
- 为0就暂停
- 1就原速度
- 对渲染不造成影响
- unscaledDeltaTime不受这影响
- DeltaTime受此影响
- timeScale
- 时间缩放
- 个别语句指定间隔执行一次
- 设置一个变量,代表下次修改时间(灵活一些,上来就做,做完再等)
- Time.time超过这时间就修改
- 然后变量为time+间隔
- 设置一个变量,代表累加时间(灵活一些,上来就等,等完在做)
- 用Time.deltaTime累加
- 超过间隔就修改
- 然后累加归零
- 重复调用方法(适合隔固定时间)
- 在start里调用
- InvokeRepeating(方法名,第一次执行时间,执行间隔)
- 结束重复调用
- CancelInvoke(方法名)
- 指定时间执行
- 在Start里调用
- Invoke(方法名,第一次执行时间)
-
思维导图
- 设置一个变量,代表下次修改时间(灵活一些,上来就做,做完再等)
- 计算到现在的时间(只读)
-