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
2
Question by darthbator · Sep 22, 2016 at 09:56 PM · networkingnetworklistsynchronizationinitialization

Inheritance and uninitialized synclists

I initially posted this to the MP forums here but haven't had any luck figuring this out. The issue I am running into is with accessing or initializing a SyncList object that has been declared in a base class. Lets say I have something like this in my base class ThowableItem.cs

 protected SyncListFloat inaccuracy = new SyncListFloat();

As long as I utilize this object within the ThrowableItem class everything works fine! However if I declare ThrowableItem.cs->Ball.cs and then attempt to access the inaccuracy element from Ball.cs I get an error that the sync list is uninitialized. This occurs even when attempting to access the inaccuracy object from a call to a base method. Here's the code running in OnStartServer generating the error from ThrowableItem.cs:OnStartServer when called from Ball.cs

 //    inaccuracy = new SyncListFloat();
     for (int count = 0; count < bagSize; count++) 
         inaccuracy.Add(Random.Range(-inaccuracyRange, inaccuracyRange));

I also tried moving the initialization out the base class. I figured I would just initialize the variable declared in the base class in the descendant and everything would work. Nope, same error, synclist uninitialized. Do SyncLists need to be initialized within class scope and not method scope? How is it recommended to declare and initialize synclists for use with inheritance and polymorphism? I can't seem to figure out how to correctly use these things within a class hierarchy.

Comment
Add comment · Show 6
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 Timboc · Nov 30, 2016 at 08:31 PM 0
Share

@darthbator I have exactly the same issue. Any luck finding a solution or workaround?

avatar image darthbator Timboc · Dec 01, 2016 at 01:16 AM 0
Share

Nope :( I ended up establishing a standard list and only using a sync field for the "next" element.

avatar image Bunny83 · Dec 01, 2016 at 02:24 AM 0
Share

Well, Synclists are not "normal" classes as Unity does a lot "Cecil magic" after your code is compiled to actually "write up" the automatic syncing. It's possible that their IL-weaver simply doesn't see the variable since it's not declared in the actual class. This however is just a guess.

Fact is that whenever you perform a changing action on the list, it will invoke it's private "Send$$anonymous$$sg" method which checks it the internal NetworkBehaviour variable has been set and if not, it shows that error:

 private void Send$$anonymous$$sg(SyncList<T>.Operation op, int itemIndex, T item)
 {
     if (this.m_Behaviour == null)
     {
         if (LogFilter.logError)
         {
             Debug.LogError("SyncList not initialized");
         }
         return;
     }
     // [ ... ]

The behaviour reference is set by the public method "InitializeBehaviour" which most likely should be called by the injected autogenerated code. $$anonymous$$aybe it's enough to to call it manually but i doubt it. It needs an additional "command hash" which is most likely generated by the injected code and used to distribute the message to the list.

So i guess declaring a synclist in a base class simply isn't supported at the moment. You may want to file a bug-report about that.

avatar image darthbator Bunny83 · Dec 01, 2016 at 02:33 AM 0
Share

haven't come back to this one in a while but it occured to me that the one case I don't believe I tested was to initialize the synclist at declaration within the base class and then call to it using the descendant (probably because the idea here was the try and be generic and the pool was not of a fixed size). Thinking more about the generative code element it could very well be that the "bug" here is that you cannot initialize a synclist at runtime and that it needs to be initialized at compile time?

avatar image clever darthbator · Dec 01, 2016 at 02:48 AM 0
Share

This seems to be a problem that plagues all SyncLists. I had a similar problem with SyncList items on server not initializing on a client when the client connects.

avatar image Timboc Bunny83 · Dec 01, 2016 at 10:55 AM 0
Share

Thanks for the replies :) - I also suspect it's an issue with the automagic that @Bunny83 describes. However, calling internal methods (especially that require hashes) sounds like dangerous ground indeed. Filing a bug report sounds like the sensible thing to do but I'm pretty disincentivised after my previous UNET bug report went completely ignored. Unity usually fixes these things given enough time. For now I'll fudge around the issue. Cheers.

1 Reply

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

Answer by YondernautsGames · Jul 14, 2017 at 09:07 AM

I know this question is old, but I think it deserves an answer for anyone else who's searching since I've been going nuts trying to sort this for almost a day now.

So the crux of the problem is uNet Weaver, the system that modifies and extends your code and classes to add all lovely uNet stuff. Weaver will add SyncList initialisation code to your class' Awake() function, however (at least in version 5.5) it seems to have no awareness of class inheritance, and so the base class Awake () will be overridden by the inherited class.

The easy fix is to define a protected virtual Awake () in your base class and then override in all inherited classes (making sure to call base.Awake ()). These functions can be empty or not. The point is Weaver will not create its own "inheritance unaware" Awake functions, it will just add you SyncList init to these and everything will be fine.

Hope someone finds this useful

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 christophermrau · Sep 17, 2017 at 10:51 PM 0
Share

@Survivalist-Games Thank-you very much! I was going nuts trying to figure out what was wrong with my code. I am beginning to realize that Unity is really bad with inheritance and polymorphism. It turns out I had implemented Awake() in an inherited class and it was, apparently, blocking the initialization of the base class. Exactly as described by @darthbator . Thanks again.

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

90 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

Related Questions

A node in a childnode? 1 Answer

Synchronizing game object across clients 2 Answers

UNET : SyncVar value not updating, hooks firing 1 Answer

SyncListStruct Not Syncing to Rest of Server! 0 Answers

How to pass a variable to a late-joining player without syncvars? / What function gets called on a new player connect? 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