1.Action委托
1、Action簡(jiǎn)介:
C#中與預(yù)定義了一個(gè)委托類型Action
它默認(rèn)可以指向一個(gè)沒(méi)有返回值牌芋,沒(méi)有參數(shù)的方法伶跷。
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(); // 輸出結(jié)果 Hello World
}
Action
其他使用方法
3、Action指向有參數(shù)的方法
static void printNumber(int x){
Console.WriteLine(x);
}
static void Main(String[] args){
Action<int> a = printNumber; // 定義一個(gè)指向 形參為int的函數(shù)
a(5); // 輸出結(jié)果 5
}
Action
可以通過(guò)泛型來(lái)指定叭莫,指向的方法有 0 - 16個(gè)參數(shù)
Action<int, int, string, bool 等等>
2.Func委托
- 1.簡(jiǎn)介
Func 也是C#預(yù)定義的委托蹈集, 且可以指向帶有一個(gè)返回值的方法,傳遞0-16個(gè)參數(shù)雇初。
與Action區(qū)別:
Action 不能指向有返回值的方法 拢肆, 不能有返回值 。Func 可以指向有一個(gè)返回值的方法靖诗, 且必須有返回值善榛。
For Example
1>指定返回值
static int GetNumber()
{
return 1;
}
static void Main(string[] args)
{
Func<int> a = GetNumber; // 定義一個(gè)Func 委托, 指向一個(gè)返回int類型的 方法
Console.WriteLine(a());
}
2>指定參數(shù)和返回值的例子
Func<string, int>
最后一個(gè)參數(shù)表示返回值類型呻畸,前面的都是形參類型移盆。
static int Test2(string str){
return 1;
}
static void Main(string[] args){
Func<string, int> a = Test2; // 泛型中最后一個(gè)參數(shù)表示返回值類型。
Console.WriteLine(a("a"));
}
-
Unity使用委托方法
觀察者模式
案例中伤为,場(chǎng)景腳本為發(fā)布者咒循,三個(gè)物體為觀察者。
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("點(diǎn)解了");
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項(xiàng)目中的點(diǎn)擊箱子:
多個(gè)發(fā)布者绞愚,一個(gè)觀察者
撿箱子
案例中:每個(gè)箱子都是發(fā)布者叙甸,而角色身上的腳本就是觀察者。通過(guò)監(jiān)聽(tīng)箱子的委托位衩,來(lái)達(dá)到拾取箱子的目的裆蒸。
// 箱子身上掛在的腳本
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;
// 發(fā)射射線,檢測(cè)名稱為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);
}
}
}
// ========================================================
// 描述:
// 作者:雷潮
// 創(chuàng)建時(shí)間: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;
// 數(shù)據(jù)存儲(chǔ)
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 + "個(gè)箱子");
}
}
我的博客即將同步至 OSCHINA 社區(qū)僚祷,這是我的 OSCHINA ID:osc_98696105,邀請(qǐng)大家一同入駐:https://www.oschina.net/sharing-plan/apply