前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Unity3D-委托使用

Unity3D-委托使用

作者头像
孙寅
发布2020-06-02 11:42:35
3820
发布2020-06-02 11:42:35
举报
文章被收录于专栏:宜达数字宜达数字
1.Action委托
1、Action简介:

C#中与预定义了一个委托类型Action 它默认可以指向一个没有返回值,没有参数的方法。

    public Action hit;
// 委托原型 = 上面的Action hit
    public delegate void hitHand();
    public hitHand hit;
2、Action基本使用
static void printString(){
  Console.WriteLine("Hello World");
}

static void Main(String[] args){
  Action a = printString;
  a(); // 输出结果  Hello World
}

Action其他使用方法

3、Action指向有参数的方法
static void printNumber(int x){
    Console.WriteLine(x);
}

static void Main(String[] args){
  Action<int> a = printNumber; // 定义一个指向 形参为int的函数
  a(5); // 输出结果  5
}

Action可以通过泛型来指定,指向的方法有 0 - 16个参数

Action<int, int, string, bool 等等>
2.Func委托
  • 1.简介

Func 也是C#预定义的委托, 且可以指向带有一个返回值的方法,传递0-16个参数。

与Action区别: Action 不能指向有返回值的方法 , 不能有返回值 。Func 可以指向有一个返回值的方法, 且必须有返回值。 For Example

1>指定返回值
static int GetNumber()
{
    return 1;
}

static void Main(string[] args)
{
 Func<int> a = GetNumber; // 定义一个Func 委托,  指向一个返回int类型的 方法
 Console.WriteLine(a());
}
2>指定参数和返回值的例子

Func<string, int>最后一个参数表示返回值类型,前面的都是形参类型。

static int Test2(string str){
  return 1;
}

static void Main(string[] args){
 Func<string, int> a = Test2; // 泛型中最后一个参数表示返回值类型。
 Console.WriteLine(a("a"));
}
  • Unity使用委托方法

观察者模式

案例中,场景脚本为发布者,三个物体为观察者。

public class ActionManager : MonoBehaviour {

    public static ActionManager instance;
    public Action hit;
    private void Awake()
    {
        instance = this;
    }
    

    void Update () {
        if (Input.GetMouseButtonDown(0)) {
            if (hit != null)
            {
                Debug.Log("点解了");
                hit();
            }
        }
    }
}
using UnityEngine;

public class ActionTest : MonoBehaviour {
    void Start () {
        ActionManager.instance.hit += Onchange;
    }

    private void Onchange()
    {
        //Debug.Log(go.name);
        transform.localScale = new Vector3(UnityEngine.Random.Range(1,3.5f),UnityEngine.Random.Range(1, 3.5f), UnityEngine.Random.Range(1, 3.5f));
    }

    private void OnDestroy()
    {
        ActionManager.instance.hit -= Onchange;
    }
  • Unity项目中的点击箱子:

多个发布者,一个观察者

捡箱子

案例中:每个箱子都是发布者,而角色身上的脚本就是观察者。通过监听箱子的委托,来达到拾取箱子的目的。

// 箱子身上挂在的脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoxController : MonoBehaviour {

    public System.Action<GameObject> OnHit;

    public void Hit()
    {
        if (OnHit != null)
        {
            OnHit(gameObject);
        }
    }       
}
using UnityEngine;

public class RoleCtrl : MonoBehaviour {

   void Update () {
        if (Input.GetMouseButtonUp(1))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            // 发射射线,检测名称为Box的layer层。
            if (Physics.Raycast(ray, out hit, Mathf.Infinity, 1 << LayerMask.NameToLayer("Box")))
            {
                BoxController box = hit.collider.GetComponent<BoxController>();
                if (box != null)
                {
                    box.Hit();
                }
                Debug.Log("find box" + hit.collider.name);

            }
      }
}
// ========================================================
// 描述:
// 作者:雷潮 
// 创建时间:2019-01-22 16:27:54
// 版 本:1.0
//========================================================
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScenneCtrl : MonoBehaviour {

    [SerializeField]
    private Transform transBox;
    [SerializeField]
    private Transform parentBox;

    private GameObject boxPrefab;
    private int minCount = 0;
    private int maxCount = 10;

    private float nextCloneTime = 0;
   

    // 数据存储
    private string boxKey = "BoxKey";
    private int getBoxCount;

    void Start () {
        boxPrefab = Resources.Load("BoxPrefabs/Box") as GameObject;
        getBoxCount = PlayerPrefs.GetInt(boxKey,0);
    }
    
    // Update is called once per frame
    void Update () {
        if (minCount < maxCount)
        {
            if (Time.time > nextCloneTime)
            {
                nextCloneTime = Time.time + 3f;
                GameObject cloneObj =   Instantiate(boxPrefab);
                cloneObj.transform.parent = parentBox;
                cloneObj.transform.position = transBox.TransformPoint(new Vector3(UnityEngine.Random.Range(-0.5f,0.5f),0, UnityEngine.Random.Range(-0.5f, 0.5f)));

                BoxController box =  cloneObj.GetComponent<BoxController>();

                if (box != null)
                {
                    box.OnHit = OnHit;
                    minCount++;
                }             
            }
        }
    }

    private void OnHit(GameObject obj)
    {
        minCount--;
        getBoxCount++;
        PlayerPrefs.SetInt(boxKey, getBoxCount);
        GameObject.Destroy(obj);
        Debug.Log("拾取了" + getBoxCount + "个箱子");
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.Action委托
    • 1、Action简介:
      • 2、Action基本使用
        • 3、Action指向有参数的方法
        • 2.Func委托
          • 1>指定返回值
            • 2>指定参数和返回值的例子
            相关产品与服务
            数据保险箱
            数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档