简体   繁体   English

自动填充可编写脚本的对象

[英]Populate Scriptable Objects Automatically

A few of my Scriptable Objects(used for seeding my initial game data) contain large 2 dimensional arrays (like 10x10), the data of which i am generating with an external Python script.我的一些可编写脚本的对象(用于播种我的初始游戏数据)包含大型二维数组(如 10x10),我使用外部 Python 脚本生成其中的数据。 I do use the Odin inspector plugin as well, to serialize the 2d array for me and provide me with a nice representation of that array inside the Unity editor.我也使用 Odin 检查器插件来为我序列化二维数组,并在 Unity 编辑器中为我提供该数组的良好表示。

I am simply doing it like this :我只是这样做:

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

and this is just an Odin SerializedScriptableObject class.这只是一个 Odin SerializedScriptableObject 类。

The problem is, I really want to avoid having to add the 10x10 elements by hand using the Unity editor and also I want my objects to have variable 2d array sizes, one could beb (10,10), another could be (5,5).问题是,我真的想避免使用 Unity 编辑器手动添加 10x10 元素,而且我希望我的对象具有可变的二维数组大小,一个可能是 (10,10),另一个可能是 (5,5 )。 Is there a way to populate my scriptable objects programmatically to achieve that ?有没有办法以编程方式填充我的可编写脚本的对象来实现这一目标? (Or does the Odin inspector plugin support something like that if anyone knows ?) (或者,如果有人知道,Odin 检查器插件是否支持类似的东西?)

Thanks !谢谢 !

Sorry for the late response @Spyros.抱歉@Spyros 回复晚了。

My approach will be similar to @D Manokhin approach, but instead of using jagged array I'll use a multidimensional array (cause you can build a custom editor script to visualize them, I'm pretty sure you can visualize jagged arrays on editor without plugins, I've never used Odin plugin).我的方法将类似于@D Manokhin 方法,但我将使用多维数组而不是使用锯齿状数组(因为您可以构建自定义编辑器脚本来可视化它们,我很确定您可以在编辑器上可视化锯齿状数组而无需插件,我从未使用过 Odin 插件)。

So I delcare one class who will store the structs called TileData :所以我定义了一个将存储名为TileData的结构的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;

}

I used value and type as an "examples", it's absolutly up to you, you can also store Vector3 if you want!我使用valuetype作为“示例”,这完全取决于您,如果您愿意,您也可以存储 Vector3!

Then, how to call and use this kind of structure?那么,如何调用和使用这种结构呢? Let's see:让我们来看看:

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();
            }
        }
    }

}

But if you really like the jagged structure, you can still use it (but remember that will not be represented on editor) like this:但是如果你真的喜欢锯齿状的结构,你仍然可以像这样使用它(但请记住它不会在编辑器中显示):

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();
            }
        }
    }

}

Remember that you can make the values of the objects as you want, so they don't need to have an static size!请记住,您可以根据需要创建对象的值,因此它们不需要具有静态大小!

To change an individual value, you can do table[x,y] = (your value) .要更改单个值,您可以执行table[x,y] = (your value) Lets say you want to fill every value with the number one, you could do:假设您想用第一个填充每个值,您可以这样做:

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

Hope that answers your question and sorry if the code is wrong - I don't have access to Unity at the moment, so you may need to fiddle around with it.希望能回答您的问题,如果代码有误,请见谅 - 我目前无法访问 Unity,因此您可能需要摆弄它。

You should serialize the arrays out to files in python, and then use a Scripted Importer to import them into Unity, construct the arrays in the ScriptableObject, and fill in their values.您应该将数组序列化为 python 中的文件,然后使用脚本导入器将它们导入 Unity,在 ScriptableObject 中构造数组,并填写它们的值。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM