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
1
Question by TheNoobieWaffle · Aug 20, 2017 at 11:07 AM · editor-scriptingserialization

When my scripts recompile or I enter play mode, my custom class gets reset

This class gets reset every time I save a script and tab back into unity. My Debug.Log("create"); appears in the console in the editor when I tab back in, to be clear. I have a scrip that has a public property of AdvancedAnimationCurve(). I tried disabling the custom editor of the object that is holding the instance. I tried diabling the custom property drawer of the class below. I tried setting the private fields in the classes below with [SerializeField]. I even tried setting the variable within my script that has the AdvancedAnimationCurve() with [SerializeField]. Im not sure what else to try...

 using System;
 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 
 
 [Serializable]
 public class AdvancedAnimationCurve {
 
     public List<AdvAnimCurveKeyframe> keys;
 
     public bool editorUpdate;//Set to true when a keyframe is modified to let the editor know to redraw. Editor sets it to false on render.
 
     public AdvancedAnimationCurve() {
         Debug.Log("create");
         keys = new List<AdvAnimCurveKeyframe>() { new AdvAnimCurveKeyframe(this, 0, 0), new AdvAnimCurveKeyframe(this, 1, 1) };
         keys[0].RightTangentTime = Mathf.Sin((90 + (90 * .6666666f)) * Mathf.Deg2Rad);
         keys[0].RightTangentValue = Mathf.Cos((90 + (90 * .6666666f)) * Mathf.Deg2Rad);
         keys[1].LeftTangentTime = 1 - Mathf.Sin((90 + (90 * -.6666666f)) * Mathf.Deg2Rad);
         keys[1].LeftTangentValue = 1 - Mathf.Cos((90 + (90 * -.6666666f)) * Mathf.Deg2Rad);
     }
 
     public AdvAnimCurveKeyframe GetKey(int index) {
         return keys[index];
     }
 
     public void SetKey(int index, float value) {
         if (index < 0 || index > keys.Count - 1) {
             Debug.LogError("SetKey action cannot be completed. Arry index out of range.");
             return;
         }
         keys[index].MainValue = value;
     }
 
     /// <summary>
     /// Adds a key to the keyframes of the graph.
     /// </summary>
     /// <param name="time">The x value of the keyframe.</param>
     /// <param name="value">The y value of the keyframe.</param>
     /// <param name="replaceValue">If the time exists, replace value?</param>
     public void AddKey(float time, float value, bool replaceValue) {
         for (int i = 0; i < keys.Count - 1; i++) {
             if (keys[i].MainTime == time) {
                 if (replaceValue)
                     keys[i].MainValue = value;
                 return;
             }
         }
         for (int i = 0; i < keys.Count - 1; i++) {
             if (time > keys[i].MainTime && time < keys[i + 1].MainTime) {
                 Debug.Log("inserting at " + i);
                 keys.Insert(i + 1, new AdvAnimCurveKeyframe(this, time, value));
                 return;
             }
         }
         keys.Add(new AdvAnimCurveKeyframe(this, time, value));
     }
 
     /// <summary>
     /// This is used internally to tell the editor script to redraw on keyframe modification.
     /// </summary>
     public void KeyframeChanged() {
         editorUpdate = true;
     }
 
 }
 
 
 
 
 
 [Serializable]
 public class AdvAnimCurveKeyframe {
 
     private AdvancedAnimationCurve home;
 
     private float mainTime, leftTangentTime, rightTangentTime, mainValue, leftTangentValue, rightTangentValue;
 
     public AdvAnimCurveKeyframe(AdvancedAnimationCurve home, float mainTime, float mainValue) {
         this.home = home;
         this.mainTime = mainTime;
         this.mainValue = mainValue;
         home.KeyframeChanged();
     }
 
     public float MainTime {
         get { return mainTime; }
         set { mainTime = value; home.KeyframeChanged(); }
     }
     public float MainValue {
         get { return mainValue; }
         set { mainValue = value; home.KeyframeChanged(); }
     }
     public float LeftTangentTime {
         get { return leftTangentTime; }
         set { leftTangentTime = value; home.KeyframeChanged(); }
     }
     public float LeftTangentValue {
         get { return leftTangentValue; }
         set { leftTangentValue = value; home.KeyframeChanged(); }
     }
     public float RightTangentTime {
         get { return rightTangentTime; }
         set { rightTangentTime = value; home.KeyframeChanged(); }
     }
     public float RightTangentValue {
         get { return rightTangentValue; }
         set { rightTangentValue = value; home.KeyframeChanged(); }
     }
 
     public Vector2 Main {
         get { return new Vector2(mainTime, mainValue); }
     }
     public Vector2 LeftTangent {
         get { return new Vector2(leftTangentTime, leftTangentValue); }
     }
     public Vector2 RightTangent {
         get { return new Vector2(rightTangentTime, rightTangentValue); }
     }
 
 }
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 TheNoobieWaffle · Aug 20, 2017 at 11:18 AM 0
Share

I also get this in the console. XD is the name of the instance of AdvancedAnimationCurve Serialization depth limit 7 exceeded at 'AdvAnimCurve$$anonymous$$eyframe.home'. There may be an object composition cycle in one or more of your serialized classes.

 Serialization hierarchy:
 8: AdvAnimCurve$$anonymous$$eyframe.home
 7: AdvancedAnimationCurve.keys
 6: AdvAnimCurve$$anonymous$$eyframe.home
 5: AdvancedAnimationCurve.keys
 4: AdvAnimCurve$$anonymous$$eyframe.home
 3: AdvancedAnimationCurve.keys
 2: AdvAnimCurve$$anonymous$$eyframe.home
 1: AdvancedAnimationCurve.keys
 0: NoobieAnimation.XD
 
 

1 Reply

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

Answer by Bunny83 · Aug 20, 2017 at 11:36 AM

Well there are several problems. First and formost the fields of your "AdvAnimCurveKeyframe " class are private and therefore not serialized as they don't have a SerializeField attribute. If you want those fields to be serialized but not automatically show up in the inspector you can do:

 [SerializeField, HideInInspector]
 private float someField;

The next potential problem is your "home" reference. It must not be serialized as otherwise you would have a circular reference between your two classes. This is not supported for custom classes. Only inside the editor in some edge cases the editor will also serialized private fields if possible (playmode change / assembly hot reload).

Custom classes are not serialized on their own but as part of the MonoBehaviour / ScriptableObject that contains a field of that type. Custom serializable classes behave like "structs". So there's no polymorphism support. Also references to other custom serializable classes are not stored as "references" but as "sub-fields". The serializer has a maximum nesting level of 7. Though a circular reference is never supported.

It's bad practise to only put in a reference to another class that isn't even used at runtime. It seems you have either a custom inspector or property drawer for your class(es). So it would make more sense to detect the changes there. Alternatively you could use a static bool which gets set to true in your setters. That way there's no need to reference the curve from the keyframes.

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 Bunny83 · Aug 20, 2017 at 11:44 AM 0
Share

To better understand how Unity actually serializes your stuff, i suggest you set your "asset serialization mode" to "force text" (Edit --> Project Settings --> Editor --> Asset Serialization) . That way whatever asset contains your animation curve will be serialized as YA$$anonymous$$L text. Just open the scene, prefab or asset file with a text editor and find the $$anonymous$$onoBehaviour / ScriptableObject that contains your curve. There you will see that all serialized fields of your curve are just sub fields of the $$anonymous$$onoBehaviour / ScriptableObject.

If you prefer to read documentations i suggest to have a look at Asset serialization and make sure you read the important sections. ("hot reloading", "serialization rules" and "When might the serializer behave unexpectedly").

avatar image TheNoobieWaffle Bunny83 · Aug 20, 2017 at 11:48 AM 0
Share

Thank you! :D

avatar image TheNoobieWaffle Bunny83 · Aug 20, 2017 at 12:06 PM 0
Share

I removed the circular reference. I just use a static bool now. I also set the line of private variables to [SerializeField] in AdvAnimCurve$$anonymous$$eyframe. For some reason, the data still seems to not serialize. I think everything meets the criteria in the section on the page you linked me "How to ensure a custom class can be serialized", but no cigar.

avatar image TheNoobieWaffle TheNoobieWaffle · Aug 20, 2017 at 12:07 PM 0
Share

It actually states that "A List of a simple field type that can be serialized", so is my list the problem?

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

79 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

Related Questions

How do you save changes made with custom editor? 3 Answers

Keeping object between edit and play modes. 1 Answer

Add lines to a script from another script 0 Answers

What would be the best way to go about loading and saving a Serializable object in JSON with Unity? 0 Answers

Base MonoBehaviour Editor, foldout with base properties, child properties untouched. 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