unity学习——委托delegate的使用

本文介绍了一个使用Unity和C#实现多个物体统一控制的例子。通过定义委托并在CubeManager脚本中调用各物体的MoveHorizontal方法,实现按键盘左右键控制多个立方体同步移动的功能。

初次接触c#的委托机制,感觉非常方便使用,下面是一个简单的委托使用的例子。
目的:实现按下键盘上左右键能使三个cube物体同时移动
1.首先创建一个unity场景(非常简单包括一个主相机,三个cube物体cube1,cube2,cube3)
2.建立两个C#脚本,一个名为SmartCube,另一个名为CubeManager
SmartCube的代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SmartCube : MonoBehaviour {
    public float speed = 10;
    public void MoveHorizontal()
    {
        transform.Translate(Time.deltaTime*speed*Input.GetAxis("Horizontal"),0,0);
    }
}

CubeManager代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CubeManager : MonoBehaviour {
    delegate void CubeMoveHDelegate();
    CubeMoveHDelegate hDelegate;
    // Use this for initialization
    void Start () {
        SmartCube[] cubes= FindObjectsOfType(typeof(SmartCube))as SmartCube[];
        for (int i = 0; i < cubes.Length; i++)
        {
            SmartCube c = cubes[i];
            hDelegate += c.MoveHorizontal;

        }
    }

    // Update is called once per frame
    void Update () {
        if (Input.GetKey(KeyCode.LeftArrow) || Input.GetKey(KeyCode.RightArrow))
            hDelegate();
    }
}

3.将SmartCube脚本拖分别拖到三个cube物体上,将CubeManager拖到主相机上,调整好相机角度便于观察cube的移动。

### Unity委托的定义 在 C#Unity 中,委托是一种类型安全的方法指针。通过声明委托类型并实例化它,可以将方法作为参数传递给其他方法[^4]。 ```csharp public delegate void MyDelegate(string message); ``` 这段代码定义了一个名为 `MyDelegate` 的委托类型,它可以指向任何接受单个字符串参数且不返回值的方法。 ### 创建和使用委托 为了更好地理解如何在 Unity使用委托,考虑如下场景: 假设有一个简单的游戏对象需要响应不同的按钮点击事件。可以通过委托来实现这一功能而不必硬编码特定的行为逻辑。 #### 定义委托 首先,在脚本中定义一个新的委托类型: ```csharp using UnityEngine; // 定义一个无参、无返回值的委托 public delegate void OnButtonClickHandler(); ``` #### 实现回调函数 接着,在另一个类中编写具体要执行的操作(即回调函数),这些操作将在触发时由委托调用: ```csharp public class ButtonActions : MonoBehaviour { // 提供两个可能的动作选项 public void Jump() { Debug.Log("Jump!"); } public void Duck() { Debug.Log("Duck!"); } } ``` #### 注册与解除注册 现在可以在管理器类里创建委托变量,并允许外部组件向其中添加或移除处理程序: ```csharp public class UIManager : MonoBehaviour { private OnButtonClickHandler buttonClickHandlers; /// <summary> /// 添加新的按钮点击处理器. /// </summary> public void AddButtonClickListener(OnButtonClickHandler handler){ this.buttonClickHandlers += handler; // 订阅事件 } /// <summary> /// 移除指定的按钮点击处理器. /// </summary> public void RemoveButtonClickListener(OnButtonClickHandler handler){ this.buttonClickHandlers -= handler; // 取消订阅事件 } /// <summary> /// 当实际发生点击行为时调用此方法. /// </summary> public void HandleButtonClick(){ if (this.buttonClickHandlers != null){ this.buttonClickHandlers(); // 调用所有已注册的处理器 } else{ Debug.LogWarning("No handlers registered."); } } } ``` 当玩家按下屏幕上的虚拟按钮时,UIManager 将会调用 `HandleButtonClick()` 方法,进而依次触发所有已经过注册的回调函数。 ### 处理多个监听者 如果希望支持多播——也就是允许多个不同对象同时监听同一个事件,则应利用 `_invocationList` 字段自动维护链表结构的能力[^2]: 每当有新成员加入到现有的委托实例上(`+=`)时,内部机制便会更新列表;而当有人取消订阅(`-=`),则相应条目会被删除。 这样做的好处在于能够轻松管理和追踪所有的观察者,即使数量较多也不会影响性能表现。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值