【问题标题】:Is there something like a Runnable in Unity?Unity中有类似Runnable的东西吗?
【发布时间】:2016-05-18 21:53:06
【问题描述】:

我是 Unity 新手,对它了解不多。但是,我过去曾使用过 Java 和 Objective-C。两种面向对象的基于 C 的编程语言,非常类似于 Unity 使用的 C#。

Objective-C 有blocks 是变量,允许您在其中存储函数并稍后调用它们。实际使用时,可以将块用作函数参数和类属性,省去程序员的“if”语句,而直接调用块。

该语法的一个示例是(取自链接的教程站点):

// Declare a block variable
double (^distanceFromRateAndTime)(double rate, double time);

// Create and assign the block
distanceFromRateAndTime = ^double(double rate, double time) {
   return rate * time;
};

// Call the block
double dx = distanceFromRateAndTime(35, 1.5);

NSLog(@"A car driving 35 mph will travel %.2f miles in 1.5 hours.", dx);

Java 有Runnable 类,这是其多线程结构的基础。 (Thread 继承自 Runnable。)我从 previous question 我问过这个类。制作Runnable的方法有两种:Java 8 使用 lambdas 的方式...

Runnable r = () -> { System.out.println("This is just an example!"); }

Java 8 使用 lambdas 作为函数参数...

void someFunction(Runnable r) {
    r.run();
}

// In a method, not sure about the semicolons
someFunction( () -> { System.out.println("This will work, too!"); });

最后,Java 8 之前...

Runnable r = Runnable(){
    @Override
    public void run() {
         System.out.println("Yet another example");
    }
}

我的问题是,我将如何在 Unity 的 C# 变体中实现这一目标?

【问题讨论】:

  • Action a = () => Console.WriteLine("lambda action");,以及异步操作Task.Run(() => Console.WriteLine("thread pooled"));
  • @Mephy 谢谢!我只需要了解Action 类。我可以在运行代码周围加上大括号并使用多行语句吗?
  • 您好 DDPWNAGE。有一件事,理解 Unity 是绝对单线程至关重要。没有其他线程,您无法访问任何其他线程。 (请注意,您可能见过“协程”。它们与线程完全没有任何联系。)
  • 您可能面临的另一个问题是,在第一段中您提到了“面向对象”。意识到 Unity 绝对不是面向对象的,它是一个 ECS 系统,这一点至关重要。它没有任何类似于继承的概念,并且与 OO 完全无关。 (关于stackoverflow.com/a/37243035/294884 的文章)碰巧,用于 Unity GameObects 编写行为的(当前)编程语言(c#)恰好是一种OO 语言。但这无关紧要。他们明天可能会改用 Lisp :) 或其他东西,这不会影响 Unity。
  • @JoeBlow 这解释了 JavaScript。谢谢你的澄清。

标签: c# unity3d lambda


【解决方案1】:

Action 委托将是等效的,没有多线程方面。您可以通过指定参数列表、'=>' 符号和结果表达式来使用表达式,该表达式也可以是一个块。如果返回类型为非 void,则可以使用 Func。

Action a = () => Console.WriteLine("a");
Action b = x => Console.WriteLine(x);
Action c = (x, y, z) => {
    Console.WriteLine(x);
    Console.WriteLine(y);
    Console.WriteLine(z);
}
Func<int, int, int> add = (x, y) => x + y; // last type is return-type

许多多线程库将接受动作和函数作为参数,包括核心 TPL,其中包括像 Task.RunTask.ForEach 这样的方法。在操作 os 集合时,PLINQ 扩展(Parallel Linq)是一个很好的工具,可以将函数链接在一起。

【讨论】:

  • 非常感谢您的澄清! ?
  • HI @DDPWNAGE 尽管你已经勾选了这个答案,但我必须再次强调 Unity 完全是单线程的。你似乎走在完全错误的轨道上。如果这有意义的话,没有 Unity 工程师会问你要问的问题。 Unity 没有线程。 Unity 中绝对没有“类似线程的习语”。您永远不会想到线程和线程将完全不参与您的 Unity 工作生活。
  • 不一定正确。只要不调用Unity API,就可以在Unity3D中使用多线程代码,这不是线程安全的。
【解决方案2】:

在 C# 中称为 Action,您使用 lambda 运算符 =&gt;

Action action = () => Console.WriteLine("This is just an example!");

您也可以传递它:

// single line statement doesn't need to be wrapped in a {code block}, and you don't need the `;` at the end
SomeFunction(() => Console.WriteLine("This will work, too!"));

SomeFunction(() =>
{
    //multiline statements
    Console.WriteLine("This will work, too!");
    Console.WriteLine("This will work, too!x2");
    Console.WriteLine("This will work, too!x3");
});

void SomeFunction(Action action)
{
    action();
}

【讨论】:

    猜你喜欢
    • 2020-04-10
    • 2021-08-04
    • 2012-05-31
    • 2012-11-27
    • 2017-11-21
    • 2012-08-03
    • 2015-08-25
    • 1970-01-01
    • 2015-11-14
    相关资源
    最近更新 更多