2016-04-16 42 views
1

讓我們直接看一個例子。假設我們有:從Update方法移出比較:使用委託或其他方法?

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

我認爲這不是很優雅的解決方案。 Unity需要對每一幀進行比較。這對我來說聽起來不太合適。我只是猜測它應該是一些其他的方式來實現相同的:

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

Update() { 
    movement(); 
} 

我想解決方案是與代表有關。這就是爲什麼我建議的解決方案看起來像代表。我不明白什麼代表都很好。

+1

你需要委託和事件來做到這一點。我建議你看下面的兩個視頻,因爲你提到你不明白代表是什麼:https://unity3d.com/learn/tutorials/modules/intermediate/scripting/delegates https://unity3d.com/learn/tutorials/modules/intermediate/scripting/events – Programmer

+0

[Unity中的簡單事件系統]的可能重複(http://stackoverflow.com/questions/36244660/simple-event-system-in-unity) – Fattie

+0

@JoeBlow您的評論聲音對我來說,比起IlonaHari提出的更好的解決方案。我們能做什麼?編輯包含你的解決方案?如果你願意,我可以爲你做。謝謝! – chelder

回答

0

Joe Blow在評論中寫下我最喜歡的答案:

Unity是基於組件的產品。我們最好switch to Component-Based Thinking而不是與代表一起工作。

因此,製作兩個(或更多)不同的腳本,並將其放在遊戲對象上。然後,根據需要打開和關閉這些組件。

因此,我們將不得不加入到我們的遊戲對象的腳本:MoveGameObjectInACircularWay.csMoveGameObjectInALinearWay.cs。然後,MainGameObjectScript.cs也加入到我們的遊戲對象用下面的代碼:

void Start() { 
    GetComponent()<MoveGameObjectInACircularWay>.active = true; 
    GetComponent()<MoveGameObjectInALinearWay>.active = false; 
} 
2

從MSDN「在C#委託是類似於在C或C的函數指針++。使用代表允許程序員封裝委託對象內的方法的參考。」(https://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx)總之是一種指向方法的指針。你想要做的是以下幾點:

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"); 
    } 
} 

你聲明的函數必須和委託簽名具有相同的簽名。如果你想添加參數,例如。一個int,decalre將委託作爲

public delegate void MovementDelegate(int speed); 

以及實現功能

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

和呼叫更改爲

movementFunction(yourIntHere) 

已更新!:感謝喬吹建議這裏是另一種解決方案:

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); 
    } 
} 
+0

但是,請考慮此QA http://stackoverflow.com/q/18740815/294884 – Fattie

+0

更新了您的建議。 –

+0

你的答案現在倍加珍貴! :) – Fattie