Unity快速入门之一 3D基础概念、Camera、Canvas RenderMode的几种方式对比_翕翕堂
Unity快速入门之二 GUI Transform 详解_翕翕堂
Unity快速入门之四 - Unity模型动画相关_翕翕堂-CSDN博客
资源管理待定……
……
这一篇主要是从代码了,代码内容是纯示例内容,可以有更多更好的思路扩展。
本篇幅会比较长,涉及到比较多的内容,请坐好准备发车~~~~
前置准备就需要自己准备好了:
1、准备 visual studio 2017 IDE。
2、安装 vs for unity 插件。
3、C#语法基础或其他语言基础。
目录
EventManagerUnity(UnityEvent && UnityAction)
C# Script(脚本)
脚本创建
Project视图下,Assets及其子目录,右键菜单->Create->C# Script:
![](https://i-blog.csdnimg.cn/blog_migrate/5fccf71e09a67290b8891e28dcfea7e1.png)
建一个Script文件夹,创建一个C#脚本,默认脚本名字 New Behaviour Script,点击脚本,可以在 Inspector中可以显示脚本内容:
![](https://i-blog.csdnimg.cn/blog_migrate/c81b319b4749a929fb9fb9a160c9e45f.png)
挂载脚本
![](https://i-blog.csdnimg.cn/blog_migrate/bd5c27f81e8d9a699bd3572882710387.png)
Hierarchy视图中选中一个3D对象,在其Inspector视图中,最下方点击 Add Componet 按钮,输入框中搜索刚才创建的脚本 NewBehaviourScript,就可以看到它了,点击挂在到这个对象上:
![](https://i-blog.csdnimg.cn/blog_migrate/edcb516a1046e46517d43964d05dc1fd.png)
先用 vs2017打开这个脚本,双击上方图片中黄色位置即可(需要配置好环境,不展开了):
![](https://i-blog.csdnimg.cn/blog_migrate/98d7b00c74b8f0edc167b2d08d2cbe52.png)
前置场景与知识准备
由于按钮是最通用的控件,从它开始切入。首先创建一个基础场景:
- 按钮控件:button event
- 文本控件:text event
- 文本控件:custom trigger
- 3D Cube:Cube
![](https://i-blog.csdnimg.cn/blog_migrate/f9cfb9ab5ea16f5cef8370f143ccaa65.png)
创建一个脚本 ButtonEvent,并放到 button event控件 上,先介绍几个脚本的基本内容:
MonoBehaviour:Unity对象的基础类,里面拥有很完整的生命周期,继承于这个类的脚本都可以当成组件挂载到具体的对象身上。
void Start():首次加载以及对象再次激活的时候会被调用,这次我们只要用到它就好了。
gameObject:此脚本组件说挂载的对象,由于我们要使用Button及其点击事件,Button也是一个独立组件,要由它来获取。
Unity内置事件
Unity按钮(Button)点击(OnClick)事件
流程上:
- 创建点击处理函数
- 找到按钮
- 绑定处理函数到按钮
按钮点击函数上代码实现方式,常见的四种:
- 成员函数
- 匿名委托
- 实例委托
- lambda
这些都是基于C#语法的,语法规则就不做展开了。
下面开始说 Button怎么绑定点击响应事件,首先,保留脚本最简形式:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ButtonEvent : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
}
增加一个响应我们点击事件的成员函数作为处理函数:
public class ButtonEvent : MonoBehaviour
{
void Start()...
public void OnClickFunction00()
{
Debug.Log("AddListener - 委托成员函数 - OnClickFunction00");
}
}
在Start中找到我们要的按钮,并将处理函数绑定到按钮上:
// 使用控件需要添加的命名空间
using UnityEngine.UI;
public class ButtonEvent : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
// AddListener - 成员函数 - OnClickFunction
gameObject.GetComponent<Button>().onClick.AddListener(OnClickFunction00);
}
public void OnClickFunction00()...
}
由于使用了Butoon,这个属于 UnityEngine.UI 之下,所以开头要使用 using UnityEngine.UI。
获取组件通过 gameObject.GetComponent<T>() 接口,我们这用的Button,所以是gameObject.GetComponent<Button>() ,下一步要绑定处理函数到按钮上,上面已经写出来了,就是 onClick.AddListener(OnClickFunction00),这是怎么来的,可以翻官网或度娘:Unity - Manual: UnityEventshttps://docs.unity3d.com/Manual/UnityEvents.html
也可以看下它的实现,我们点开Button看看:
![](https://i-blog.csdnimg.cn/blog_migrate/28ef100d9de77de6eb60f4d9ea301f52.png)
可以看到Unity的UI Button,有一个OnClick,来自于ButtonClickedEvent,而它又来自于UnityEvent,另外Button继承于几个xxxHandler 接口。
我们继续点开UnityEvent看看:
![](https://i-blog.csdnimg.cn/blog_migrate/2efd2defcf67a4f39845a7da4ed54588.png)
看到 Reflection、MethodInfo、Invoke,大概就知道,这东西是靠反射来实现的,这里就不继续往 UnityEventBase展开了,但是可以给没接触过反射的朋友大概说下,反射(Reflection)就是通过拿到目标类及其类下所有的变量、函数等信息,做额外存储,在运行时可以通个这些额外存储的信息以及类的实例对象进行调用,但是需要占用额外内存,性能也比较低。
好了,我们继续。
它的目标函数怎么绑定的,这个很明显:public void AddListener(UnityAction call);
那么UnityAction是什么玩意儿,点进去看看:public delegate void UnityAction();
![](https://i-blog.csdnimg.cn/blog_migrate/d560c96b4aa5e8b088e448b8e86abe36.png)
一个委托(Delegate),类似于C++的函数指针形式,但是使用的时候实际上是对象。
掌握了这些信息,我们可以继续拓展我们的事件了。(对于上面 反射、委托不懂想要深究的,可以找其他资料进行了解)
首先看下上面的结果:
![](https://i-blog.csdnimg.cn/blog_migrate/2ae473e56079d1d563052aae3533cbb3.png)
没毛病,点击按钮,确实输出了我们需要的消息。既然 UnityAction 是个 delegate,那么我们应该可以直接使用委托匿名函数来作为处理函数。
{
// Start is called before the first frame update
void Start()
{
...
// AddListener - 委托匿名函数 - delegate
gameObject.GetComponent<Button>().onClick.AddListener(delegate
{
Debug.Log("AddListener - 委托匿名函数 - delegate");
});
}
public void OnClickFunction00()...
}
也可以使用委托实例,这里显示的调用了 UnityAction,需要增加 using UnityEngine.Events:
// 使用UnityAction需要增加这个
using UnityEngine.Events
public class ButtonEvent : MonoBehaviour{
// Start is called before the first frame update
void Start()
{
...
// AddListener - 委托实例 - OnClickFunction01
gameObject.GetComponent<Button>().onClick.AddListener(
new UnityAction(OnClickFunction01)
);
}
public void OnClickFunction00()...
public void OnClickFunction01()
{
Debug.Log("实例委托 - OnClickFunction02");
}
}
委托lambda:
{
// Start is called before the first frame update
void Start()
{
...
// AddListener - 委托lambda表达式 - lambda
gameObject.GetComponent<Button>().onClick.AddListener(
() => Debug.Log("lambda表达式委托 - lambda")
);
}
public void OnClickFunction00()...
}
由于UnityAction是委托,所以可以不调用AddListener,直接使用多路广播,最后一次性绑定:
{
//创建UnityAction成员变量
public UnityAction m_untiyAction;
// Start is called before the first frame update
void Start()
{
// 多路广播,委托函数
m_untiyAction += OnClickFunction01;
// 委托匿名函数
m_untiyAction += delegate
{
Debug.Log("多路广播 - 匿名函数委托 - delegate");
};
// 委托实例 - OnClickFunction01
m_untiyAction += new UnityAction(OnClickFunction01);
// 委托lambda表达式
m_untiyAction += () => { Debug.Log("多路广播 - lambda表达式委托 - lambda"); };
// AddListener - UnityAction - delegate
// 将UnityAction绑定到AddListener
gameObject.GetComponent<Button>().onClick.AddListener(m_untiyAction);
}
public void OnClickFunction00()...
}
放个完整的ButtonEvent代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
public class ButtonEvent : MonoBehaviour
{
//https://docs.unity3d.com/Manual/UnityEvents.html
public UnityAction m_untiyAction;
// Start is called before the first frame update
void Start()
{
// AddListener - 成员函数 - OnClickFunction
gameObject.GetComponent<Button>().onClick.AddListener(OnClickFunction00);
// AddListener - 委托匿名函数 - delegate
gameObject.GetComponent<Button>().onClick.AddListener(delegate
{
Debug.Log("AddListener - 委托匿名函数 - delegate");
});
// AddListener - 委托实例 - OnClickFunction01
gameObject.GetComponent<Button>().onClick.AddListener(new UnityAction(OnClickFunction01));
// AddListener - 委托lambda表达式 - lambda
gameObject.GetComponent<Button>().onClick.AddListener(
() => Debug.Log("lambda表达式委托 - lambda")
);
// 多路广播,委托函数
m_untiyAction += OnClickFunction01;
// 委托匿名函数
m_untiyAction += delegate
{
Debug.Log("多路广播 - 匿名函数委托 - delegate");
};
// 委托实例 - OnClickFunction01
m_untiyAction += new UnityAction(OnClickFunction01);
// 委托lambda表达式
m_untiyAction += () => { Debug.Log("多路广播 - lambda表达式委托 - lambda"); };
// AddListener - UnityAction - delegate
gameObject.GetComponent<Button>().onClick.AddListener(m_untiyAction);
}