最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Unity copy data from scriptable object without link - Stack Overflow

programmeradmin1浏览0评论

In my card game, I have a scriptable object that contains data about what cards the algorithm should place on its turn.

public class Structures : ScriptableObject
{
    public List<Card> Cards;
    public List<int> x;
    public List<int> y;
}

When it plays this structure using the "Prepare" behavior pattern, it copies the data into a separate variable at the beginning of the algorithm, then starts checking the first element of each list and deleting it on each turn.

private Structures playingStructure = null;
private void PlayPrepare()
{
    if(playingStructure == null)
    {
        int index = FindIndexOfStrutureByPatternIndex();
        if (index >= 0)
        {
            playingStructure = pattern.structures[index];
        }
        else Debug.LogError("index not found");
    }
    if(playingStructure != null)
    {
        try
        {
            gridManager.AddObjectToGridByAI(playingStructure.Cards[0], CardPrefab, (playingStructure.x[0] , playingStructure.y[0]));
            playingStructure.Cards.RemoveAt(0);
            playingStructure.x.RemoveAt(0);
            playingStructure.y.RemoveAt(0);
        }
        catch 
        {
            playingStructure = null;
            IsPlayingByTrigger = false;
            PlaceCards();
        }
    }
}

By deleting data from the playingStructure variable, the data is deleted from the original scriptable object.

Why? How do I copy data from a scriptable object so that it is not linked to the original?

In my card game, I have a scriptable object that contains data about what cards the algorithm should place on its turn.

public class Structures : ScriptableObject
{
    public List<Card> Cards;
    public List<int> x;
    public List<int> y;
}

When it plays this structure using the "Prepare" behavior pattern, it copies the data into a separate variable at the beginning of the algorithm, then starts checking the first element of each list and deleting it on each turn.

private Structures playingStructure = null;
private void PlayPrepare()
{
    if(playingStructure == null)
    {
        int index = FindIndexOfStrutureByPatternIndex();
        if (index >= 0)
        {
            playingStructure = pattern.structures[index];
        }
        else Debug.LogError("index not found");
    }
    if(playingStructure != null)
    {
        try
        {
            gridManager.AddObjectToGridByAI(playingStructure.Cards[0], CardPrefab, (playingStructure.x[0] , playingStructure.y[0]));
            playingStructure.Cards.RemoveAt(0);
            playingStructure.x.RemoveAt(0);
            playingStructure.y.RemoveAt(0);
        }
        catch 
        {
            playingStructure = null;
            IsPlayingByTrigger = false;
            PlaceCards();
        }
    }
}

By deleting data from the playingStructure variable, the data is deleted from the original scriptable object.

Why? How do I copy data from a scriptable object so that it is not linked to the original?

Share Improve this question asked Feb 4 at 18:24 kryakvakryakva 11 silver badge 0
Add a comment  | 

3 Answers 3

Reset to default 1

You could create a runtime clone using Instantiate

playingStructure = pattern.structures[index];
if(playingStructure)
{
    playingStructure = Instantiate(playingStructure);
}

Even better might be to rather do this only once wherever the list of those structures is stored.

Depending on thy type of Card and whether you modify that on runtime this might be not enough though.

Instantiate basically creates a "deep clone" so the lists will be copied and not linked to the original lists. However, any UnityEngine.Object references in this case (for ScriptableObjects) will remain the same. (For GameObjects only the external ones will remain while anything within the own hierarchy is replaced accordingly)

ScriptableObjects are references, so if you do something with them in code using editor, it will apply permamently (so after you stop the game, the changes will stay).

You can copy the data to normal object or instantiate a clone of your ScriptableObjects.

By the way - if you build the game it will work properly (ScriptableObjects will be ok after restarting the game).

Because when you run

playingStructure = pattern.structures[index];

This assign a reference by the original object to the variable playingStructure. Therefore, all operations on playingStructure are actually performed on the original object.

And as derHugo say,UnityEngine.Object.Instantiate can copy all Serializable data in ScriptableObject,But if you know what data will change,copy it manually like List<int> tx = new List<int>(playingStructure.x) ,performance is better.

发布评论

评论列表(0)

  1. 暂无评论