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
2
Question by IGoByChad · May 12, 2012 at 11:15 PM · serializablebestpracticesconstructor

System.Serializable, Constructors, Defaults

I was just wondering what the best practice was for constructors and custom classes. Currently I have a MonoBehaviour that contains a List that contains a CustomClassWithoutSerializableAttribute. I want to know the best way to default the third class. It looks like the following:

Character.cs

 public class Character : MonoBehaviour
 {
     public List<Ability> m_abilities;
 }


Ability.cs

 [System.Serializable]
 public Ability : IAbility
 {
     [SerializeField]
     private int m_somethingSetInEditor;
 
     private Damage m_damage;
 
     public Ability()
     {
         m_damage = new Damage(10);
     }
 }


Damage.cs

 public Damage
 {
     public Damage(int number)
     {
     }
 }


Damage is null at the end of this chain of events. I've been trying to find the best practice for this. Eventually I want to move Ability out of the Inspector, but for now, I want to be able to iterate quickly on this and want to know the best practice for this type of thing.

Should Ability be deriving from ScriptableObject and initializing m_damage in the Start() function?

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 eDorosh · Feb 03, 2017 at 11:18 AM 0
Share

Hi. Did you find a solution for this? Now I have the same problem. Neither constructor nor private Damage m_damage = new Damage(10); work.

avatar image Bunny83 eDorosh · Feb 03, 2017 at 11:58 AM 1
Share

Please don't try to hijack another question. See my answer below. If you have a similar problem, you should ask a seperate question. We can't handle your specific case here in the comments. $$anonymous$$ake sure you include your actual code that reproduces the problem. Obviously the code "IGoByChad" posted is not his actual code as the "class" keyword is missing in both class definitions. If you don't want to post your actual code, make sure if you create a repro-sample that it actually has the same problem.

btw:

 private Damage m_damage = new Damage(10); 

does work as well. Of course the Damage instance it not serialized, but each time the Unity serialization system is recreating / deserializing the Ability class, the Damage instance will be recreated as well.

Note: If you use the constructor of the Ability class, make sure you initialize it in the parameterless constructor as this is used by Unity. FieldInitializers however should work as well as they run even before the constructor.

avatar image eDorosh Bunny83 · Feb 03, 2017 at 12:30 PM 0
Share

Thanks a lot. The problem was with the absence of parameterless constructor.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Feb 03, 2017 at 11:49 AM

The question is old, but since it got bumped:

I can't reproduce your problem. The Damage instance is not null. My test case:

 [System.Serializable]
 public class Ability
 {
     [SerializeField]
     private int m_somethingSetInEditor;

     private Damage m_damage;
     public Damage damage { get { return m_damage; } }

     public Ability()
     {
         m_damage = new Damage(10);
     }
 }
 public class Damage
 {
     public int val;
     public Damage(int number)
     {
         val = number;
     }
 }

 public class Character : MonoBehaviour
 {
     public List<Ability> m_abilities;
     void Start ()
     {
         foreach (var a in m_abilities)
         {
             Debug.Log(a.damage.val);
         }
     }
 }

This prints out "10" for each ability that i "create" in the inspector. Though be aware that Unity does not support inheritance for custom serializable classes. So your Ability array can only contain Ability instances if you want Unity to serialize them. You can not store derived classes in that List. Well, you can but they won't be serialized. If you need inheritance you have to use ScriptableObject and create seperate assets for each ability. In that case inheritance would work.

Comment
Add comment · Show 1 · 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 kylewill713 · Jul 01, 2018 at 01:57 PM 0
Share

In this example range is being set to whatever I set it to in the inspector, but I never get the message "Constructor called..." in my console. When i try to do anything else in the constructor it just doesn't happen

 using UnityEngine;
 using System.Collections.Generic;
 
 [System.Serializable]
 public class Ability
 {
     private int damage;
     public Ability(int damage)
     {
         this.damage = damage;
     }
 }
 
 [System.Serializable]
 public class RangedAbility : Ability
 {
     [SerializeField]
     public int range;
     [SerializeField]
     public int damage;
 
     public RangedAbility(int range, int damage) : base(damage)
     {
         this.range = range;
         Debug.Log("Constructor called...");
     }
 }
 
 public class Character : $$anonymous$$onoBehaviour
 {
     public  RangedAbility[] m_abilities;
     void Start ()
     {
         foreach (var a in m_abilities)
         {
             Debug.Log(a.range);
         }
     }
 }

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

7 People are following this question.

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

Related Questions

Replacing and stacking shaders for some objects 1 Answer

Best practices - Model, animation and material naming 3 Answers

Referencing multiple Textures from a Component 0 Answers

3D novice - Sculptris model, UV map, and application in Unity .OBJ 1 Answer

Static Initialization 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