自动填充脚本对象

时间:2018-11-10 09:38:23

标签: c# unity3d

我的一些可编写脚本的对象(用于播种我的初始游戏数据)包含大型2维数组(如10x10),我使用外部Python脚本生成其二维数组。我也确实使用了Odin检查器插件,为我序列化2d数组,并在Unity编辑器中为我提供了该数组的漂亮表示。

我只是这样做:

[TableMatrix()]
public int[,] table = new int[10, 10];

这只是一个Odin SerializedScriptableObject类。

问题是,我真的想避免必须使用Unity编辑器手动添加10x10元素,而且我希望我的对象具有可变的2d数组大小,一个可能是beb(10,10),另一个可能是( 5,5)。有没有办法以编程方式填充我的可编写脚本的对象来实现这一目标? (或者,如果有人知道,Odin检查器插件是否支持类似的功能?)

谢谢!

3 个答案:

答案 0 :(得分:1)

对不起@Spyros的回复。

我的方法与@D Manokhin方法类似,但是我将使用多维数组(而不是使用锯齿状数组(因为您可以构建自定义编辑器脚本来可视化它们),我敢肯定,您可以可视化锯齿状数组在没有插件的编辑器中,我从未使用过Odin插件。)

因此,我delcare一个将存储名为TileData的结构的类:

using UnityEngine;
using System.Collections;

[System.Serializable]
public class TileData
{
    /*
     * rows
        [rowData][rowData][rowData]
        [cell]  ->value
                ->type
        [cell]  ->value
                ->type
        [cell]  ->value
                ->type
    */

    [System.Serializable]
    public struct cell
    {
        public float value;
        public string type;
    }


    [System.Serializable]
    public struct rowData
    {
        public cell[] row;
    }

    public rowData[] rows;

}

我使用valuetype作为“示例”,这完全由您决定,如果需要,您还可以存储Vector3!

然后,如何调用和使用这种结构?让我们看看:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Matrix : MonoBehaviour {

    //declare the structure that will store the data
    public TileData tileData = new TileData();    

    //those are public so you could make the matrix with the size you want..
    //..ideally dynamically call it from your python file requisits
    public int horizontalMatrixSize = 10;  
    public int verticalMatrixSize = 10;

    // Use this for initialization
    void Start()
    {        
        //Create the matrix structure and fill it
        tileData.rows = new TileData.rowData[horizontalMatrixSize];
        for (int i = 0; i < tileData.rows.Length; i++)
        {
            tileData.rows[i].row = new TileData.cell[verticalMatrixSize];
            for (int u = 0; u < tileData.rows[i].row.Length; u++)
            {                
                tileData.rows[i].row[u].value = GetValuesFromPythonFileOrWhatever();
                tileData.rows[i].row[u].type = GetValuesFromPythonFileOrWhatever();
            }
        }
    }

}

但是,如果您真的喜欢锯齿状的结构,则仍然可以使用它(但请记住,它不会在编辑器中显示),如下所示:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Matrix : MonoBehaviour {
    //declare the structure that will store the data
    [SerializeField] private float[,] grayscaleBidimensional = null;

    //those are public so you could make the matrix with the size you want..
    //..ideally dynamically call it from your python file requisits
    public int horizontalMatrixSize = 10;  
    public int verticalMatrixSize = 10;

    // Use this for initialization
    void Start()
    {        
        //Create the matrix structure and fill it
        tileData.rows = new TileData.rowData[horizontalMatrixSize];

        grayscaleBidimensional = new float[horizontalMatrixSize, verticalMatrixSize];
        for (int x = 0; x < horizontalMatrixSize; x++)
        {
            for (int y = 0; y < verticalMatrixSize; y++)
            {
                grayscaleBidimensional[x, y] = GetValuesFromPythonFileOrWhatever();
            }
        }
    }

}

请记住,您可以根据需要设置对象的值,因此它们不必具有静态大小!

答案 1 :(得分:0)

要更改单个值,可以执行table[x,y] = (your value)。假设您想用数字1填充每个值,可以这样做:

for (int y = 0; y < 10; y++)
{
    for (int x = 0; x < 10; x++)
    {
        table[x, y] = 1;
    }
}

希望能回答您的问题,对不起,如果代码错误-我目前无法访问Unity,因此您可能需要摆弄它。

答案 2 :(得分:0)

您应该将数组序列化为python中的文件,然后使用脚本导入器将其导入Unity,在ScriptableObject中构造数组,并填写其值。

https://docs.unity3d.com/Manual/ScriptedImporters.html