• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by asters · Oct 26, 2016 at 10:36 PM · serializationscriptableobjectinstantiationeditor extensionreferences

How to break reference from .asset classes and runtime copied values?

Hello, I have an issue with the .assets files I created through a editor extension I made myself. Basically I create in a base class, a List containing my objects. These are complex objects containing other variables that get their value from other .asset files (in the editor), everything is serialized of course. Everything works fine, I can perform all the operations both in the editor and in game. The problem is that even if when I start the game I copy the values of the base List in an array with CopyTo, any change I make to any variable in the object is saved to the .asset file. Moreover, if I add the same object multiple times in the array and modify one of them, every object that uses the same variable changes accordingly. What I would like to do is: 1) to break the link between instantiated objects in game and the .asset database 2)break the link between objects that use the same value for a variable (coming from another .asset file), so that if I modify a variable in one object the changes do not propagate to the other objects.

I am afraid I was not clear enough but any help is appreciated.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

2 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by Adam-Mechtley · Oct 27, 2016 at 07:13 AM

Hi @asters! If I understand correctly, you need to:

  1. Assuming your .asset is a ScriptableObject of some kind, you need to call Instantiate() when your game starts to create a duplicate. Make any run-time modifications on the duplicate rather than on the source asset.

  2. You need to make sure that when you assign the same item to multiple different list indices that it is a copy. If the list element is a value type (e.g., float, int, struct) this is automatic. If it is a reference type (e.g., any class object) then you need to make sure you are assigning a copy. If the elements are a subclass of UnityEngine.Object, do the same as step 1 for each duplicated element. If they are a custom class of some kind, then you need to do something like make them ICloneable or otherwise copy any necessary data to a new instance.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
0

Answer by asters · Oct 27, 2016 at 06:13 PM

Thank you, I was able to solve my problem and I learned something in the process while doing so, thank to your explanation. Basically what I needed was a so called "Deep Copy" of my main Class. You can do it as you said, making the classes ICloneable and implementing a symple Clone() function for them to make a copy without reference of the variables, so with a main function that did that starting from the outer class and going down to all referenced objects. I used a more lazy but quite effective approach, using this helper function: using System; using System.IO; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary;

 /// <span class="code-SummaryComment"><summary></span>
 /// Provides a method for performing a deep copy of an object.
 /// Binary Serialization is used to perform the copy.
 /// <span class="code-SummaryComment"></summary></span>
 public static class ObjectCopier
 {
     /// <span class="code-SummaryComment"><summary></span>
     /// Perform a deep Copy of the object.
     /// <span class="code-SummaryComment"></summary></span>
     /// <span class="code-SummaryComment"><typeparam name="T">The type of object being copied.</typeparam></span>
     /// <span class="code-SummaryComment"><param name="source">The object instance to copy.</param></span>
     /// <span class="code-SummaryComment"><returns>The copied object.</returns></span>
     public static T Clone<T>(this T source)
     {
         if (!typeof(T).IsSerializable)
         {
             throw new ArgumentException("The type must be serializable.", "source");
         }
 
         // Don't serialize a null object, simply return the default for that object
         if (Object.ReferenceEquals(source, null))
         {
             return default(T);
         }
 
         IFormatter formatter = new BinaryFormatter();
         Stream stream = new MemoryStream();
         using (stream)
         {
             formatter.Serialize(stream, source);
             stream.Seek(0, SeekOrigin.Begin);
             return (T)formatter.Deserialize(stream);
         }
     }
 }

It serializes your Object (Class, List, etc.) and deserializes it into a new Object, so you get a fresh copy of everything, free of any reference. The only drawback is that every class must be tagged serializable, but in my case I had to add it for just a couple of them. Here is the source of this script for anyone who will stumble into my same problem: http://www.codeproject.com/Articles/23832/Implementing-Deep-Cloning-via-Serializing-objects

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

78 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How to write a Story Event System with ScriptableObjects? 0 Answers

Keep editor variable value 0 Answers

ScriptableObject not Serializing? 0 Answers

Serialize a list of class containing ScriptableObject assets 0 Answers

[SOLVED] ScriptableObject generic list makes all derived instances to base type when serializing 1 Answer

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges