Unity Scripting : Delegates

Unity Scripting : Delegates

Postby BenChang » Wed Feb 11, 2015 6:27 pm

A delegate is a function that you give to another function or class to take care of some custom behavior in response to an event. In this example, we spawn a bunch of little objects, and then the "A" key triggers a "Kaboom", destroying all the objects within a certain radius. To do this, we keep a List of all the little things, and then we want to search that list and find all the ones where the distance between it and the center of the blast is less than 5. List.Find() is a built-in method for searching lists, and you can give it a delegate function that defines the criteria. Find() iterates the list, and calls your delegate function on each element (basically like writing a for loop). Your delegate function should return true of false.

You can give a named function, sort of like this:

Code: Select all
int AnswerToLifeTheUniverseAndEverything = MyList.Find(MyComparison);

bool MyComparison (int x)
{
  if (x==42)
    return true;
  else
    return false;
}


One limitation is scope. MyComparison () is not in the scope of the function you called Find() from, so it will not have access to properties and variables that you might need. In this case, I need access to the GameObject's position, because I want to compare distance to it, not check absolute world position. I need to access gameObject.transform.position, but with a standalone delegate function I can't do that. So, I use an anonymous delegate function instead: these exist within current scope so I can access the gameObject.transform property.

Code: Select all
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class DelegateExample : MonoBehaviour {
   public GameObject prefab;
   
   private List<GameObject> things;
   
   void Start () {
      things = new List<GameObject>();
      
      for (int i=0;i<200;i++)
       {
          GameObject g = Instantiate(prefab) as GameObject;
         things.Add(g);
         Vector2 pos = Random.insideUnitCircle * 10;
         g.transform.position = new Vector3(pos.x, 0, pos.y);
      }
   }
   
   // Update is called once per frame
   void Update () {
      if (Input.GetKeyDown (KeyCode.A))
      {
         Kaboom();
      }
   }
   
   void Kaboom ()
   {
      List<GameObject> sublist = things.FindAll(
         delegate (GameObject obj)
         {
            float d = Vector3.Distance(obj.transform.position, transform.position);
            
            if (d < 5)
               return true;
            else
               return false;            
         }
      );

      foreach (GameObject g in sublist)
      {
         Destroy (g);
         things.Remove (g);
      }   
   }
}

User avatar
BenChang
 
Posts: 176
Joined: Mon Jan 17, 2011 4:48 pm

Return to Game Development

Who is online

Users browsing this forum: No registered users and 1 guest

cron