Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Problem: Serialized multiple times

Discussion in 'Scripting' started by Marscaleb, Apr 7, 2015.

  1. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    992
    I just got hit with a compile error I do not understand, and is not directed at any line of code.

    First of all, I have structured my game with a fair amount of inheritance to make it work easier.
    I have a pawn class that handles things that every character in the game will use, like having health.
    I made playerpawn class that extends from that class and handles all the basic player motion and controls (as opposed to an enemy pawn or an npc.)
    And on top of that I have classes for specific player classes, like PP_Mage and PP_Ranger that handle the unique particulars of those classes, like how they attack.

    So today I was working on some enemies, and I decided that I want to use some of the same movement code that I have been using for the players. So I went into my PlayerPawn class, copied and removed a couple variables, and placed them in the Pawn class, so I could have them in my enemy's classes.

    Then I got this error:
    "myXVelocity" is one of the variables I moved from the PlayerPawn class. It is declared as a protected variable so it can be used in the children classes. It it is never referenced or called in any manner from the scripts for the particular player classes.

    So, I'm confused. What is this error?
     
  2. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    992
    That's odd, suddenly the error has disappeared. I didn't even change anything.
     
  3. invicticide

    invicticide

    Joined:
    Nov 15, 2009
    Posts:
    109
    I just had this happen today. I had two classes, DetonatorBullet and HomingBullet, which both inherited from the base class Bullet. Both classes declared a member field m_directional. I decided DetonatorBullets should *be* HomingBullets, so I changed DetonatorBullets to inherit from HomingBullet and removed the DetonatorBullet.m_directional declaration in favor of the inherited HomingBullet.m_directional. As soon as I recompiled scripts, Unity threw this error.

    It seems it still had the DetonatorBullet.m_directional value serialized in existing DetonatorBullet prefabs, and now with the new inheritance is also had HomingBullet.m_directional serialized into those same prefabs, which would obviously be screwy. However, I think the error itself is superfluous; I restarted Unity and reimported scripts once more (with no other changes) and the error went away. I think it's just holding onto some stale serialization data longer than it should.
     
    Reimirno7 likes this.
  4. Mikael-H

    Mikael-H

    Joined:
    Apr 26, 2013
    Posts:
    309
    I had the same error today while refactoring some classes and creating interfaces to be used as variables in some places. I got a lot of errors like Serialized Multiple Times and, to be honest, at some time there probably was a duplication of variables in an inheriting class. The errors did not go away though.

    Then I realized, it was not a compile error! It is an error thrown by unity at serilization/deserialization. So all you have to do is fix the offending class structure and clear the console. If the error has not been solved, Unity will let you know next time it serializes...
     
  5. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    897
    When Unity saves the data shown in the inspector, it can only save the tip. so when a base class has a field that says
    Code (CSharp):
    1. public Collider2D targetCollider;
    then an inheriting class has something like
    Code (CSharp):
    1. new public BoxCollider targetCollider;
    unity sees both types and doesn't know which to serialize to (even though BoxCollider should take precidence)
    EDIT: To clarify, its not specifically Unity, its the fact of how Reflection works that Unity uses during serialization/deserialization

    regardless whether unity should or shouldn't handle this more intelligently, the real problem is with the code. It violates Liskov's Substitution principal. The cleaner way to handling this is that the base class refers to the most abstract version needed and then the inheriting classes attempt to cast at run-time. this should avoid most of your "serialized multiple times" issue


    Code (CSharp):
    1. public abstract class BaseClass:MonoBehaviour
    2. {
    3.   public Collider target; //all inheriting classes will use SOME type of collider
    4. }
    5.  
    6. public class BoxClass:BaseClass
    7. {
    8.   private void OnTriggerEnter(Collider other)
    9.   {
    10.       //cast to the actual type we need
    11.       BoxCollider box = target as BoxCollider;
    12.       if(box == null)
    13.       {
    14.           Debug.LogError("Collider is not a BoxCollider!");
    15.           return;
    16.       }
    17.  
    18.       Debug.Log("Using BoxCollider!");
    19.   }
    20. }
    21.  
    22. public class CapsuleClass:BaseClass
    23. {
    24.   private void OnTriggerEnter(Collider other)
    25.   {
    26.       //cast to the actual type we need
    27.       CapsuleCollider capsule = target as CapsuleCollider;
    28.       if(capsule == null)
    29.       {
    30.           Debug.LogError("Collider is not a CapsuleCollider!");
    31.           return;
    32.       }
    33.  
    34.       Debug.Log("Using CapsuleCollider!");
    35.   }
    36. }
     
    Last edited: Nov 9, 2016