MicroStation to Unity to VR - Workflow 2

This tutorial describes my Virtual Reality workflow and is meant to replace the previous tutorial on this same topic. The main difference being that these instructions relate to Unity 5.6.1, SteamVR 1.2.2, and VRTK 3.2.

I created a series of companion videos for the old tutorial but they are now slightly out of date. As long as you follow this written VR Tutorial, I think those videos could be useful as a visual aid. You can find the YouTube playlist here:
https://www.youtube.com/watch?v=-q965SGPzzU&list=PL0JBlaeAgD15fFWHx4d6bFTVR6Je9zCpl

Introduction:

  • The “Unity” real time game engine has an impressive world wide following and has built up an extensive asset store that provides a vast amount of user generated content. With the availability of virtual reality headsets such as the HTC Vive and Oculus Rift, Unity has become a compelling tool of choice for architects interested in creating real time interactive virtual environments.

  • Unity uses FBX as its native file format which means that MicroStation’s FBX exporter is very well suited to providing Unity the content that it needs to build virtual worlds.

  • After some initial setup, the workflow between MicroStation & Unity becomes seamless which means that iterative changes are automatically incorporated into the Unity project with very little additional input from the user.

Prerequisites:

Prepare the VRTK project files:

  • Download the VRTK ZIP file from GitHub.

  • Unzip the file and place the extracted folder alongside your other Unity Projects.

  • Optionally, open the VRTK project with your latest version of Unity to upgrade all the files and make them ready for use.

Surface normal direction:

  • For performance reasons, Unity's standard shader only does single sided rendering which means that the back face of a surface will be rendered invisible.

  • MicroStation's Solids are OK but you will need to be careful and make sure that all Surface geometry has its surface normals pointing in the outward direction.

  • It is possible within Unity to use a custom shader that turns OFF “Back Face Culling” but this is something that should be used sparingly and only for things such as chain-link fences or tree foliage. This particular feature isn’t covered in this tutorial.

Create collision mesh geometry:

  • The only additional MicroStation geometry that you will need to create is a simplified collision mesh that represents the boundary of where the user is allowed to walk or teleport.

  • Even though you might be able to make your entire building model a collision mesh, you will get better performance if you use simplified geometry instead.

  • Additionally, if you intend to create grabbable objects, you will need to create a separate collision mesh for each object.

Export DGN geometry as FBX files:

  • Setup a series of DGN Reference files that break up your project into a number of smaller manageable components that are ready for export. If need be, move all referenced files so that the main point of interest is at the global origin XYZ = 0,0,0.

  • Open each DGN export file and goto [ File > Export > FBX ] (or keyin: “mdl keyin fbxexport dialog fbx”).

  • Set “Stroke Tolerance” to about “0.005” (if you have curved objects).

  • Turn ON “Invert Y and Z”.

  • Export all of your FBX files one at a time.

Create a Unity project:

  • Start Unity and create a new 3D Project.

  • In the top right corner set Layout to Default.

  • In the top right corner of the Scene View, click on the “Gizmos” drop down menu item:

    • Turn off or reduce the size of the “3D Icons”.
      This affects the size of the VRTK flying pig icons in your scene view.

    • Turn off “Show Grid”.

  • In the bottom right corner of the Assets content window, drag the slider to the left to enable “List” view.

  • Goto [ Toolbar > Window > Lighting > Settings ] to make sure the Lighting tab is docked next to the Inspector tab.

  • Click on the Inspector tab to make it active.

  • Goto [ Toolbar > Window > Asset Store ] to make sure the Asset Store tab is docked next to the Game tab.

  • From the Asset Store, install “SteamVR Plugin” and accept all defaults.

  • Close the Asset Store tab or click on the Scene tab to make it active.

  • Import “VRTK” (Virtual Reality Toolkit):

    • Open a second instance of Unity.

    • Open the “VRTK-master” project.

    • From the Assets folder, drag and drop the VRTK folder onto the Assets folder of your newly created Unity project and then close the second instance of Unity.

  • Goto [ Toolbar > Edit > Project Settings > Player ]:

    • In the Inspector tab, set:

    • [ Other Settings > Graphics Jobs (Experimental) ] to [ ON ].

    • [ Other Settings > Virtual Reality Supported ] to [ ON ].

    • [ Other Settings > Virtual Reality SDKs ] to [ OpenVR ].

    • [ Other Settings > Stereo Rendering Method] to [ Single Pass ].

  • Goto [ Toolbar > Edit > Project Settings > Quality ]:

    • In the Inspector tab, set:

    • [ Rendering > Anti Aliasing ] to [ 4x Multi Sampling ].

    • [ Shadows > Shadow ] to [ Hard and Soft Shadows ].

    • [ Shadows > Shadow Resolution ] to [ Very High Resolution ].

    • [ Shadows > Shadow Distance ] to [ A meaningful value for the scale of your scene ].

    • [ Shadows > Shadow Cascades ] to [ Four Cascades ].

  • Goto [ Toolbar > File > Save Scene As… ]:

    • Create a new sub-folder called “Scenes” in the Assets folder.

    • Double click on the Scenes folder and name the new scene “Main”.

Add Prefabs and Scripts to the Unity project:

  • Make sure that the “Main” scene tree structure is expanded by clicking on the little triangle in the Hierarchy tab.

  • Delete the default “Main Camera” from the “Main” scene.

  • Setup the VRTK_SDK Manager:

    • In the Hierarchy tab, right click and choose “Create Empty” GameObject. Name it “VRTK_Files”.

    • Click on the [ Inspector tab > Add Component ] button and search for “VRTK_SDK Manager”.

    • In the Hierarchy tab, right click on “VRTK_Files” and choose “Create Empty” GameObject. Name it “SDK_Files”.

    • Drag and drop [ Project tab > Assets > SteamVR > Prefabs > CameraRig ] onto [ VRTK_Files > SDK_Files].

      • Set [ CameraRig > Inspector tab > Transform > Position X,Y,Z ] to [ 0,0,0 ].

      • Set [ CameraRig > Inspector tab > Steam VR_Play Area > Draw in Game ] to [ OFF ].

      • Set [ CameraRig > Inspector tab > Steam VR_Play Area > Size ] to [ Calibrated ].

    • Drag and drop [ Project tab > Assets > SteamVR > Prefabs > SteamVR ] onto [ VRTK_Files > SDK_Files ].

    • In the Hierarchy tab, click on “SDK_Files”:

      • Click on the [ Inspector tab > Add Component ] button and search for “VRTK_SDK Setup”.

      • Set [ VRTK_SDK Setup > SDK Selection > Quick Select ] to [ SteamVR ]

    • In the Hierarchy tab, click on “VRTK_Files”:

      • Click on the [ Inspector tab > VRTK_SDK Manager > Setups > Auto Populat ] button.

  • Setup VRTK controller scripts:

    • In the Hierarchy tab, right click on “VRTK_Files” and choose “Create Empty” GameObject. Name it “Script_Files”.

    • In the Hierarchy tab, right click on “Script_Files” and choose “Create Empty” GameObject. Name it “Controller_L”.

    • In the Hierarchy tab, right click on “Script_Files” and choose “Create Empty” GameObject. Name it “Controller_R”.

    • In the Hierarchy tab, click on “VRTK_Files”:

      • Drag and drop [ Hierarchy tab > VRTK_Files > Script_Files > Controller_L ] onto
        [ Inspector tab > VRTK_SDK Manager > Script Aliases > Left Controller ].

      • Drag and drop [ Hierarchy tab > VRTK_Files > Script_Files > Controller_R ] onto
        [ Inspector tab > VRTK_SDK Manager > Script Aliases > Right Controller ].

    • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > VRTK_ControllerEvents ] onto
      [ Hierarchy tab > VRTK_Files > Script_Files > Controller_L AND Controller_R ].

    • Drag and drop [ Project tab > Assets > VRTK > Scripts > Pointers > VRTK_Pointer ] onto
      [ Hierarchy tab > VRTK_Files > Script_Files > Controller_L AND Controller_R ]:

      • For both controllers, set:

      • [ Inspector tab > VRTK_Pointer > Pointer Activation Settings > Activation Button ] to [ Touchpad Press ].

    • Drag and drop [ Project tab > Assets > VRTK > Scripts > Pointers > PointerRenderers >
      VRTK_BezierPointerRenderer ] onto [ Hierarchy tab > VRTK_Files > Script_Files > Controller_L AND Controller_R ].

      • From the Inspector tab, drag and drop [ VRTK_Bezier Pointer Renderer (Script) ] onto
        [ VRTK_Pointer > Pointer Activation Settings > Pointer Renderer ].

      • For both controllers, in the [ Inspector tab > VRTK_Bezier Pointer Renderer ], set:

      • [ Bezier Pointer Appearance Settings > Tracer Density ] to about [ 50 ].

      • [ Bezier Pointer Renderer Settings > Rescale Tracer ] to [ ON ].

      • [ Bezier Pointer Renderer Settings > Cursor Match Target Rotation ] to [ ON ].

      • Drag and drop [ Project tab > Assets > VRTK > Examples > ExampleResources > Prefabs > LightSegmentTexAnim ] onto [ Bezier Pointer Custom Appearance Settings > Custom Tracer ].

  • Setup VRTK teleport scripts:

    • In the Hierarchy tab, right click on “Script_Files” and choose “Create Empty” GameObject. Name it “PlayArea”.

    • Drag and drop [ Project tab > Assets > VRTK > Scripts > Locomotion > VRTK_DashTeleport ] onto
      [ Hierarchy tab > VRTK_Files > Script_Files > PlayArea ].

      • Set [ Inspector tab > VRTK_Dash Teleport > Base Settings > Blink Transition Speed ] to [ 0 ].

      • Note: You can use HeightAdjustTeleport instead of DashTeleport.

Import FBX files and set default attributes:

  • Close Unity and with Windows File Explorer navigate to the “Assets” folder in your Unity project.

    • Create a new sub-folder called "FBX" and copy the previously exported FBX files to this folder.

    • If applicable, Create a new sub-folder called "Textures" and copy texture files to this folder
      that aren’t included in the exported FBX files. This might include such things as Normal maps.

  • Restart Unity and open your project. Unity will import all new or changed files automatically.

  • Goto [ Project tab > Assets > FBX ] and highlight the collision mesh FBX file.

  • In the Inspector tab set the following attributes:

    • Read/Write Enabled = OFF

    • Generate Colliders = ON

    • Normals = Import

    • Tangents = None

    • Import Materials = OFF

    • Press the "Apply" button.

  • Goto [ Project > Assets > FBX ] and highlight all FBX files except for the collision mesh.

  • In the Inspector tab set the following attributes:

    • Read/Write Enabled = OFF

    • Generate Colliders = OFF

    • Normals = Import

    • Tangents = None

    • Press the "Apply" button.

    • By default, Unity does not use MicroStation’s Material names. To fix this:

      • Goto [ Project tab > Assets > FBX > Materials ] and delete all of the materials.

      • Goto [ Project tab > Assets > FBX ] and highlight all FBX files except for the collision mesh.

      • In the Inspector tab set the following attribute:

        • [ Material Naming ] = [ From Model’s Materials ].

        • Press the “Apply” button.

  • Goto [ Project > Assets > FBX > Materials ] and tweak the individual material properties.
    Note: These tweaks are only done once as all changes are kept even after you replace the FBX files with newer versions.

Add FBX files to your Scene:

  • In the Hierarchy tab, right click and choose “Create Empty” GameObject. Name it “Model_Files”.

    • Set [ Inspector tab > Transform > Position X,Y,Z ] to [ 0,0,0 ]

  • From [ Project tab > Assets > FBX ] drag and drop all FBX files onto the “Model_Files” container created earlier:

    • Make sure the Position Transform for the FBX files is set to X,Y,Z = 0,0,0

  • Click on the collision mesh in the Hierarchy window.

  • Goto [ Inspector tab > Mesh Renderer > Settings cog Icon on the right ] and select [ Remove Component ].

  • The [ Hierarchy tab > VRTK_Files > SDK_Files > CameraRig ] position has already been set to XYZ = 0,0,0
    but at this point you can move it to suit the geometry in your scene.

Setup a Directional Light Source:

  • Goto [ Toolbar > Window > Lighting > Settings ] and dock the Lighting tab next to the Inspector tab.

  • Drag and drop [ Hierarchy tab > Main > Directional Light ] onto [ Lighting tab > Environment > Sun Source ].

  • Set [ Lighting tab > Environment > Environment Reflections > Intensity Multiplier ] to about [ 0.75 ].

  • Set [ Lighting tab > Mixed Lighting > Baked Global Illumination ] to [ OFF ].

  • In the Scene tab, move and rotate the “Directional Light” so that it correctly illuminates your project geometry.

  • Click on the “Directional Light” in the Hierarchy tab:

    • In the Inspector tab, set:

    • [ Light > Shadow Type > Realtime Shadows > Resolution ] to [ Very High Resolution ].

Make Objects Grabbable:

  • In the ControllerEvents script for both controllers, remember that [ Grab Button ] is set to [ Trigger Press ]

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > VRTK_InteractTouch ] onto
    [ Hierarchy tab > VRTK_Files > Script_Files > Controller_L AND Controller_R ].

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > VRTK_InteractGrab ] onto
    [ Hierarchy tab > VRTK_Files > Script_Files > Controller_L AND Controller_R ]:

      • For both controllers, set:

      • [ Inspector tab > VRTK_Interact Grab > Grab Settings > Grab Button ] to [ Trigger Press ].

  • Highlight the object mesh in the Hierarchy tab:

    • In the Inspector tab:

    • Click on [ Add Component ] > [ Rigidbody ].

    • Option 1 (Simple Box Collider):

      • Click on [ Add Component ] > [ Box Collider ]:

        • Click on the “Edit Collider” button and adjust the size and position of box to suit the geometry.

    • Option 2 (Convex Mesh Collider):

      • Create a convex mesh collider for the grabbable object and import the FBX file just like the main collision mesh.

      • Click on [ Add Component ] > [ Mesh Collider ].

      • Set [Inspector tab > Mesh Collider > Convex ] to [ ON ].

      • Drag and drop [ Project tab > Assets > FBX > “Your Object Collider Geometry” > Mesh ] onto
        [ Inspector tab > Mesh Collider > Mesh ].

    • Option 3 (Concave Mesh Collider):

      • There are no “Concave Mesh Colliders” but you can build one up by combining multiple “Convex Mesh Colliders”.

      • Create multiple independent convex mesh colliders for the grabbable object and import the FBX files just like the main collision mesh.

      • Click on [ Add Component ] > [ Mesh Collider ]. (Add as many as there are Collision Mesh FBX files)

      • Set [Inspector tab > Mesh Collider > Convex ] to [ ON ].

      • Drag and drop each [ Project tab > Assets > FBX > “Your Object Collider Geometry” > Mesh ] onto its respective
        [ Inspector tab > Mesh Collider > Mesh ].

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > VRTK_ InteractableObject ] onto
    the
    object mesh in the Hierarchy tab.

      • In the Inspector tab, set:

      • Grab Options > Is Grabbable = ON

      • Grab Options > Hold Button to Grab = ON (or OFF if you prefer)

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > VRTK_ InteractControllerAppearance ] onto
    the
    object mesh in the Hierarchy tab.

      • In the Inspector tab, set:

      • Hide Controller On Grab = ON

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > VRTK_ InteractHaptics ] onto
    the
    object mesh in the Hierarchy tab.

      • In the Inspector tab, set:

      • Haptics On Touch > Strength On Touch = 0.3

      • Haptics On Touch > Duration On Touch = 0.1

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > GrabAttachMechanics >
    VRTK_ ChildOfControllerGrabAttach ] onto the object mesh in the Hierarchy tab.

      • In the Inspector tab, set:

      • Base Options > Precision Grab = ON

  • Drag and drop [ Project tab > Assets > VRTK > Scripts > Interactions > SecondaryControllerGrabActions >
    VRTK_ SwapControllerGrabAction ] onto the object mesh in the Hierarchy tab.

View the scene in VR with the HTC Vive headset:

  • Start SteamVR from your desktop and make sure that the Vive headset, base stations, and controllers are all up and running.

  • From within the Unity editor, press the “Play” button at the top of the screen.

  • Put the Vive headset on and walk around the scene as you would in real life.

  • To travel further than the confines of your physical room, press the big Touchpad button on your tracked controllers and aim the Bezier curve to the spot where you would like to be teleported.

  • Use the “Trigger” button on the Vive controllers to interact with grabbable objects.

  • In the Unity editor, press the “Play” button again to exit out of VR mode.

  • To share your project with a client who also has an HTC Vive, you can build a standalone executable of your project by going to [ Toolbar > File > Build Settings… ].

Known workflow difficulties:

  • The FBX exporter does not export elements of type “Surface” to the Unity game engine. To fix this problem, I’ve gotten into the habit of using the “CONVERT BREP” command to convert all “Surface” elements to “Smart Surface” elements.

  • Geometry that has a material that doesn’t use a texture map gets exported without UV texture coordinates. For Unity’s Baked Lighting to work, all geometry needs to have properly applied UV texture coordinates.

  • The FBX exporter appends the DGN file name to the material name. This leads to very long material names in the Unity editor but it also means that you get duplicate materials when you use multiple FBX files to export your project in smaller more manageable chunks.

  • Unity’s Standard shader uses single sided rendering which means that surface normal directions are critical. MicroStation needs a more efficient method of show the direction of ALL surface normals at once.

  • MicroStation’s mirror tool makes a mess of all surface normals so use it as sparingly as possible.

  • You can see a more in depth discussion of these issues here:
    https://communities.bentley.com/products/microstation/f/273/t/120578

Conclusion:

And that's all there is to it...

But seriously, I urge everyone to give VR a go. It looks daunting but once you've gone through the steps on your first project, the rest will be a breeze. This really is a game changer   :-)

  • Really fantastic work Andrew!!

    About the normals problem (many often this takes a big part of the time when I work with Unity), do you have experience with the export double sided option in Connect?

    When I use this option, the materials becomes a mess in Unity. If this works, it could save a lot of time.

    Regards Louis
  • Unknown said:
    About the normals problem, do you have experience with the export double sided option in Connect?

    Hi Louis,

    I'm running MicroStation SS3 so I haven't had a chance to try the Connect FBX exporter. I'm curious, does the Connect FBX exporter include any other new settings other than the double sided export option? I'd be particularly interested to know if there is an option to apply some sort of default UV texture map coordinates to geometry that has a material definition but does NOT include a texture map.

    With regard to the double sided export option, doesn't that mean that the FBX file contains twice the amount of geometry? I feel like that's a performance hit that I'd like to avoid. I think the better approach might be to use a custom Unity shader that allows you to turn OFF "Back Face Culling" on selected bits of geometry.

    On a related note, I wish Bentley would introduce a new Display Style that showed geometry with its surface normal facing the camera as green and geometry with its surface normal facing away from the camera as red. This would make it immediately obvious which surfaces need to be reversed for the sake of Unity and other similar applications.

    Cheers,
    Andrew.

  • Hi Everyone,

    I've made some minor adjustments to this VR Tutorial so that it now relates to the latest versions of "Unity 5.6.1", "SteamVR 1.2.2", & "VRTK 3.2". The main change was to a few of the settings in the "VRTK_SDK Manager" script.

    I think if you are updating an existing Unity project that uses "VRTK 3.1" to "VRTK 3.2" then you probably don't need to do anything as it should all continue to work as it did before the upgrade.

    Cheers,
    Andrew.

  • Hi Andrew,

    Thank you very much for this great guideline! It makes me possible to view our 3D Models with HTC Vive.

    And everybody of my colleagues who take a first look can not believe how impressive it is!

    Without your guideline it would have been impossible for me to find out how it works.

    So thanks again!

    Regards

    Christian