将不同的参数传递给委托

Pass diverse parameters to a delegate

我希望场景中的许多游戏对象以编程方式具有 Y 位置 "animated"。我有一个 class,我们称它为 "TheGameObject",它不是从 MonoBehaviour 继承的,因此不能具有实现游戏对象的 Y 运动所需的 Update() 函数。 我决定尝试使用委托,但随后出现了一个问题:我只能将一个转换传递给委托。

这是静态 class 中委托的代码,我们称它为 "staticClass",它派生自 MonoBehaviour:

public delegate void UpdatingEventHandler(Transform t);
public static event UpdatingEventHandler Updating;

void Update() {
    if(Updating != null)
        Updating(/*Transform that should be passed*/);
}

这是 "TheGameObject" class 中的代码:

public GameObject gameObject { get; set; }

private void spawn() {
  GameObject go = new GameObject();
  staticClass.Updating += animateYpos(go.transform);
}

void animateYpos(Transform t) {
  //modify t.position.y
}

有没有办法将每个相应的 Transform 传递给委托,以便在静态 class Update() 中调用 Updating() 并让所有游戏对象分别移动? 问题不在于传递的参数类型,而是传递了 哪个 Transform,以便每个不同的 Transform 都将修改自己的 Y 位置。

请考虑 Joe 所说的,但要将多个参数传递给委托,您可以使用此 iirc :

public delegate void DoStuffToTransform(params Transform[] transform);

这是完全错误的,水芹!

经验丰富的开发人员并不真正了解 Unity 是很常见的

不是面向对象的,与继承等概念完全没有联系。

(当然,目前在 Unity 中编写组件所使用的编程语言恰好是 OO,但这在很大程度上是无关紧要的。)

好消息是,解决方案非常简单。

您在 Unity 中所做的就是编写 行为 来执行您想要的操作。

关于它的文章...

试着理解这个概念:假设你的游戏中有一个“机器人攻击装置”。

因此,Unity 场景中唯一的东西就是 GameObjects。 (没有别的 - 根本没有。)

您的“机器人攻击设备”会有这些行为。 (“行为”表示附加到它的组件。组件是 MonoBehavior。)

"robot attack device"
• animate Z position
• shoot every ten seconds
• respond to bashes with sound effect

等等。

鉴于,你的“卡哇伊花”可能有这些行为

"kawaii flower fixed NPC"
• shoot every 5 seconds
• respond to bashes with sound effect
• rainbow animation

在这种情况下,您问的是如何编写“动画 Y”行为。

这很简单,首先请注意,您在 Unity 中所做的所有事情都是通过扩展来完成的,所以它就像

public static void ForceY( this Transform tt, float goY )
    {
    Vector3 p = tt.position;
    p.y = goY;
    tt.position = p;
    }

扩展快速教程:

然后关于为 Y 设置动画的微不足道的组件(所有组件都是微不足道的),就像

public class AlwaysMoveOnYTowards:MonoBehaviour
 {
 [System.NonSerialized] public float targetY;
 void Update()
  {
  float nextY = .. lerp, or whatever, towards targetY;
  transform.ForceY(nexyT);
  }
 }

请注意,当然,您只需根据需要打开和关闭该组件即可。所以如果它睡着了或者你游戏中的任何东西

thatThing.GetComponent().enabled = false;

以及稍后 true 当您再次需要该行为时。

回想一下,您所做的只是为您游戏中的每个东西(LaraCroft、恐龙、kawaiiFlower、子弹......等等)制作一个 模型

(回想一下,在 Unity 中有 两种使用模型的方法,要么使用 Unity 的预制系统(有些喜欢,有些不喜欢),或者只是让模型位于屏幕外,然后根据需要实例化或使用。)

{请注意,最近 Unity 中的一个混乱(选择一个)是:直到几年前,您还必须为您拥有的一些东西编写自己的池。那些日子早已过去,现在永远不要汇集。只是实例化。 Unity 的一个大问题是完全过时的示例代码。}

顺便说一句,在 UI 系统

的情况下,这是同一种 ForceY
public static void ForceYness(this RectTransform rt, float newY)
    {
    Vector2 ap = rt.anchoredPosition;
    ap.y = newY;
    rt.anchoredPosition = ap;
    }

最后,如果您只想将 Y 上的某物动画化到某处一次,您应该进入令人惊叹的

吐温

这是游戏工程的可卡因:


Unity 的一个大问题是人们通常没有意识到制作游戏有多么简单。 (有很多 classic 例子:你会收到 1000 多个问题,询问如何在 Unity 中制作一个(完全微不足道的)计时器,其中 OP 使用协同程序将自己束缚在结中。当然,你只需使用 InvokeInvokeRepeating 99% 的时间用于 Unity 中的计时器。计时器是游戏引擎中最基本的部分之一:当然,很明显 unity 是通过一种微不足道的方式来实现的。)

这是一个“文件夹”(实际上只是一个毫无意义的空游戏对象,这些模型位于其下方)在游戏场景中放置一些模型。

这些是游戏中的一些敌人。作为一名工程师,我只是把它们放在那里,游戏“设计师”会出现并设置质量(所以,土豆很快,萝卜实际上是一个杀不死的老板,飞行的头连接到 google 地图或随便)。

同样,这是来自“文件夹”(另外,如果您使用一个空的游戏对象作为文件夹来存放狗屎,它通常被称为“文件夹” - 它不亚于一个游戏对象)和一些“窥视”(“玩家射弹”)。同样,这些是在游戏中使用的这些东西的 模型 。所以很明显,这些只是坐在屏幕外,就像你在游戏中所做的那样。看,它们就在这里,字面上只是坐在“-10”周围或相机平截头体之外的东西(记住 Unity“相机”的好地方无非...................... GameObject 附有某些组件(为方便起见,Unity 已经编写了这些组件)。)

(再次强调:在许多情况下,您可能更喜欢使用 prefabs。Unity 提供两种方法:预制件或“只是坐在屏幕外”。我个人认为有很多一开始被称为“只是坐在屏幕外”,因为它可以让你设计适当的状态等等;你本来就必须有一个“只是等待”的状态等等,这是非常重要的。我强烈建议你,一开始只是'sit your models around offscreen',一开始不要使用预制件。无论如何那是另一个问题。)

那么 确实是 一些窥视者 ...

谢天谢地,我生来就是一名工程师,而不是一个混蛋“游戏设计师”,所以其他人出现并按照他们认为合适的方式设置了这类东西。 (当然,确实添加了非常重要的(从玩家的角度来看)Component,例如“渲染器”、音效等。

请注意,Cress:您可能会在上面注意到:因为那里的命名中“生活就是这样”(这纯粹是一个命名问题,而不是一个深刻的问题)我们非常不明智地违背了我在这里描述的内容。所以,请注意,我有一个组件应该命名为“Killableness”或者可能只是“projectileness”或者实际上只是“power”或“speed”。正因为生活就是这样,我相当不明智地 将其命名为“导弹”或“射弹”,而不是真正的“飞行”或“攻击力”。你可以看到这是非常非常糟糕 因为当我在下一个项目中重用组件“attackPower”(这里愚蠢地命名为“missile”)时,这涉及到机器人挖掘机或其他东西而不是导弹,每个人都会对我尖叫 “伙计,为什么我们的攻击力组件附加到我们的机器人蜘蛛上,称为 'missile' 而不是 'attack power', WTF?" 我相信你明白我的意思了。

还要注意,那里有一个很好的例子,虽然 Unity 和 GameObject 与计算机科学或编程完全没有联系,它是完全正常 - 如果令人困惑 - 在 编写组件 中,你必须是 OO 的大师,因为 (碰巧) Unity 使用的当前语言确实碰巧是一种 OO 语言(但请记住,他们可以随时更改为使用 Lisp 或其他语言,这不会从根本上影响 Unity。作为一名经验丰富的程序员,您会立即看到 (对于此处讨论的组件) 我有一些类似基础 class“Flightyness”的东西,然后还有子classes,如“ParabolaLikeFlightyness”“StraightlineFlightyness”“BirdFlightyness” " "NonColliderBasedFlightyness" "CrowdNetworkDrivenFlightyness" "AIFlightyness" 等等;你可以看到每个都有“通用”设置(供游戏设计师史蒂夫调整)和更具体的设置(再次供史蒂夫调整)。一些对您来说非常有意义的随机代码片段...

public class Enemy:BaseFrite
    {
    public tk2dSpriteAnimator animMain;
    public string usualAnimName;
    [System.NonSerialized] public Enemies boss;
    
    [Header("For this particular enemy class...")]
    public float typeSpeedFactor;
    public int typeStrength;
    public int value;

public class Missile:Projectile
    {
    [Header("For the missile in particular...")]
    public float splashMeasuredInEnemyHeight;
    public int damageSplashMode;

注意 [Header 的使用……Unity 中最重要的事情之一! :)

请注意“Header”这个东西有多好用,尤其是当你向下链接派生时。在每个人都像这样工作的大项目中工作,为坐在屏幕外的模型制作超级整洁、超级清晰的 Inspector 面板,这不过是一种乐趣。这是一个“Unity 做对了”的案例。等到你得到他们搞砸的东西! :O