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 /
avatar image
0
Question by jcfrizz · Jun 18, 2018 at 10:18 PM · c#listitemcopyobject pool

How to make a deep copy instead of a shallow one?

Hi everyone, so as of right now I am making a shallow copy of an item in a list. When I click on this item in game, a copy is made of it and that copy is put in another list. The problem is, when I click on this item more than once, I want each individual copy of this original item to still have different elements. Since a shallow copy is being made right now, each clone is exactly the same... which is not what I want. I am pretty sure the way to do this is to create a deep copy instead, but I don't know how to change my code to be a deep copy.

To be more specific, I want the time I create each copied item to be different on each one. So when the first time the item is copied, the time on copy1 is 1:00. The second time the item is copied, the time on copy2 is 1:05. That sort of thing. Here is my code below:

 [System.Serializable]
 public class Item
 {
     public string activityName;
     public Sprite icon;
     public float Productivity = 1f;
     public float Social = 1f;
     public float Health = 1f;
     public float Fun = 1f;
 
     public string dateButtonAdded;
     public string timeAdded;
 
     public Sprite checkMark;
 }
 
     public void Setup(Item currentItem, ActivityScrollList currentScrolllist){
 
         item = currentItem;
 
         nameLabel.text = item.activityName;
         iconImage.sprite = item.icon;
 
         prodValue.text = item.Productivity.ToString ();
         socValue.text = item.Social.ToString ();
         healthValue.text = item.Health.ToString ();
         funValue.text = item.Fun.ToString ();
 
         checkMark.sprite = item.checkMark;
 
         scrollList = currentScrolllist;
 
     }

I create this items through a simple object pool. I got the code for this from a Unity tutorial. Here is the code for the object pool:

 // A very simple object pooling class
 public class SimpleObjectPool : MonoBehaviour
 {
     
     // the prefab that this object pool returns instances of
     public GameObject prefab;
     // collection of currently inactive instances of the prefab
     private Stack<GameObject> inactiveInstances = new Stack<GameObject>();
 
 
     // Returns an instance of the prefab
     public GameObject GetObject() 
     {
         GameObject spawnedGameObject;
 
         // if there is an inactive instance of the prefab ready to return, return that
         if (inactiveInstances.Count > 0) 
         {
             // remove the instance from the collection of inactive instances
             spawnedGameObject = inactiveInstances.Pop();
         }
         // otherwise, create a new instance
         else 
         {
             spawnedGameObject = (GameObject)GameObject.Instantiate(prefab);
 
             // add the PooledObject component to the prefab so we know it came from this pool
             PooledObject pooledObject = spawnedGameObject.AddComponent<PooledObject>();
             pooledObject.pool = this;
         }
 
         // put the instance in the root of the scene and enable it
         spawnedGameObject.transform.SetParent(null);
         spawnedGameObject.SetActive(true);
 
         // return a reference to the instance
         return spawnedGameObject;
     }
 
     // Return an instance of the prefab to the pool
     public void ReturnObject(GameObject toReturn) 
     {
         PooledObject pooledObject = toReturn.GetComponent<PooledObject>();
 
         // if the instance came from this pool, return it to the pool
         if(pooledObject != null && pooledObject.pool == this)
         {
             // make the instance a child of this and disable it
             toReturn.transform.SetParent(transform);
             toReturn.SetActive(false);
 
             // add the instance to the collection of inactive instances
             inactiveInstances.Push(toReturn);
         }
         // otherwise, just destroy it
         else
         {
             Debug.LogWarning(toReturn.name + " was returned to a pool it wasn't spawned from! Destroying.");
             Destroy(toReturn);
         }
     }
 }
 
 // a component that simply identifies the pool that a GameObject came from
 public class PooledObject : MonoBehaviour
 {
     public SimpleObjectPool pool;
 }

So basically I am unsure of how to change my code to be able to create a deep copy instead. Any help on how to do this is greatly appreciated.

Comment
Add comment · Show 4
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 NoDumbQuestion · Jun 19, 2018 at 01:46 AM 0
Share

Ask another question and remove this one.

The question you want to ask is Reversible check point of Object.

Your answer basically is making a Dictionary.

avatar image jcfrizz NoDumbQuestion · Jun 26, 2018 at 05:12 PM 0
Share

Can you expand on this? What is a reversible check point and how does this tie into making a dictionary?

avatar image NoDumbQuestion jcfrizz · Jun 27, 2018 at 01:51 AM 0
Share

Sorry not dictionary, we don't have Stack Dict or Queue Dict in C#.

What you want is make another wrapper Struct or Class

 private Stack<BackupData> inactiveInstances = new Stack<BackupData>();
 
 public class BackupData{
      float time;
      GameObject obj;
 }
avatar image toddisarockstar · Jun 27, 2018 at 01:30 AM 0
Share

this totally depends on what conponents you want to be different about your game objects. when you instantiate a game object it is not going to make multiply copys of the image files used for texture or the shader or material files or the mesh filesor animation files and blah blah blah. it would be a proficiencey nightmare.

whatever component or propery of a component you want independant you would need to specifically define it with the "new()" command.

scripts are the exeption if they are not marked static. they allready do run independantly when objects are spawned with your custom scripts attached

1 Reply

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

Answer by JDelekto · Jun 27, 2018 at 02:32 AM

The difference between the shallow and deep copy are not just copying the references and value types of an object's fields, but in the case of reference types, creating brand new objects and populating those with copies of its properties, and recursively.

You can provide a DeepCopy method and create a new instance of your object, then copy over simple properties, while reference types need to have new instances created. Because of the shallow copy you are seeing, your variables such as nameLabel, iconImage, prodValue, etc. are just copying the references over to the new object and the data which they contain will be the same between all objects.

It appears that several types in Unity provide an Instantiate method which can take a reference to an existing type and clone it for you. In the case of simple types like bool, float, string, etc. it's a straight copy of the properties, for things like Image, on the other hand, require the instantiation.

Here is an example of something that uses this technique:

 public class Item {
 
     float someValue;
     string someString;
     bool someBoolean;
     Image iconImage;
 
     public Item DeepCopy()
     {
         Item sc = new Item();
 
         sc.someValue = this.someValue;
         sc.someString = this.someString;
         sc.someBoolean = this.someBoolean;
         sc.iconImage = Image.Instantiate<Image>(this.iconImage);
 
         return sc;
     }
 }

One other thing, if you are working with pooled objects and do not want to create a new instance, then you can overload (or replace) your DeepCopy() method and pass a parameter which is a reference to your pooled object. It would then look something like the following (item still returned as a convenience):

     public Item DeepCopy(Item po)
     {
         po.someValue = this.someValue;
         po.someString = this.someString;
         po.someBoolean = this.someBoolean;
         po.iconImage = Image.Instantiate<Image>(this.iconImage);
 
         return po;
     }
 
Comment
Add comment · Show 5 · 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 jcfrizz · Jun 30, 2018 at 04:19 PM 0
Share

Thank you! I will try this out. Just a question... Would I replace this function with my current "Setup()" function? Just making sure I understand this correctly.

avatar image JDelekto jcfrizz · Jun 30, 2018 at 05:55 PM 0
Share

You don't need to replace your Setup() function. The DeepCopy() method I provided goes onto the class that you want to be able to copy.

If you use the DeepCopy version which takes a reference to the object that you want to copy data to, then in your Setup() function, you can just use the single line: currentItem.DeepCopy(this).

You pass the 'this' reference to your item, then currentItem will deep copy its properties into your new object. It is basically populating itself from currentItem.

avatar image jcfrizz JDelekto · Jun 30, 2018 at 09:24 PM 0
Share

I am trying your method but it still doesn't seem to be working for me. I should also note, my setup function is in another class than where I create my item. I will show which function is in which class this time. This is what I have changed so far:

 public class ActivityBookButton : $$anonymous$$onoBehaviour {
 
     public Button button;
     public Text nameLabel;
     public Image iconImage;
     public Text prodValue;
     public Text socValue;
     public Text healthValue;
     public Text funValue;
     public Text timeAdded;
     public Item item;
     private ActivityScrollList scrollList;
 
     public void Setup(Item currentItem, ActivityScrollList currentScrolllist){
 
         item = currentItem;
 
         nameLabel.text = item.activityName;
         iconImage.sprite = item.icon;
         prodValue.text = item.Productivity.ToString();
         socValue.text = item.Social.ToString ();
         healthValue.text = item.Health.ToString ();
         funValue.text = item.Fun.ToString ();
         timeAdded.text = currentItem.timeAdded;
 
         scrollList = currentScrolllist;
 
     }

 [System.Serializable]
 public class Item
 {
     public string activityName;
     public Sprite icon;
     public float Productivity = 1f;
     public float Social = 1f;
     public float Health = 1f;
     public float Fun = 1f;
     public string dateButtonAdded;
     public string timeAdded;
 
     public Item DeepCopy()
     {
         Item po = new Item ();
 
         po.activityName = this.activityName;
         po.icon = this.icon;
         po.Productivity = this.Productivity;
         po.Social = this.Social;
         po.Health = this.Health;
         po.Fun = this.Fun;
         po.dateButtonAdded = this.dateButtonAdded;
         po.timeAdded = this.timeAdded;
 
         return po;
     }
 }

I'm sorry if these seem like basic questions but I am pretty new to all of this so I'm not really sure where I am going wrong now. Why is everything still exactly the same even though I added the DeepCopy function? Thanks in advance.

Show more comments

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

515 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 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 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 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 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 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 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

copy an list in c# 1 Answer

A node in a childnode? 1 Answer

Copy From Array to List without reference [C#] 2 Answers

Add item to string by name? 1 Answer

How do get a specific item in a list? 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