今天说说委托,常用委托四种,Func 委托与 Delegate 、Action Event,四种都可以用来做事件委托使用
Delegate 和Action 功能上差不多,本人是做VR的,所以大部分使用委托时是做动画播放使用和UI部分的数据观察(观察者模式)
先上一部分代码示例
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public delegate void delegatemove();//定义委托
public abstract class delemove : MonoBehaviour {
public delegatemove move;
public abstract void inend();
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class delemove1 : delemove { // 第一个物体要实现的动画 obj1
bool isok;
public override void inend()//改写方法
{
isok = true;
}
void Update () {
if (isok)
{
transform.position = Vector3.MoveTowards(transform.position,
new Vector3(10, 10, 10), Time.deltaTime * 5);
if(transform.position == new Vector3(10, 10, 10))
{
if(move != null)
{
move();//产生回调
}
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class delemove2 : delemove//第二个物体要实现的动画 obj2
{
bool isok;
public override void inend()//改写方法
{
isok = true;
}
void Update()
{
if (isok)
{
transform.position = Vector3.MoveTowards(transform.position,
new Vector3(10, 10, 10), Time.deltaTime * 5);
if (transform.position == new Vector3(10, 10, 10))
{
if (move != null)
{
move();//回调
}
}
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class delemove3 : MonoBehaviour//使用
{
public GameObject obj1;
public GameObject obj2;
delemove d1;
delemove d2;
private void Start()
{
d1 = obj1.GetComponent<delemove>();
d1.inend();
d1.move += delegate//匿名
{
d2 = obj2.GetComponent<delemove>();
d2.inend();
};
}
}
以上解决两个问题,动画的顺序播放,解耦和
执行顺序 获取到obj1的delemove并执行inend()方法,匿名将obj2的inend方法注册进委托move里面,在obj1执行后回调move函数执行下一个动画 用Action也可以完成 亲测 可以看到在获取obj1和obj2时,获取的都是delemove这个基类,这就是Delegate委托参数的逆变性和委托返回类型的协变性 可参考http://www.cnblogs.com/murongxiaopifu/p/4684728.html 作者:慕容小匹夫的详解
Func 委托
-
Func<T in,T Tresult>:
封装一个具有一个参数并返回 TResult 参数指定的类型值的方法
-
Func使用:
1)似乎不能多播委托
2)在 Unity 编程的时候,添加上 using System;
3)Func 用于带返回值的委托
4)与Action委托区别,Func能返回函数执行结果,而Action返回类型是Void
-
函数委托形式:
形式为:Func = FuncName;其中Func为Func委托名,FuncName为函数名称
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Func : MonoBehaviour {
public Func myfun;
public Func<string> myfun1;
public Func<int, string> myfun2;
// Use this for initialization
void Start () {
myfun1 = callfun1;
myfun2 = callfun2;//指定一个方法
//myfun2 = delegate(int curName) { return curName.ToString(); };//匿名
//myfun2 = name => { return name.ToString(); };//Lamda
}
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.A))
{
print(myfun1());
}
if (Input.GetKeyDown(KeyCode.F))
{
print(myfun2(2));
}
}
string callfun1()
{
return ("无参带返回值的Func委托 1");
}
string callfun2(int intAgr)
{
return ("带参带返回值的Func委托 " + intAgr);
}
}
方法一:采用匿名委托,方法二:指定一个实际的方法。方法三:使用Lamda表达式。以上3中用法均可运行。Action同样适用
亲测Func不可以+= -= 不知道是不是写的问题,欢迎指导