【问题标题】:Unity C# Array type error (when converting from unityscript)Unity C# 数组类型错误(从 unityscript 转换时)
【发布时间】:2012-11-12 05:46:36
【问题描述】:

我正在尝试将这段简化的代码从 unityscript 转换(并理解)为 C#:

private var actionList = new Array();                                                           

function Start()
{
actionList = new Array(12);

for(i=0; i<actionList.length; i++) 
    actionList[i] = new Array(4);
for(i=0; i<actionList.length; i++)
{
    actionList[i][1] = Rect(50+(i*55),50, 50, 50);        
    actionList[i][2] = new Array("action");     
}
actionList[0][3] = KeyCode.Alpha1;
actionList[1][3] = KeyCode.Alpha2;
actionList[2][3] = KeyCode.Alpha3;
actionList[3][3] = KeyCode.Alpha4;
actionList[4][3] = KeyCode.Alpha5;
actionList[5][3] = KeyCode.Alpha6;
actionList[6][3] = KeyCode.Alpha7;
actionList[7][3] = KeyCode.Alpha8;
actionList[8][3] = KeyCode.Alpha9;
actionList[9][3] = KeyCode.Alpha0;
actionList[10][3] = KeyCode.Minus;
actionList[11][3] = KeyCode.Equals;
}

function OnGUI()
{
for(i=0; i<actionList.length; i++)
    {
    if(actionList[i][1] != null)
        drawButton(actionList[i][1]);
    }
}

function drawButton(rect)
{
    GUI.Button(rect, "Hello");
}

完整的代码可以在这里找到:Creating a Drag and Drop Spell Bar

我在 C# 中对此的看法(省略了键映射):

using UnityEngine;
using System.Collections.Generic;

public class SpellBar : MonoBehaviour
{
private object[][] actionList;

void Start()
{
actionList = new object[12][];

for (int i=0; i<actionList.Length; i++)
    actionList[i] = new object[4];
for (int i=0; i<actionList.Length; i++)
{
    actionList[i][1] = new Rect(50+(i*55), 50, 50, 50);
}

//Keymappings
}

void OnGUI() 
{
for(int i=0; i<actionList.Length; i++)
    {
    if(actionList[i][1] != null)
        DrawButton(actionList[i][1]);
    }
}

void DrawButton(Rect rect)
{
    GUI.Button(rect,"Hello");
}
}

我在使用 DrawButton(actionListi) 时遇到的错误出现在 OnGui 中。 错误:无法将“对象”表达式转换为类型“UnityEngine,Rect”。

我在 unityscript 或 C# 方面都不是经验丰富的程序员。我在谷歌上搜索了几个小时,尝试了 Lists、ArrayLists 等,但找不到解决方案。提前谢谢!

编辑 27-11-2012
所以,我遇到了一个新的相关问题。不知道我是否应该在此处编辑此内容,但我无法在回复中正确格式化。
在我尝试转换的 JavaScript 代码中,以下代码用于将类存储在数组中:

var openSlot = getNextSlot(actionList);    
if(openSlot != -1)
    actionList[openSlot][0] = new classEvilSmile();

虽然这不完全是我想要的方式,但我希望能够将方法存储在数组中,但我找不到在 C# 中执行此操作的方法。这根本不可能吗?
(示例)我正在尝试做这样的事情:

//In addition to what I posted above
void Start()
{
actionList[i][0] = void FireBall();
}

void FireBall()
{
Texture2D icon = Resources.Load("icon_fireball") as Texture2D;
String description = new String("Shoot a ball of fire");

//etc
}

【问题讨论】:

  • 那不是 Java。它可能是 Javascript,但不是 Java。
  • 当我听到人们混淆“Java”和“Javascript”时,我感到畏缩。有表面上的相似之处——但在最重要的方面,“Java”和“Javascript”是天壤之别。我编辑了帖子并将标题更改为“Javascript”。

标签: c# unity3d unityscript


【解决方案1】:

与 Javascript 不同,C# 是强类型的,这意味着您不能将 object 传递给请求 Rectangle 的方法。您必须为该方法提供确切的类型,或从该类型派生的子项。

所以,而不是

private object[][] actionList;

你应该有

private Rectangle[][] actionList;

强类型语言会执行大量编译时验证,以查看您是否没有将错误的变量类型传递给错误的方法参数。优点有两个,首先您不必在运行时执行测试来知道变量是否属于正确的类型。其次,它提供了一种简单的方法来查找代码中的错误,而无需运行代码的每一部分。如果它编译,你已经完成了 80%。

但是,如果您想在该数组中组合不同的类型,则有多种选择。您可以使用Tuple&lt;&gt; 之类的类来组合一组没有匹配类型的对象,或者您可以将object 转换为Rectangle,然后再将其提供给如下方法:

DrawButton((Rectangle)actionList[i][1]);

但是,如果强制转换无效,您将获得运行时断言。

【讨论】:

  • 感谢您的快速回复!我在 Unity 中找不到关于 Tuple 的文档(不知道如何实现),但转换为矩形是有效的。你会说这不是正确的方法吗?如果是这样,你会建议什么而不是对象数组?再次感谢
  • @downdf: Tuple&lt;&gt; 不是 Unity 类,它是 .NET 4+ 类,但本质上,它只是围绕一组对象的通用包装器。假设您总是有一个 Rectangle 和一个字符串作为名称。你可以做List&lt;Tuple&lt;string, Rectangle&gt;&gt;。所以,这是一个总是包含字符串和矩形组合的列表。 msdn.microsoft.com/en-us/library/system.tuple(v=vs.100).aspx 最好的方法是无需演员即可管理,因为它涉及一些运行时成本,并且通常使代码更易于阅读,因为您知道什么是什么。但如果你更喜欢有演员表,也可以。
  • 我用一个相关的问题编辑了我的 OP(希望这就是这里所做的事情),如果你能看看它,将不胜感激。干杯!
  • @downdf: 引用 void?你的意思是数组中的一个空槽?关键字是null。如MyObject = null; if (MyObject == null)。就像我说的,变量是用 C# 输入的,你不需要在里面放什么东西让编译器知道应该或者可以放什么。
  • 该死的你真快!不确定我是否完全理解你的答案,但我想我没有清楚地问这个问题。我想我想问的是:您可以将方法存储在数组中吗?将 OP“对 void 的引用”编辑为“方法”。
猜你喜欢
  • 2013-10-05
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-26
  • 2014-10-27
  • 2017-06-09
  • 1970-01-01
相关资源
最近更新 更多