1

Let's go straight to an example. Let's say we have:

Update(){
   if (value.Equals("circular")) moveGameObjectInACircularWay();
   else if (value.Equals("linear")) moveGameObjectInALinearWay();
}

I think that is not very elegant solution. Unity needs to perform a comparison every frame. That does not sound very optimal to me. I'm just guessing it should be some other way to implement the same like:

Start () {
   if (value.Equals("circular")) movement += moveGameObjectInACircularWay;
   else if (value.Equals("linear")) movement += moveGameObjectInALinearWay;
} 

Update () {
   movement();
}

I guess the solution is related with delegates. That's why my proposed solution looks like delegates. I don't understand what delegates are well yet.

chelder
  • 3,819
  • 6
  • 56
  • 90
  • 1
    you need delegates and events to do this. I suggest you watch the two videos below since you mentioned that you don't understand what delegates are : https://unity3d.com/learn/tutorials/modules/intermediate/scripting/delegates https://unity3d.com/learn/tutorials/modules/intermediate/scripting/events – Programmer Apr 16 '16 at 13:45
  • Possible duplicate of [Simple event system in Unity](http://stackoverflow.com/questions/36244660/simple-event-system-in-unity) – Fattie Apr 16 '16 at 13:53
  • @JoeBlow your comment sounds to me like a better solution than the proposed one by IlonaHari. What could we do? Edit the solution including yours? I can do it for you if you prefer. Thank you! – chelder Apr 19 '16 at 12:02
  • 1
    Note that another approach here is, very simply, make two (or more) different scripts, and put those on the game object in question. Very simply, turn on and off these behaviors as you wish. Very often your state machine will just turn the behaviors on and off as needs be. – Fattie Apr 26 '16 at 13:24

2 Answers2

2

From MSDN "A delegate in C# is similar to a function pointer in C or C++. Using a delegate allows the programmer to encapsulate a reference to a method inside a delegate object." (https://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx) In short is a pointer to a method. What you want to do is the following:

using UnityEngine;
using System.Collections;

public delegate void MovementDelegate();

public class Movement : MonoBehaviour {

    MovementDelegate movementFunction=null;
    public string value = "linear";
    void Start () {
        if (value.Equals("circular")) movementFunction = moveGameObjectInACircularWay;
        else if (value.Equals("linear")) movementFunction =  moveGameObjectInALinearWay;
    }

    // Update is called once per frame
    void Update()
    {
        if (movementFunction != null)
        {
            movementFunction();
        }
    }

    void moveGameObjectInACircularWay()
    {
        Debug.Log("do circular movement here");
    }

    void moveGameObjectInALinearWay()
    {
        Debug.Log("do linear movement here");
    }
}

The functions you declare must have the same signature as the delegate signature. If you want to add parameters to it, ex. an int, decalre your delegate as

public delegate void MovementDelegate(int speed);

and your implementation functions as

void moveGameObjectInACircularWay(int speed)
void moveGameObjectInALinearWay(int speed)

and change the call to

movementFunction(yourIntHere)

UPDATED!: Thanks to Joe Blow suggestion here is another solution:

public class Movement : MonoBehaviour
{
    Action<int> movementFunction = null;

    public string value = "linear";
    void Start()
    {
        if (value.Equals("circular")) movementFunction = moveGameObjectInACircularWay;
        else if (value.Equals("linear")) movementFunction = moveGameObjectInALinearWay;
    }

    // Update is called once per frame
    void Update()
    {
        if (movementFunction != null)
        {
            movementFunction(2);
        }
    }

    void moveGameObjectInACircularWay(int speed)
    {
       Debug.Log("do circular movement here "+ speed);
    }

    void moveGameObjectInALinearWay(int speed)
    {
        Debug.Log("do linear movement here " + speed);
    }
}
Danny Herbert
  • 2,002
  • 1
  • 18
  • 26
Ilona Hari
  • 533
  • 3
  • 14
0

My favorite answer has been written by Joe Blow in the comments:

Unity is components based. We better switch to Component-Based Thinking instead working with delegates.

So make two (or more) different scripts, and put those on the game object in question. Then, turn on and off these components as you wish.

So we would have to scripts added to our game object: MoveGameObjectInACircularWay.cs and MoveGameObjectInALinearWay.cs. Then a MainGameObjectScript.cs also added to our game object with the following code:

void Start () {
   GetComponent()<MoveGameObjectInACircularWay>.active = true;
   GetComponent()<MoveGameObjectInALinearWay>.active = false;
}
chelder
  • 3,819
  • 6
  • 56
  • 90