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
0
Question by G_hi3 · Nov 25, 2020 at 01:24 PM · startupserializedpropertyconstructor

Non-MonoBehaviour object with SerializableField

Hi, I'm trying to implement health for my player character and enemies. My class looks like this:

 [Serializable]
 public class Health {
 
   [SerializeField] private int totalHealthPoints;

   public Health() {
     HealthPoints = totalHealthPoints;
   }
 
   public int TotalHealthPoints => totalHealthPoints;
 
   public int HealthPoints { get; private set;  }
 
   public bool IsEmpty => HealthPoints <= 0;
 
   public void TakeDamage(int damagePoints) {
     HealthPoints -= damagePoints;
   }
 
 }

I have another class that checks the HealthPoints in their Update method (with a reference to my PlayerCharacter class which is a MonoBehaviour with a IsAlive property) and ends the game if the player has no health left. My problem is that the game ends immediately and if I log the value of totalHealthPoints in the constructor, it's always 0, no matter what I input in the editor.

Is there no way to access a serialized value in the constructor without making the class a MonoBehaviour? The only other way to solve this problem would be to introduce an event to the Health, which the "observer" can listen to.

 public class PlayerCharacter : MonoBehaviour {

   [SerializeField] private Health health;

   public bool IsAlive => !health.IsEmpty;
 
 }

 public class PlayerHealthObserver : MonoBehaviour {

   [SerializeField] private PlayerCharacter playerCharacter;

   private void Update() {
     if (playerCharacter.IsAlive)
       return;

     EndGame();
   }

   private void EndGame() {
     // Does stuff to end the game.
   }
 
 }
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
1
Best Answer

Answer by G_hi3 · Nov 25, 2020 at 06:23 PM

I was able to find a solution to my problem: Unity 4.5 introduced the ISerializationCallbackReceiver interface. It declares two methods called OnBeforeSerialize and OnAfterDeserialize. I implemented the interface on my Health class to set the healthPoints variable after deserialization.

 [Serializable]
 public class Health : ISerializationCallbackReceiver {

   [SerializeField] private int totalHealthPoints;

   public int TotalHealthPoints => totalHealthPoints;

   public int HealthPoints { get; private set; }

   public bool IsEmpty => HealthPoints <= 0;

   public void TakeDamage(int damagePoints) {
     HealthPoints -= damagePoints;
   }

   public void OnBeforeSerialize() {
   }

   public void OnAfterDeserialize() {
     HealthPoints = totalHealthPoints;
   }

 }

The only down-side in my case is the empty OnBeforeSerialize method.

ISerializationCallbackReceiver Documentation link

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
1

Answer by xxmariofer · Nov 25, 2020 at 02:25 PM

Hello, have you consider using ScriptableObject for that task? simply create the scriptable object and use it for serialization

 using UnityEngine;
 [CreateAssetMenu(fileName = "Health", menuName = "ScriptableObjects/Health", order = 1)]
 
 public class HealthScriptable : ScriptableObject
 {
     [SerializeField] private int totalHealthPoints;
 
     public int TotalHealthPoints => totalHealthPoints;
 
     public int HealthPoints { get; private set; }
 
     public bool IsEmpty => HealthPoints <= 0;
 
     private void OnEnable()
     {
         HealthPoints = totalHealthPoints;
     }
 
     public void TakeDamage(int damagePoints)
     {
         HealthPoints -= damagePoints;
     }
 }
 
Comment
Add comment · Show 3 · 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 G_hi3 · Nov 25, 2020 at 06:06 PM 0
Share

Yes, but as I understand it, the ScriptableObject is used for things you want to create an asset for. It seems a bit overkill to create an asset for every Health instance I want to use in my game. Especially, since it's such a lightweight class.

avatar image Llama_w_2Ls G_hi3 · Nov 25, 2020 at 06:27 PM 0
Share

It only creates one asset, and the instances are components. It's like the box collider component for example. You can find it in the menu (which are part of the default Unity assets) and when you add a new instance of a box collider component onto your object, it doesnt create a new asset. Its definitely not overkill and it's probably a good idea to use xxmariofer's solution above.

avatar image G_hi3 Llama_w_2Ls · Nov 26, 2020 at 08:41 PM 0
Share

I've been working a bit with ScriptableObject lately. An asset created from a ScriptableObject can be referenced by different objects in the scene. In my case it made more sense to have Health be a ISerializationCallbackReceiver, because it will only ever be accessed by a PlayerCharacter or Enemy object that owns it.

I did end up using ScriptableObject in my project as something completely unrelated. I'm able to create a Dialog object and write dialog pages and reference the speaking characters.

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

139 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

Related Questions

AttributeDrawer: Draw parent property? (the one [AttributeName] is attached to) 0 Answers

Display function parameters in inspector 0 Answers

Unity doesn't start on Windows 7 x64? 8 Answers

Weird Crash after Upgrading to 3.5.2 1 Answer

Large resouce folder iOs crash at startup 2 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