Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor Scene Setup #302

Merged
merged 135 commits into from
Jul 22, 2021
Merged

Refactor Scene Setup #302

merged 135 commits into from
Jul 22, 2021

Conversation

freezy
Copy link
Owner

@freezy freezy commented May 30, 2021

This is still WIP, but I'll write some documentation here so people can validate before I go into too deeply (although the ground work is already done).

Before this PR, importing a VPX file would write the entire table data into the scene. This approach had several issues:

  • Inefficient: When we extract heavy data like textures and meshes, the original data was still kept, and very badly: While Unity stores meshes as serialized binary data, our data meshes were serialized as objects, resulting in gigabytes of scene data for medium-sized tables.
  • Synchronization problems: Because game play, export etc were still using the originally imported Table object, hacks were necessary to update this object when stuff in the scene was added or removed. It actually didn't really work at all.
  • Not editable: Assets like textures and sounds couldn't be edited or replaced, because they were still stored as serialized objects.

Table Container

To solve the synchronization issue, we've split the Table class, which was the root object of all the data, into two classes:

  • Table now only holds the "table data", which are the global parameters of the table, but no game items, textures, or anything else.
  • TableContainer is an abstract class that provides access to the rest of the data, which are textures, materials, sounds, game items, collections, global table props, custom info tags, and mappings.

Now, when the table file is read, we get a instance of FileTableContainer, a subclass of TableContainer. That's how we get access to all the data in the file. That data is then converted to a scene, where we have a SceneTableContainer (as a field of TableAuthoring). This container also provides access to all the data, but it pulls it out of the scene. This means we don't need to sync anymore, since the old FileTableContainer doesn't exist anymore once import has finished.

SceneTableContainer doesn't contain any state, it just knows where to retrieve the state from. For example, the binary data of a texture would be retrieved from an image in the asset folder (see below), or the metadata of a flipper would be retrieved from the flipper's FlipperAuthoring component, which still sits in the scene.

We currently refresh the references of SceneTableContainer on EditorApplication.hierarchyChanged, but this might not be necessary, maybe we can lazy-refresh only when we actually need fresh data.

Assets

When importing, assets are now written to separate files in the asset folder whenever possible, to keep as little as possible in the scene.

  • Textures are written as image files
  • Sounds are written as .wav files
  • Materials are saved as .mat files
  • Physical materials are saved as .asset files
  • Primitive meshes are saved as .mesh files, generated meshes are not saved
  • All game items are saved as prefabs

This means that we can now edit textures directly on the disk and Unity will automatically re-import them.

Note that we still store all the original data in the authoring component of the game object. However, we "free" heavy, fields once extracted. For example, after the mesh data of a primitive is saved as an asset, the mesh of the data object is nulled so it doesn't add redundant data to the scene.

Materials

Materials from Visual Pinball are saved for later export, but are ignored otherwise. That means updating them doesn't change anything in the converted Unity material, and changing the converted Unity material doesn't update the original material. If a material is used as physics material, or if it has the physics properties set, the material is saved as asset as a PhysicsMaterial object and linked to the collision authoring component. During gameplay, the asset is used instead of the table data.

Side Car

The "side car" object was initially used to off-load heavy data into a separate ScriptableObject. I don't see any use of this anymore. However, we still would like to re-export data we currently don't use in VPE. Thus, this object was renamed to LegacyContainer and contains data that is in the VPX file, but ignored by VPE.

TODO

  • Implement SceneTableContainer.GetMaterial()
  • Implement SceneTableContainer.GetTexture()
  • Handle asset folder name:
    • When importing, use file name instead of table object name
    • When creating a new table, ask for a name (Table1 is fine, it can be renamed)
  • Verify legacy data is saved correctly
  • Handle the storage indices, probably best to re-index just before exporting, since we don't need them anywhere else.
  • Handle imported meta data of textures, sounds and materials when exporting
  • Don't re-import assets that already are in the asset folder
  • Test other sound formats than .wav
  • Convert the "resources" dependency to prefabs (new issue)
  • When exporting, add an option to automatically include all meshes in the scene as primitives (non-collidable toys), even when no PrimitiveAuthoring component is set. (new issue - maybe)
  • Fix test coverage

@freezy freezy added unity Concerns the Unity project editor Editor-related changes for Unity labels May 30, 2021
@freezy freezy self-assigned this May 30, 2021
@codecov
Copy link

codecov bot commented May 30, 2021

Codecov Report

Merging #302 (daa8ae0) into master (ce83f7e) will increase coverage by 13.94%.
The diff coverage is 82.80%.

Impacted file tree graph

@@             Coverage Diff             @@
##           master     #302       +/-   ##
===========================================
+ Coverage   69.68%   83.62%   +13.94%     
===========================================
  Files         136      136               
  Lines        6646     7444      +798     
  Branches      859        0      -859     
===========================================
+ Hits         4631     6225     +1594     
+ Misses       1785     1219      -566     
+ Partials      230        0      -230     
Impacted Files Coverage Δ
VisualPinball.Engine/Math/DragPointData.cs 46.87% <ø> (+4.01%) ⬆️
VisualPinball.Engine/Math/Rect3D.cs 100.00% <ø> (+100.00%) ⬆️
VisualPinball.Engine/Math/Vertex2D.cs 86.95% <ø> (+30.95%) ⬆️
VisualPinball.Engine/Math/Vertex3D.cs 100.00% <ø> (+37.63%) ⬆️
VisualPinball.Engine/VPT/Bitmap.cs 79.20% <0.00%> (+1.00%) ⬆️
VisualPinball.Engine/VPT/Flipper/Flipper.cs 68.00% <ø> (+15.05%) ⬆️
...Pinball.Engine/VPT/Flipper/FlipperMeshGenerator.cs 100.00% <ø> (+12.20%) ⬆️
VisualPinball.Engine/VPT/Gate/GateData.cs 70.45% <ø> (+4.66%) ⬆️
...isualPinball.Engine/VPT/HitTarget/HitTargetData.cs 73.91% <ø> (+7.24%) ⬆️
VisualPinball.Engine/VPT/ItemData.cs 100.00% <ø> (ø)
... and 175 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update caa8d7f...daa8ae0. Read the comment docs.

@freezy freezy added this to the Usable Editor milestone May 30, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
editor Editor-related changes for Unity unity Concerns the Unity project
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants