Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • 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 Zankaster · 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 Zankaster · 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.

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

Recursive serialization error? 0 Answers

Serialization issue after updating Unity from 2018.2.1 to 2019.2.6 1 Answer

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

Using dictionaries in scriptable objects to store crafting recipe's 0 Answers

Keep editor variable value 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges