Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 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
1
Question by ZoltanErdokovy · May 24, 2013 at 05:36 PM · custom class

GO duplication vs. custom class instances

I add an empty GameObject then my custom component. In the component several instances of other custom classes can be stored, created, deleted. Everything is serialized, properly saved and loaded with the scene.

However when I duplicate the Game Object manually in the editor there is a problem: the GO is new but the component inside is referencing to stuff from the original GO. What I'd like to have is unique instances of everything inside the GO.

What is the proper way of handling this?

The actual system is somewhat complicated but can be boiled down to the following example:

I have GameObject "Pot" and I add component "Plant" to it. That component can create and store instances of the custom class "Berry" (public, serialized, extends C#'s root class). Berry creation is not possible through the inspector.

If I duplicate "Pot" using the editor context menu then I end up with "Pot(2)" containing "Plant(2)" while "Berry" is shared between the two plants. My goal is to have "Berry(2)", a unique copy of the original.

EDIT: Added example. EDIT2: Made it more apparent that duplication is done by the Unity Editor, not from script.

Comment
Add comment · Show 1
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 clunk47 · May 26, 2013 at 04:57 PM 0
Share

Sorry I couldn't help, but voted +1 for a good question. I just haven't done anything w/ custom editor for so long :/

2 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by FL · May 25, 2013 at 11:42 PM

Use the C#'s interface ICloneable and use Clone(). Reference.

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 ZoltanErdokovy · May 26, 2013 at 06:28 AM 0
Share

You mean Clone() should be called by the Unity Editor when it duplicates a GO, component and other contents? $$anonymous$$y tests show that even if Berry implement ICloneable, Clone() is not actually called, but I might be missing something.

avatar image FL · May 26, 2013 at 12:04 PM 0
Share

No. You need to call Clone().

First, try to implement this interface in both Plant and Berry (in your example) and manually add the script to second Pot using plantClone = Plant.Clone(); and, after call secondPot.AddComponent(plantClone);

If this didn't works, you can also implement the interface only in the Berry, and after duplicate the object, use secondPlant = firstPlant.Clone();.

avatar image ZoltanErdokovy · May 26, 2013 at 01:57 PM 0
Share

Just to be clear, I'm talking about duplication of a GO manually in the editor (CTRL+D, Edit/Duplicate). I don't see where and when I'm supposed to call Clone().

avatar image FL · May 26, 2013 at 05:15 PM 0
Share

Oh! Sorry! I misunderstand this part. You probably need to edit/make some Editor scripts to use the Clone() method but I have no experience in this part.

avatar image clunk47 · May 26, 2013 at 05:23 PM 0
Share

As far as I know, things work pretty much the same way as regular scripting if you just use ExecuteInEdit$$anonymous$$ode... I could very well be wrong, but check it out, it may at least point you in the right direction :)

avatar image
0

Answer by ZoltanErdokovy · Jun 01, 2013 at 09:12 AM

My example was wrong above, here is how things seem to be working:

  • If 'Berry' extends c#'s root class (i.e. extends nothing) then it does get duplicated properly.

  • If 'Berry' extends ScriptableObject then the instance is shared. In other words the references are duplicated not the instance they are pointing to. This behavior is actually a feature as explained in this excellent post. (Although I'm still somewhat confused how serialization and ctrl+d relate exactly.)

  • For other reasons I needed 'Berry' to be a ScriptableObject so I had to detect when a GO got duplicated from the editor UI and do deep copies and reference fixes throughout the cloned component:
    • The component in question has [ExecuteInEditMode] so it's Update() is executed every time the scene changes, such as on duplication.

    • I store the result of GetInstanceID() in a separate variable, initialized on creation of the component and on Awake() to handle scene loads. In Update() the cached value is compared to the current GetInstanceID() and if they differ then we are a duplicate.

    • The UNITY_EDITOR define ensures that this comparison is only done while in the editor.

    • While performing the deep copies on the contents of the component I build a remapping dictionary containing oldInstance - newInstance pairs. I use that to restore inter-component referencing. (So nothing keeps pointing to the original component's contents but rather to the similar part of the newly created component with the now unique instances.)

It's not the most elegant solution but works.

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

15 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

Related Questions

Dont Destroy On Load Scene Return Problem 1 Answer

Inspector val init on non-mono class 1 Answer

Inspector - Show/hide property within custom class using enum 1 Answer

Spawn issue - Duplication of Object 1 Answer

C# script can't access my JS class, even though its in Plugins 1 Answer


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