事件和委托:
    区别:事件不能外部使用赋值=符号,只能使用+=,-=,委托哪里都能用,
    事件不能外部执行,委托哪里都能执行。
    事件不能作为函数中临时变量,委托可以

委托:

  对于委托,用法就是在声明委托后再在其他的方法内实现,并用+=,-=调用。

委托分为带参数和不带参数两种。

      C#内常用的委托为Action和Fun两种,要带参数只需要用泛型类型。

委托使用:
    delegate void MyFun();//声明
    MyFun f=new MyFun();//使用
    f.Invoke();//调用
    //作为参数
    public MyFun fun;
    public MyFun2 fun2;
    public void TestFun(MyFun fun,MyFun2 fun2){    this.fun=fun;   this.fun2=fun2      }
匿名函数:
    Action a=delegate( )
    {    什么时候调用委托就什么时候用匿名函数
        console.writeLine("匿名函数逻辑");
    }


lambda表达式:   什么时候调用委托就什么时候用lambda
  Action a=( )=>{    Console.WriteLine("")        }        a();          Action<int> a2=(int Value)=>{   Console.WriteLine("   +{0}",value)   }
 

C#中的事件系统:

 // //事件的拥有者   Customer类
   // //事件  [event关键字修饰]  OnOrder,点餐事件
   // //事件的响应者  Waiter类
   // //事件处理器    [受到约束的方法] TakeAction方法
   // //事件订阅(+=操作符)   += (只能增加或者减少事件,其他不行)


   // //声明委托类型
   //                                           //事件拥有者      事件参数
   //// public delegate void OrderEventHandler(Customer _customer,OrderEventArgs _e);//约束事件处理器,创建出的实例是专门存储事件处理器    
   // //为声明OnOrder事件委托       简化后没必要声明这个委托,因为有EventHandler

   // //传递事件信息,事件消息
   // public class OrderEventArgs : EventArgs
   // {
   //     public string CoffeeName { get; set; }
   //     public string CoffeeSize { get; set; }
   //     public float CoffeepPrice{ get; set; 

   // }

   // public class EventEx : MonoBehaviour
   // {
   //     Customer customer = new Customer();
   //     Waiter waiter = new Waiter();
   //     private void Start()
   //     {
   //         customer.Onorder += waiter.TakeAction;
   //         customer.Order();

   //         customer.PayTheBill();
   //     }
   // }

   // public class Customer
   // {
   //     public float Bill { get; set; }
   //     public void PayTheBill()
   //     {
   //         Debug.Log("我要支付" + this.Bill);
   //     }
   //     ////完整的声明事件
   //     ////事件拥有者
   //     //private OrderEventHandler ordereventhandler;
   //     //public event OrderEventHandler OnOrder  //声明事件
   //     //{
   //     //    add
   //     //    {
   //     //        ordereventhandler += value;
   //     //    }
   //     //    remove
   //     //    {
   //     //        ordereventhandler -= value;
   //     //    }
   //     //}

   //     //简略声明格式
   //     //public event OrderEventHandler Onorder;  //像字段,
   //     public event EventHandler Onorder;
   //     public void Order()
   //     {
   //         if (Onorder != null)//事件是否为空
   //         {
   //             OrderEventArgs e = new OrderEventArgs();//事件1
   //             e.CoffeeName = "卡布奇诺";
   //             e.CoffeeSize = "中杯";
   //             e.CoffeepPrice = 28;
   //             Onorder(this, e);

   //             OrderEventArgs e1 = new OrderEventArgs();//事件2
   //             e.CoffeeName = "普洱咖啡";
   //             e.CoffeeSize = "大杯";
   //             e.CoffeepPrice = 30;
   //           Onorder(this, e1);

   //         }
   //     }

   //     //事件Event基于委托delegate 
   //     //1.类型兼容    用委托类型做约束  即消息发送限制
   //     //2.存储方法的引用    在一个地方把事件处理器保存,存储记录下来

   // }


   // public class Waiter
   // {
   //     internal void TakeAction(object sender, EventArgs e)
   //     {
   //         float finalPrice = 0;
   //         Customer customer = sender as Customer;
   //         OrderEventArgs _e = e as OrderEventArgs;
   //         switch (_e.CoffeeSize)
   //         {
   //             case "中杯":
   //                 finalPrice = _e.CoffeepPrice;
   //                 break;
   //             case "大杯":
   //                 finalPrice = _e.CoffeepPrice + 3;
   //                 break;
   //             case "超大杯":
   //                 finalPrice = _e.CoffeepPrice + 6;
   //                 break;


   //                 customer.Bill += finalPrice;
   //         }
   //     }

   //     //internal void TakeAction(Customer _customer, OrderEventArgs _e)
   //     //{
   //     //    float finalPrice = 0;
   //     //    switch (_e.CoffeeSize)
   //     //    {
   //     //        case "中杯":
   //     //            finalPrice = _e.CoffeepPrice;
   //     //            break;
   //     //        case "大杯":
   //     //            finalPrice = _e.CoffeepPrice + 3;
   //     //            break;
   //     //        case "超大杯":
   //     //            finalPrice = _e.CoffeepPrice + 6;
   //     //            break;


   //     //    _customer.Bill += finalPrice;

   //     //    }
   //     //}


   // }

unity中的事件系统:

关于在unity里用事件系统的终极结论:但凡是跟unity3D世界交互的都写在HUD,但凡是跟C#内部交互
的都写在Inventory。
    模版参考BiLiBiLi背包系统:https://www.bilibili.com/video/BV1FT4y1m79Z/?spm_id_from=333.1387.favlist.content.click

    unity内事件系统常用模板分为四个部分:Inventory,HUD,Interface,EventArgur.
Inventory对应处理C#内部逻辑,格式为:
    public class Inventory : MonoBehaviour
{
      private List<IInventoryItem> mItems = new List<IInventoryItem>();  //库存项目列表 
      public event EventHandler<InventoryEventArgs> ItemAdded;    //将项目添加到此列表的方法
    
       public void AddItem(IInventoryItem item)    //处理器
       {
     mItems.Add(item);    //增加到事件List内

     item.OnPickup();    //在Item内针对接口内方法实现方法的事件。  (这里Item是指Unity3D世界里的物品)

    //通知所有事件订阅者
    if (ItemAdded != null)
    {
        ItemAdded(this, new InventoryEventArgs(item));
    }
       }

HUD对应处理unity3D世界逻辑,格式为:

      public class HUD : MonoBehaviour
      {

     void Start()
     {
         Inventory.ItemAdded += InvenToryScript_ItemAdded;  //事件处理(事件订阅)
     }

     private void InvenToryScript_ItemAdded(object sender, InventoryEventArgs e)   //自定义委托名(InvenToryScript_ItemAdded)+自定义类 (e)
     {
        //如实现对Canvan的遍历获取子物体,将Item属性上传等
    }
}


用接口实现对物品属性的传递(只被继承在unity3D世界中的物品属性中):
    public interface IInventoryItem     //接口概念:和类进行约定,完成某些指定的功能,这里是用是为了一个方便属性的传递与修改
{                                  
    string Name { get; }
    Sprite Image { get; }
    void OnPickup();
}

事件系统中的润滑剂,接口EventArgs,实现对拥有者和响应者之间信息处理:
    public class InventoryEventArgs:EventArgs
     {
        public IInventoryItem Item;
    public InventoryEventArgs(IInventoryItem item)
    {
        Item=item;
    }
      }
 

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐