目录
16.Unity如何调用android与iOS的 API函数?
1.委托是什么?Event关键字有什么用?
- 委托:用于将方法作为参数传递给其他方法。事件处理程序就是通过委托调用方法。
- 你可以创建一个自定义方法,当特定事件发生后,某个类就可以调用你这个方法。
- 可以将多个方法赋给同一个委托,调用时,依次调用其所有绑定的方法,也可以取消。
- 举例:遇到不同国家的人,以不同的方式打招呼。
-
using System; using System.Collections.Generic; namespace UnityBase { //委托 public delegate void sayhelloDelegate(string name); class Program { static void Main(string[] args) { List<People> pp = new List<People>(); var ma = new People { Name = "马云", Country = "中国", sayFunction = ChineseSay }; ma.Country = "USA"; ma.sayFunction += EnglishSay; pp.Add(ma); pp.Add(new People { Name = "Bill", Country = "USA", sayFunction = EnglishSay }); pp.ForEach(p => Say(p)); } public static void Say(People p) { p.sayFunction(p.Name); } public static void ChineseSay(string name) { Console.WriteLine($"{name},老表,吃了没?"); } public static void EnglishSay(string name) { Console.WriteLine($"hello,{name},how are you ?"); } } public class People { public string Name { get; set; } public string Country { get; set; } public sayhelloDelegate sayFunction { get; set; } } }
事件(Event):在类中声明生成,通过使用同一个类或者其他类中的委托与事件处理程序关联。
-
包含事件的类用于发布事件称为(发布器)类,其他接受该事件的类称为(订阅器)
-
在类内部声明事件,首先必须声明该事件的 委托类型。然后声明事件本身,使用event关键字
using System;
namespace UnityBase
{
// 发布器
public class EventTest {
public delegate void NumDelegate();
public event NumDelegate NumEvent;
protected virtual void OnNumEvent() {
if (NumEvent != null)
{
NumEvent();
}
else {
Console.WriteLine("Event Not !!!");
Console.ReadKey();
}
}
public void SetValue() {
OnNumEvent();
}
}
// 触发
class Program
{
static void Main(string[] args)
{
EventTest e = new EventTest();
e.SetValue();
e.NumEvent += new EventTest.NumDelegate(prinnf);
e.SetValue();
e.SetValue();
}
// 订阅器
public static void prinnf()
{
Console.WriteLine("Event Fire");
Console.ReadKey();
}
}
}
2.Unity协程是如何实现的 (IEnumerator)
- 协程:
- 性能:相比于一般函数,没有更多开销
- 好处:分部做一个比较耗时的东西,如需大量计算,将计算放到一个随时间进行的协程来处理,分散计算压力。
- 坏处:本质是迭代器,且是基于unity生命周期的,大量开启协程会产生GC。
- 执行:协程不是线程,不是异步执行的。在主线程中执行,是一个分部执行,遇到条件(yield return)会挂起,直到满足条件才会被唤醒继续执行后面的代码。unity每帧都会处理对象上的协程。
- 结束:StopCoroutine(string methordName); StopAllCoroutines(); 暂停当前脚本下所有协程。或者设置对象active=false,即使再次激活,也不能继续执行。但enable=false 不能停止协程。。
- 中断:WaitForSeconds() 等待数秒,受Time.timeScale影响,当time.timeScale=0时,yield return new WaitForSecond(1)不会被满足。 WaitForFixedUpdat:等待一个固定帧。。。。 StartCoroutine等待一个协程暂停,WWW等待一个加载完成。
- 执行顺序:开始协程—>执行协程—>遇到中断指令中断协程—>返回上层函数继续执行上层函数的下一行代码—>中断指令结束,继续执行中断指令之后的代码—>协程结束。
- 在一个主线程里,同时最多只能有一个处于运行状态的协程。协程不是并行的,同一时刻,一个脚本实例中可以有多个暂停的协程,但只有一个运行的协程。
- 和线程的区别:线程是利用多核达到真正的并行计算,缺点是有大量的锁,切换,等待的问题。而协程是非抢占式,需要手动释放使用权来切换到其他协程,因此,同一时间只有一个协程拥有运行权,相当于单线程的能力。 协程是C#线程的替代品,是unity不使用线程的解决方案。使用协程不用考虑锁的问题。多个协程可以同时进行,会根据启动顺序来更新。
- 注意点:IEnumerator类型的方法不能带ref和out型参数,但可以被传递引用。函数Update和FiexdUpdate中不能使用yield语句,否则会报错,但是可以启动协程。
3.摄像机有几种模式,成像原理分别是什么?
- Projection:Prespective 透视;Orthographic 正交。
4.Canvas 有几种模式,如何配置?
- canvas的RenderMode共有三种模式:Screen Space-OverLay,Screen Space-Camrea,World Space;
- Screen Sp模块管理ace-OverLay:Canvas 覆盖屏幕,且永远覆盖在其它元素的上层,也就是说 UI 会遮挡场景中的其它元素。显示优先级由 Sort Order 确定
- Screen Space-Camrea:和 Overlay 模式相仿,Canvas覆盖整个屏幕空间画布也是填满整个屏幕空间。不同之处在于,Canvas 被放置于指定摄像机的前方。这种模式下面 UI 并不一定能渲染在 3d 元素之上。
- Word Spcae:此种模式下,Canvas 与场景中其它3D元素没有区别。
- 同时显示多个摄像机:更改相机的Viewport Path,上面的相机Depth要大。
5.UGUI如何打包图集?
- 开启:Edit--Project Setting-Editor-Sprite Packer-Mode
- Disable:不可用
- Enable For Builds:打包发布时启用
- Always Enable:一直启用,在开发和打包阶段都启用,方便开发人员在开发阶段查看图集信息,推荐使用
- 操作:Type是Sprite,设置Packing Tag的名字,unity会自动将这些图按照tag打包到图集中去。
- 查看:window-sprite packer
- 注意:打包的图片不要放到Rescore下。
- 加载:动态加载,需要自己写代码。Atlas和AutoSetTextureUISprite包含usingEditor,需放在Editor下,否则报错。
- https://blog.csdn.net/weixin_41843959/article/details/80411529