Unity tutorials _ Locomotion and Ergonomics

 https://learn.unity.com/tutorial/unit-4-locomotion-and-ergonomics/?courseId=5d955b5dedbc2a319caab9a0&tab=overview&uv=2018.4#5d955977edbc2a001f0ea3ea

  • Locomotion or how we move is one of the core design features
  • Users need to remain comfortable during the experiences. 
  • Individual preferences vary quite a bit
  • Recommended supporting all types of locomotion, so people can choose
Physical Movement

  • Movement in VR that matches the physical movement, provides the most comfortable experience because there is no mismatch of senses that could trigger discomfort
  • Comes with some limitations - room size. Design for a small room, or limited mobility
  • Choose a mechanic that supports the design and considers all the types of users
Scripted movement and Avatar Movement

  • Scripted - the perspective moves along a predefined path of motion. Often considered difficult. Use sparingly if at all.
  • Vection - the sensation of movement of the body in space produced purely by visual stimulation
  • Avatar - combination of thumbstick, button, headset, motion controllers and gameplay state to drive motion in a way that makes sense
  • Evidence shows that the more we move our bodies, the more comfort there is
  • The more we mimic the way we move in the real world, the greater the immersion 
Steering motion and World Pulling

  • Steering motion - the player is controlling the inertia. Near-continuous six degrees of freedom (6DoF) - meaning the freedom of a rigid body in three-dimensional space, acceleration and velocity is common and often includes moving at high speed. Despite the sensory mismatch, steering motion can be enjoyed.
  • World Pulling - the player is generally stationary until they grab some point in the world and pull or push it. The world is locked to the controller and moves with it exactly.
Teleports
  • An instant, or nearly instant mechanic where you quickly appear somewhere else. This typically works by aiming a beam and pressing a button
  • Variations: 1) quick warp (almost like a fast cut) 2) Projectile warping - you warp to where you throw or shoot 3) Projected Avatars - follow a 3rd person character
Part 6: Implementing Teleports part 1. 

https://learn.unity.com/tutorial/unit-4-locomotion-and-ergonomics?courseId=5d955b5dedbc2a319caab9a0&tab=overview&uv=2018.4#5d96919bedbc2a6084598911


  • Go to project>packages>VRTK>pointers
  • Drag ObjectPointerCurved to the scene
  • Rename in the hierarchy 'Teleport_Curve_L"  Duplicate and rename for Right
  • Configure Select Teleport_Curve_L to open the inspector. Open Tracked Alias in the hierarchy. Drag the LeftControllerAlias child object to the Pointer Settings Follow Source field. Do the same for the right.

  • Create an empty game object>rename InputHandlers
  • Create two game object children. Rename "Thumbstick.Touched.L" for the left and "Thumbstick.Touched.R" for the right
  • Assets>search for OVRInputTouchAction script
  • Drag from the project folder onto the left and right "Thumbstick.Touched.L and R" respectively, in the hierarchy. This automatically creates a component.
  • Select "Thumstick.Touched L">inspector>Touch>Primary Thumbstick. Do the same for the right.

  • Select "Teleport_Curve_L" to open the inspector. Go to the hierarchy and drag Thumbstick.Touched.L to the Pointer Settings Activation Action field.
  • Repeat for the right.
  • Save
  • Test in VR.
  • Recording below. Packages manager>Unity Recorder>Window>general>recorder>recorder window>set file destination>select wildcard>take.
  • Take 4 below.


Implementing teleports - part 2

 https://learn.unity.com/tutorial/unit-4-locomotion-and-ergonomics?courseId=5d955b5dedbc2a319caab9a0&tab=overview&uv=2018.4#5d96919cedbc2a5ecf78754d

  • Teleportation action is what actually moves the player
  • VRTK>prefabs>teleporters>teleporterinstant
  • Drag into hierarchy
  • The target of the teleporter is what's actually moved, when the teleport happens. For us trying to move the player, this means the play area alias object.
  • Select 'Teleporter.Instant'>inspector>target>(drag PlayAreaAlias) to target slot>Drag HeadsetAlias to Offset slot
  • Validity rules explained more in VRTK docs- for now find 'scene cameras' under 'trackedalias' and drag to 'teleporter. instant' inspector window>camera validity field. This provides the rule behaviour we need.
  • Hook up the teleporter, so that clicking the thumbstick, triggers the teleport. Use the OVRinput button action, to trigger the teleport action. These button actions need to exist in the scene, so make two empty child game objects in hierarchy, under InputHandlers. Rename 'ThumbstickPressed.L and ;ThumbstickPressed.R" respectively
  • Search for OVRInputButtonAction in assets
  • Drag script onto ThumbstickPressed L and R in the hierarchy. This automatically generates a component.
  • Select both in the hierarchy and whilst selected go to the inspector window. Under the 'button' filed select drop down menu and select Primary Thumbstick

  • Then configure each and set the controller field to the value we need. In this case L touch and R touch respectively
  • Next tell the teleport cuves (Teleport_Curve_L and R) to select the destination when these boolean actions are triggered.
  • Select Teleport_Curve_L. In the inspector window>heirarchy select ThumbstickPressed.L and drag to the Selection Action field in pointer settings. Do the same for the right

  • Select 'Teleport_Curve_L' in the hierarchy. In the inspector>Pointer Events>Selected(EventData) list empty>click+>drag 'teleporter instant' from hierarchy into new slot>select drop down function menu>teelporter facade>teleporter. Do the same for the right.
  • Save
  • Test in VR

Implementing teleports - part 2
https://learn.unity.com/tutorial/unit-4-locomotion-and-ergonomics?courseId=5d955b5dedbc2a319caab9a0&tab=overview&uv=2018.4#5d96919eedbc2a6236bc1184

Add a directional indicator

  • Internals of Teleport_Curve_L>ObjectPointer.Internal>Elements>Destination>Elements.Cylinder> ValidContainer
  • Add an arrow to this by
  • Assets>search arrow
  • Drag arrow model onto 'valid container'
  • Arrow>inspector>>set position values>X0 Y0.02 Z 0.15 set rotation values>X -90 Y-125 Z 0   Scale X50 Y50 Z1 
  • Set material the same as the pointer. To do this
  • Assets>search>pointerdefaultvalid>drag onto arrow
  • Duplicate arrow>move to same place under the Teleport_Curve_R
  • Now both teleport curves have direction indicators
  • We want to rotate these with the thumb sticks, using the OVR input axis 2D action
  • These actions need to exist in a scene somewhere. Create an empty object
  • Rename 'ThumbstickPosition.L>duplicate>rename for right
  • Search for OVR input axis 2D action and drag the script into both
  • Inspector>Axis>Primary Thumbstick for both
  • Assign controller field for each hand
  • Select both in the hierarchy and drag to under the InputHandlers
  • Now set up the actions when the thumbstick directions are changed
  • Search Axis Rotator Prefabs
  • Drag into hierarchy. Rename AxisRotator.L>duplicate>rename for right
  • We see fields for the two axis here, which take float actions, but our thumbstick inputs are vector2 actions, which aren't compatible. To convert our 2D actions to 1D actions we are going to create two new game objects that will have one convertor for each axis
  • To make convertors
  • Select ThumbstickPosition.L in hierarchy. Create empty>rename ThumbstickX.L>duplicate>rename for Right. Repeat for Thumbstick.Position.R
  • Select all four and add component Vector 2 to Float (script)
  • Set up the convertors to extract the axis values we want
  • Select the Y convertors>inspector>Coordinate to extract>Y
  • No need to do for X as X is the default axis already
  • Next make sure that when these vector 2 values change, the float convertors are notified. To do this
  • To do that select ThumbstickPosition.L>inspector>add two Value Changed handlers>set them up by dragging ThumbstickX.L and Y.L into each field>function>Vector2ToFloat>Do transform. Repeat for R
  • Now we need a float action to trigger a response. So let's add a float action to each of the convertors
  • Select all four (X and Ys for left and Right>add component>float action (script)
  • Select ThumbstickX.L in hierarchy>inspector>Vector2ToFloat>add field>drag ThumbstickX.L into field>Function>FloatAction. Receive. Repeat for all four
  • Set up the axis rotators to respond to the float actions just built
  • Select AxisRotator. L>inspector>drag 'ThumbstickX.L to the Axis Rotator Facade>Axis settings>Lateral - and the ThumbstickY.L to the longitudinal axis
  • Set up the target reference (valid container) - it's what we are teleporting to and it's what we need to rotate
  • Select AxisRotator>L>drag Teleport_Curve>L valid container to target settings>target field. Repeat for right
  • Go to hierarchy>Teleporter.Instant>offset usage>Offset Always With Destination Rotation
  • The player rotation will now be set up to  match the valid container objects
  • Set the Position X0 Y0.02 Z0.15 to offset the arrow slightly
  • Rotation X-90 and Y-125 z 90 to align it 
  • Save
  • Test in VR


Implementing teleports - part 4 - to be continued
Add restrictions to where viewers can teleport

https://learn.unity.com/tutorial/unit-4-locomotion-and-ergonomics?courseId=5d955b5dedbc2a319caab9a0&tab=overview&uv=2018.4#5d9691a1edbc2a2d9fcf776e

  • Use layers to define which colliders are valid teleport targets
  • Add a layer : Hierarchy>environment>inspector>layers>edit layers>next available layer>rename 'Teleportable'

  • Hierarchy>Environment>FloorCollider>inspector>layer>teleportable
  • Everything in VRTK that can and cannot be done, uses some kind of rule in the form of a game component
  • Make a new object to contain the teleportation rule. Hierarchy>right click create>empty game object>rename 'TeleportationRule'
  • Select 'TeleportationRule' in the hierarchy>inspector>addcomponent>AnyLayerRule
  • Set the layer mask to teleportable. This makes sure that we only teleport to locations that are on this layer (because it will fail a validation test if it isn't)
  • Select 'Teleporter.Instant'>inspector>drag 'TeleportationRule' to the Teleporter Facade>Target Validity Field

  • At this point the pointer will turn from green to red, however, the teleportation can still happen. To rectify this select both 'Teleport_Curve_L and R' and in the Pointer Settings (Script) drag the 'TeleportationRule' into the Target Validity Field
  • Now my pointer will become red if I attempt to teleport on top of the desk or other objects.
  • Save
  • Test in VR

Implementing teleports part 5 

How to add a teleportation target' allowing the player to snap their teleport ray to a fixed location

  • Create an empty game object>rename 'TeleportTargets'
  • Add component 'Action Dispatcher (Script)
  • Add component 'Transform Proxy Data Emitter (Script)
  • Add slot to Transform Proxy Data Emitter (Script) and drag Teleporter.Instant into the slot>set function>TeleporterFacade>Teleport
  • Assets>DestinationPoint Variant (glowing cylinder) drag into hierarchy>drag onto TeleportTargets
  • Duplicate and place in chosen locations in the room
  • Hierarchy select all DestinationPoint Variants>add slot to 'Activated (Transform Data) field>drag TeleportTargets>change function to 'TransformDataProxyEmitter>Receive
  • The destination points need to be in the transportable layer, or they will block the cursor, when trying to aim at a valid target
  • Select all destination points>change layer to 'transportable'>yes to children prompt
  • At this point in VR the ray would go over the sphere collider and would not snap.
  • Take both of the Teleportation Curves and forward the entered and exit events to the teleportation targets
  • Hierarchy>Teleport_Curve_L and R>Pointer Facade>Entered (EventData) add slot>Exited (EventData) add slot>drag TeleportTargets to both new slots
  • Set function for enter>ActionDispatcher>Enter
  • Set function for exit>ActionDispatcher>Exit
  • Save
  • Test in VR

Snap turns, custom inputs and player occlusion
Adding snap turn to the left controller so players don't need to physically turn (considering for partially sighted players/or those in a wheelchair etc). Also create custom inputs for teleportation and how to block players from looking through objects

To make the pointer move by pushing the thumbstick forward. Raise up and down to increase or decrease distance. Press and release thumbstick down to teleport to chosen destination.
  • Create two empty game objects under the InputHandlers in the hierarchy 
  • Rename to 'TeleporterActivation.R' and 'TeleporterSelection.R'
  • Add component 'TeleporterActivationScript'  onto 'TeleportationActivation.R'
  • Add component 'Teleporter Selection Script' onto 'TeleportationSelection.R' 
  • Set the controller field on both of these to 'R Touch'
  • Hierarchy>under 'TeleporterSelection.R' right click to create empty>rename'RightTeleport.X'>duplicate>rename'RightTelport.Y'
  • Select both>inspector>add component>float action
  • Assign the X and Y to the respective Extract X and Y fields in the Teleporter Selection Script 
  • Select AxisRotator.R in the hierarchy>replace old 'ThumbstickX.R and Y.R with the new X and Y float actions instead
  • Hiearchy>select the following in the InputHandler (all of the old Thumbstick Touched, Pressed and Position ending R)>inspector>disable
  • Hierarchy>Teleport_Curve_R>Replace Activation Action and Activation Selection fields with the new TeleportActivation.R and TeleportSelection.R 
  • Save
  • Test in VR

To create snap turns on the left controller - with a fade to black in-between each rotation

  • Disable the left teleportation by selecting 'Teleport_Curve_L'; ThumbstickTouched.L; ThumbstickPressed.L and AxisRotator.L
  • Search Project>AxesToVector3>drag to hierarchy>inspector>Axis Usage Type>Directional>Lateral Axis>ThumbstickX.L>Longitudinal>None>Lateral Speed Multiplier to 45 (degrees of snap rotation)>Longitudianal Speed>0
  • Project Search (filter)>Vector3Cache (script)>drag to>AxesToVector3
  • Inspector>Events>Add slot>Drag>AxesToVector3object>Function>Vector3Cache>CachedData (this fades the screen in and out with each snap). To make this fade happen....
  • Set up a Camera Colour Overlay Script by:
  • Select AxesToVector3 object>add component>CameraColorOverlay (Script)
  • Whenever the cache is modified we want to call the blink function.
  • Select AxesToVector3 object>On the Vector3Cache (script)>Add slot>Drag AxesToVector3object into new slot>Function>CameraOverlay>Blink. This means whenever you snap left or right the camera will fade
  • To configure the camera overlay script - configure the camera validity field. Heirarchy>TrackedAlias>SceneCameras>Drag to 'Camera Color Overlay (script)>Camera Validity field
  • Set Overlay Material as the TeleportFade material from the project
  • Search TeleportFade material
  • Select AxesToVector3>inspector>Camera Color Overlay>Overlay Material>Drag TeleportFade material into the slot
  • Change duration to half a second (0.5)
  • Create new empty object>rename SnapRotator (which will take care of the camera rotation)
  • Add component>Vector3ToVector2 script
  • Add compenent>Vector2ToVector3 script
  • Add event to AxesToVector 3 Facade>event>drag>SnapRotator to new slot>Function>Vector3ToVector2>Do transform
  • Select 'SnapRotator'>inspector>Vector 3 To Vector 2 Script>Add slot>drag SnapRotator to new slot>Function>Vector2ToVector3. Do Transform
  • Coordinate map>X To X and Y to Y Exclude Z
  • On Vector 2 To Vector 3 script>use default X to X And Y to Y
  • Select 'SnapRotator'>add component>Transform Euler Rotation Mutator (Script)
  • Select 'SnapRotator'>Vector 2 To Vector 3>Add slot>Drag SnapRotator>Function>TransformEulerRotationMutator.DoIncrementProperty
  • Hierarchy>PlayAreaAlias>Drag to 'TransformEulerRotationMutator' Target 
  • Check 'Use Local Values' in 'TransformEulerRotationMutator'>Mutate On Axis>uncheck X and Z
  • Save
  • Test in VR


Snap to floor disable
  • Prevent the player from snapping to irregular surfaces on the floor -which can make the camera suddenly high up and this can be uncomfortable
  • Teleporter.Instant>Internal>SnapToFloor>inspector>disable
Prevent viewer from looking through objects or walls

  • Search 'CollisionFader'>drag to hierarchy under 'Tracked Alias'>Aliases>HeadsetAlias
  • Camera Validity Rule - drag scene cameras to this slot
  • Everything else stays as default
  • Create two new layers 'FadeCamera' and 'FadeOut'
  • Put the CollisionFader on the FadeCamera layer - yes to children prompt
  • Put any objects that need to trigger the fading (e.g cabinet and the wall) onto the FadeOut layer
  • By default objects collide with everything. What we want is the camera fader to activate when hitting the walls or the cabinet, but not when it hits anything else, like the ceiling or the objects in your hands.
  • To do this go to project settings>PhysicsTab>Collision Matrix>configure so the FadeCamera layer only collides with the fadeOut layer

  • Save
  • Test in VR

  • If the viewer moves their head outside of the wall they will see the skybox fade back in. 
  • To change this to black:
  • Hierarchy>OVRCameraRig>TrackingSpace>select all three Left/Center/RightEyeAnchor>inspector>Camera>ClearFlags>Skybox>Solid Color>Background>Colour pick>Black





Comments

Popular posts from this blog

Dr Hannah Thompson, Royal Holloway University