sschmid / Entitas

Entitas is a super fast Entity Component System (ECS) Framework specifically made for C# and Unity
MIT License
6.99k stars 1.11k forks source link

Blueprints: SerializationException when adding a component with Vector2 field #380

Closed PanCotzky closed 7 years ago

PanCotzky commented 7 years ago

Hey! Stumbled uppon a problem. When I add a component, containing Vector2 into a Blueprint it throws the following exception. I know that the reason is that Vector2 is not marked as serializable. I've already worked this issue around but I think you should know and may be apply some measures to solve this problem because vectors and quaternions are pretty popular data types when it comes to game programming.

Update I've tried other data types. GameObjects are also have problems with serialization. Looks like it's general trouble with the serialization method.

Here's stack tracking.

SerializationException: Type UnityEngine.Vector2 is not marked as Serializable. System.Runtime.Serialization.Formatters.Binary.BinaryCommon.CheckSerializable (System.Type type, ISurrogateSelector selector, StreamingContext context) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryCommon.cs:119) System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetObjectData (System.Object obj, System.Runtime.Serialization.Formatters.Binary.TypeMetadata& metadata, System.Object& data) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:386) System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObject (System.IO.BinaryWriter writer, Int64 id, System.Object obj) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:306) System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectInstance (System.IO.BinaryWriter writer, System.Object obj, Boolean isValueObject) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:293) System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteQueuedObjects (System.IO.BinaryWriter writer) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:271) System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteObjectGraph (System.IO.BinaryWriter writer, System.Object obj, System.Runtime.Remoting.Messaging.Header[] headers) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/ObjectWriter.cs:256) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph, System.Runtime.Remoting.Messaging.Header[] headers) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:232) System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize (System.IO.Stream serializationStream, System.Object graph) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Runtime.Serialization.Formatters.Binary/BinaryFormatter.cs:211) Entitas.Unity.Blueprints.BinaryBlueprint.Serialize (Entitas.Blueprints.Blueprint blueprint) (at Assets/Addons/Entitas.Unity.Blueprints/BinaryBlueprint.cs:36) Entitas.Unity.Blueprints.BinaryBlueprint.Serialize (IEntity entity) (at Assets/Addons/Entitas.Unity.Blueprints/BinaryBlueprint.cs:31) Entitas.Unity.Blueprints.BinaryBlueprintInspector.OnInspectorGUI () (at Assets/Addons/Entitas.Unity.Blueprints/Editor/BinaryBlueprintInspector.cs:162) UnityEditor.InspectorWindow.DrawEditor (UnityEditor.Editor editor, Int32 editorIndex, Boolean rebuildOptimizedGUIBlock, System.Boolean& showImportedObjectBarNext, UnityEngine.Rect& importedObjectBarRect) (at C:/buildslave/unity/build/Editor/Mono/Inspector/InspectorWindow.cs:1229) UnityEditor.PopupCallbackInfo:SetEnumValueDelegate(Object, String[], Int32)

sschmid commented 7 years ago

Agree, basic types should be supported, definitely.

About Blueprints - don't use them, and don't plan to use them anytime soon until there are json blueprints :D I suggest having a custom solution for configuration or if you really like blueprints and want to use them, it's really easy to add JSON blueprints which should be way easier to handle and migrate than the current binary blueprints. The main reason I haven't pushed them yet is because I didn't want to depend on a 3rd party lib. But you can totally do that. The json lib must be able to serialize object type.

See also #267

PanCotzky commented 7 years ago

Oh. Ok, i'll get back to composing my entities in code.

Also, about json. It looks like Unity added a native json serializer to version 5.6. May be you should try it. Here it is:

https://docs.unity3d.com/Manual/JSONSerialization.html

Update Nevermind. Found your comment on the matter.

267

sschmid commented 7 years ago

:D see https://github.com/sschmid/Entitas-CSharp/issues/267#issuecomment-292813369

sschmid commented 7 years ago

About serializing GameObject: Maybe you know the Entitas-Shmup example project (ignore the fact that it's on an old Entitas version) There you can see I have an AssetComponent with a string of the asset name.

I like to treat blueprints as configuration - data you pull in from a source, e.g. a server which stores the game configuration. It should only contain simple data such as strings, ints etc. For that reason I think serializing GameObjects is not a good idea. I prefer to save to name of the resource.

vbnn2 commented 7 years ago

Hi, this is my first comment on Entitas issues and I'm sorry if my English is bad. I also want to show my respect with the guys who made Entitas.

I know Entitas when it first came out on Unite 2015 and I really like the concept of Entitas. But I'm have not used it in any project because of it can't company with Unity GameObject or Prefab.

I try to fix this problem about a week and now I gave up, but I still explain my idea here since it may help the others a little bit. Maybe they have a better idea :)

Desire: Using Entitas with GameObject & Prefab just as like blueprint did right now, we have a game object, we attach a script and starting to add component to it. When the game run, the object will create an entity and components associate with it. It's can also support all kind of serialization that Unity support.

My approach:

I succeed with this approach, i can add/update component, i can run and the gameobject can create entity with component .....

But .... at the end i realized my approach have 1 fault. Currently to add or create a component, we must know the component lookup id, and it can be changed if we add new/delete component. So my week is gone =))

I really really like Entitas and hope it can company with Unity soon :)

FNGgames commented 7 years ago

@vbnn2 I might have misunderstood you, but it seems like you are trying to make Entitas comply with a more traditional unity architecture (e.g. adding objects in the inspector, attaching scripts to them etc.) I think this is a problem - in Entitas you should be using Systems to carry the logic of your game, not unity scripts.

In any case, the simplest way to acheive what you're looking for in Entitas would be to have your AssetComponent carry a string : assetName. Then you would have a System take care of loading the prefab when such a component is added. See Match-One: AddViewsystem. This way you can serialize the component because its data is just a string. No need to ever serialize a GameObject.

pixeption commented 7 years ago

@FNGgames I think the biggest difference between cocos2d-x and Unity2D is the Editor (I compare these two since i use both of them). For example i want to design levels in game, the powerful of editor will save ton of times, just grab object into the scene and everything is ok no matter how complex the level is (WYSIWYG)

With entitas, to achieve the same result, i don't think we can do the same thing, maybe we can create a level just like above, then export to some asset file then we load at runtime. This can leads to a huge workload and complexity from writing the exporter, the importer and objects creator system.

I trying to make Entitas easier to use and can use the powerful power of editor. The script i wrote is like EntityLink from Entitas, the difference is it can automatic create entity and component of a game object when it's created.

Note: Sorry, i'm still vbnn2 above, i use 2 computers and signed in with different account

sschmid commented 7 years ago

Will close. Binary Blueprints currently don't have a high prio unfortunately. See #267