将代码行作为参数传递给函数

时间:2017-05-16 10:51:39

标签: c# unity3d unity5

我希望将一行代码传递给我在c#中调用的函数,目的是优化我的代码并尝试学习新的东西。我熟悉使用我在代码中显示的字符串,整数,浮点数,布尔值。

我们的想法是在按钮单击上调用一个函数来停止脚本并再次启动脚本。没有该代码正在运行的功能:

public void PlayOnClick()
{
    if(count != 1)
    {
        m_animator.GetComponent<Animator>().Play("Scale");
        d_animator.GetComponent<Animator>().Play("CloseUp");
        ((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Play();
        Dialyser.GetComponent<RotationByMouseDrag>().enabled = false;
        count = 1;
    }
    else
    {
        m_animator.GetComponent<Animator>().Play("Scale");
        d_animator.GetComponent<Animator>().Play("ScaleDown");
        ((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Stop();
        Dialyser.GetComponent<RotationByMouseDrag>().enabled = true;
        count = 0;
    }     
}

但我相信这可以缩短。到目前为止我有这个:

void Lock(string A, string B, ? C, bool D, int E)
{
    m_animator.GetComponent<Animator>().Play(A);
    d_animator.GetComponent<Animator>().Play(B);
    C;
    Dialyser.GetComponent<RotationByMouseDrag>().enabled = D;
    count = E;

}

在函数C中,我想在按下一次时传递以下行:

((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Stop();

再次按下时再改变它:

((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Play();

我遇到了eval - 但我相信这只是针对javascript而且可能是处理器密集型的。我已经研究过将该行解析为字符串。

我目前正在搜索和尝试上获胜。有谁可以为我解释这个问题?

2 个答案:

答案 0 :(得分:4)

您正在寻找的是c ++术语中的委托或函数指针。

您可以在delegates找到更多信息。

Actions可能会更快地编码。

基本上,您可以传递对要执行的方法的引用。方法的签名应与方法中声明的参数类型完全相同。因此,如果您希望传递并运行一段不返回任何值的代码,则可以使用Action类型,而不使用任何类型参数。例如

class A {
    void printAndExecute(String textToPrint, Action voidMethodToExecute) {
        Debug.Log(textToPrint);
        voidMethodToExecute();
    }
}

class B : MonoBehaviour {
    void Start() {
        new A().printAndExecute("SAY", sayHello);
    }

    void sayHello() {
        Debug.Log("Hello!");
    }
}

希望有所帮助

答案 1 :(得分:3)

您必须传递Action类型或自定义代理:

void Lock(string A, string B, System.Action C, bool D, int E)
{
    m_animator.GetComponent<Animator>().Play(A);
    d_animator.GetComponent<Animator>().Play(B);
    C();
    Dialyser.GetComponent<RotationByMouseDrag>().enabled = D;
    count = E;    
}

// ...

Lock("Scale", "CloseUp", ((MovieTexture)MovieOne.GetComponent<Renderer>().material.mainTexture).Play, false, 1 ) ;