latest blogs

Google Virtual Reality: Lets go for a walk


I haven’t written a piece in a while but while I was playing around with a Unity3d and a Google Cardboard VR Headset, I found quite a few people had difficulty with getting a workable Third Person Locomotion controlled by the headset. So, here we’ll build up to that with a few simple working controls and then put them together to control a character model at the end.

With Google Virtual Reality here’s 2 things we’re going to achieve

  • Move around a scene using a Google Cardboard VR kit in the First Person
  • Create a Character and control its motion in a Chase view with the Cardboard Headset

Screenshot

Lets get things set up

  • Install Unity (I’m using 2018.1.5f1 Personal)
  • Install Google VR SDK (I’m using GoogleVRForUnity_1.130.1)
  • Create Demo Project to verify it all works by following the instructions above.
  • Additional setting
    • Under Resolution and Presentation, uncheck all except Landscape Left, this fixes a bug in the GVR SDK

Create Terrain and Skybox

I find it’s always nice to have something to look at, so lets create a landscape and an object that has some behaviour. Also - it will give us a reference point when we move.

  • Create Terrain
    • Goto Assets >Import Package >Environment
    • Goto Inspector > Click paint brush > Edit Textures
  • Create Skybox
    • Goto Window > Lighting > Settings
    • Set the Skybox Material (i use Cope)
  • Create the objetc for some interaction
    • Create GameObject > 3d Object > Cube
    • Add component EventTrigger, this allows the raycaster to detect it.
    • Finally add a script that will spin the cube and add the following
    public float spinValue = 90;
    // Spin the Cube
      void Update () {
          transform.Rotate(Vector3.up * spinValue * Time.deltaTime);
      }
    

Add the VR components

  • Add the VR Assets as described in the link above
    • GvrEditorEmulator
    • GvrControllerMain
    • GvrEventSystem
    • GvrRecticlePointer (add to MainCamera)
    • GvrPointerPhysicsRayCaster (add to MainCamera)
  • Create a Player
    • Create Menu>GameObject > Empty Object and rename to Player
    • On the Player Object add a CharacterComponent
    • Drag main camera to Player
    • Select Camera and right click on transform and click reset
    • Set Player Position to 1.8
      • we’ll use each unit as a meter

Lets go for a stroll

First Person View

Add the 4 scripts below to the

  • VRLookWalk.cs

    using UnityEngine;
    using System.Collections;
    
    [RequireComponent(typeof(CharacterController))]
    public class VRLookWalk: MonoBehaviour
    {
        public float speed = 3.0F;
    
        private CharacterController characterController;
        private Transform cameraTransform;
    
        void Start()
        {
            characterController = GetComponent<CharacterController>();
            cameraTransform = Camera.main.transform;
        }
    
        void Update()
        {
            Vector3 forward = cameraTransform.TransformDirection(Vector3.forward);
            characterController.SimpleMove(forward * speed);
        }
    }
    
  • VRAutoWalkLookDown.cs

    [RequireComponent(typeof(CharacterController))]
    public class VRAutoWalkLookDown : MonoBehaviour {
    
        public Transform cameraTransform;
        public float toggleAngle = 10.0F;
        public float speed = 3.0F;
        public bool moveForward;
    
        private CharacterController characterController;
    
    
      // Use this for initialization
      void Start () {
            characterController = GetComponent<CharacterController>();
            cameraTransform = Camera.main.transform;
      }
    
      // Update is called once per frame
      void Update () {
    
            if (cameraTransform.eulerAngles.x >= toggleAngle
              && cameraTransform.eulerAngles.x <= 90.0f)
                moveForward = true;
            else
                moveForward = false;
    
            if(moveForward){
                Vector3 forward = cameraTransform.TransformDirection(Vector3.forward);
                characterController.SimpleMove(forward * speed * toggleAngle / 5);
            }
      }
    }
    
  • VRLookWalkKeyboard.cs

    [RequireComponent(typeof(CharacterController))]
    public class VRLookWalkKeyboard: MonoBehaviour
    {
        public float speed = 3.0F;
        public float rotateSpeed = 3.0F;
    
        private CharacterController characterController;
        private Transform cameraTransform;
    
        void Start()
        {
            characterController = GetComponent<CharacterController>();
            cameraTransform = Camera.main.transform;
        }
    
        void Update()
        {
            // read inputs
            var x = Input.GetAxis("Horizontal");
            var z = Input.GetAxis("Vertical");
            // Move Left/Right
            characterController.transform.Rotate(0, x, 0);
    
            // Move forward/backward
            float curSpeed = speed * z;
            Vector3 forward = cameraTransform.TransformDirection(Vector3.forward);
            characterController.SimpleMove(forward * curSpeed);
    
        }
    }
    
  • VRLookWalkMagneticClick.cs

    public class VRLookWalkMagneticClick : MonoBehaviour {
    
        public Transform cameraTransform;
        public float toggleAngle = 10.0F;
        public float speed = 3.0F;
        public bool moveForward;
    
        private CharacterController characterController;
    
      // Use this for initialization
      void Start () {
            characterController = GetComponent<CharacterController>();
            cameraTransform = Camera.main.transform;
      }
    
      // Update is called once per frame
      void Update () {
            if (Input.GetButtonDown("Fire1"))
            {
                moveForward = !moveForward;
            }
    
            if (moveForward)
            {
                // Find the forward direction
                Vector3 forward = cameraTransform.TransformDirection(Vector3.forward);
                characterController.SimpleMove(forward * speed * toggleAngle / 5);
            }
      }
    }
    

Only check one of these at a time to test them all out.

Third Person View

This is the one most people will be interested in - ** controlling a Character with head movement **

  • Create a new Scene as above but stop at the Create Player stage
  • Goto Assets >Import Package >Characters
  • Drag the new asset Standard Assets/Characters/ThirdPersonCharacter/Prefabs/ThirdPersonController to the scene (His name is Ethan apparently)
  • Click the ThirdPersonController and uncheck the Third Person User Control (Script)
    • We don’t want to use this locomotion, we’ll write out own and bind it to the ThirdPersonController
  • Create an Empty Object and call it CameraCradle - drag it to the ThirdPersonController
  • Drag the Main Camera to the CameraCradle
  • In the Scene View, align the view to Ethan, then Menu>Game Object>Align With Viwe
    • This will match the Camera to the position you have the scene in, and will stick it there as it’s a child object
  • Add this script to the MainCamera ThirdPersonVRController.cs

      public class ThirdPersonVRController : MonoBehaviour {
          // A reference to the ThirdPersonCharacter on the object
          public ThirdPersonCharacter m_Character;
          // A reference to the main camera in the scenes transform
          private Transform m_Cam;
    
          void Start()
          {
              Debug.Log("Started");
              // get the transform of the main camera
              if (Camera.main != null)
              {
                  m_Cam = Camera.main.transform;
              }
              else
              {
                  Debug.LogWarning(
                      "Warning: no main camera found. Third person character needs a Camera tagged \"MainCamera\", for camera-relative controls.", gameObject);
                  // we use self-relative controls in this case, which probably isn't what the user wants, but hey, we warned them!
              }
          }
    
          void Update()
          {
              Vector3 forward = m_Cam.TransformDirection(Vector3.forward);
              m_Character.Move( forward, false, false);
          }
      }
    
  • Finally, there is a public property Character on the script above. Select the MainCamera in the Hierarchy View, and you will see it in the Inspector window. then from the Hierarchy View drag the ThirdPersonController to the Character property in the Inspector Window - binding it to the script.
  • Hit Play, and you should be controlling Ethan with slight head motion.
  • Play around with the script and you can make the motion smoother.

References and shoutouts

I’m a n00b to Unity and VR, and it took me about a week to figure this out. Most of what follows is based on these Tutorials and amalgmating pieces of each

VagrantUP: Creating a custom base image


Vagrant Ubuntu Desktop Server

Create a VagrantUp base image for an ubuntu 14.01.1 Virtual Machine

##Prerequisites

Create a Ubuntu Desktop Server in VirtualBox

The creation of a virtual machine on VirtualBox straight forward. Just start VirtualBox, click New and follow the instructions with the following details:

Name and Operating System

  • Name: ubuntu-trusty-desktop-64
  • Type: Linux
  • Version: Ubuntu64

Memory Size

  • 2048

Take defaults for the rest

Now click Start the VM, when the machine boots it will ask for a disk image. Select the Ubuntu ISO you downloaded above. Follow all on screen instructions.

Create a new Administrator user called vagrant with a password of vagrant

The installation process will take a few minutes. Once done and restarted, be sure to run an update to get all the latest patched and updates. The script below will install updates.

sudo apt-get update

Install Virtual Box Guest additions

Customise it in any way you want. The following will install Google Chrome Browser.


cd /tmp
wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb
sudo dpkg -i google-chrome-stable_current_i386.deb

If an error occurs, run this.

sudo apt-get -f install

Finally, power down the VM

Create the Vagrant base

To package a Virtual Machine created in VirtualBox, set the base to the NAME of the box in VirtualBox.

Note You may need to be in the location of the VM image for this to work.

cd ~/VirtualBox\ VMs/

vagrant package --base ubuntu-trusty-desktop-64 --output ubuntu-trusty-desktop.box

Add the box to Vagrants Index

vagrant box add ubuntu-trusty-desktop-64 ubuntu-trusty-desktop.box

Create a vagrant file if you don’t have one already

vagrant init ubuntu-trusty-desktop-64

Distribute the VM

Boot the VM

Test the dsitribution

vagrant up jnyryan/ubuntu-trusty-desktop-64 --provider virtualbox

VagrantUP: Using virtualization for local development


Ever needed a quick local Ubuntu Server for testing? How about a Windows 7 with IE6 for some odd reason. Or a private network with your own gateway, ldap server, domain controller, and clients? That’s what VagrantUp provides, a very quick scripted way to bootstrap virtual machines and blow them away when you’re done with them!

That’s what VagrantUp provides, a way to create virtual machines and networks on your local PC/Laptop for testing and development. It’s a great tool that takes the repetitive nature of creating short lived servers and finally gives you an excuse to boost the RAM on your Development Laptop.

##What is VagrantUp?

Simply put, VagrantUp is a wrapper around your virtualization software (e.g. VirtualBox or VMWare Player) that through the command line interface and a configuration file will allow a user to:

  • download operating system image(s) (and add them to a local library for future use)
  • start the operating system or systems
  • NAT or Bridge the network to your host system
  • forward any ports from your host to the virtual machine(s)
  • provision the system (run a script to install software on the virtual machine)
  • allow users to SSH, RDP to the virtual machine, or just run it in VirtualBox.

A Linux Python Script to hit a MongoDb


The life of a polygot programmer is never done. Changing from language to language frequently can leave heads muddled and hair tousled. So whenever something takes me longer than it should, either due to complexity or hangover - I tend to write it up either in a gist or blog post. So here’s one I struggled with for a while and it’s not that hard.

I wanted to create a quick script to hit a MongoDb database. “But this is not a difficult task” I hear some say. My issue was one of tools rather than code. I spend a lot of my time switching between .Net, nodejs, bash and ruby. None of which i find good for small scripts either due to portability, setup or the programming style. I wanted to find a solution that one I bootstrapped I would be able to do similar scripts in minutes. So my time was spent debating the pros and cons of various scripting languages over implementing the few lines of code. Eventually I settled on python, mainly because I am very amateur at it and figured it’s a great tool for little jobs like this.

First, I assume you have MongoDb somewhere, in this case installed on your local server.

Now if you don’t have pythong installed, well install it using Distribute, the python setup manager.

curl -O http://python-distribute.org/distribute_setup.py
python distribute_setup.py    
easy_install pip  

We’re also going to install pymongo, a package for accessing MongoDB.

python -m pip install pymongo

And finally here’s some python to hit the database:

import pymongo    
connection = pymongo.Connection("localhost", 27017)    
db = connection.test    
db.name    
db.my_collection.save({"Name": "John"})  
db.my_collection.save({"Name": "Frank"})
db.my_collection.save({"Name": "Bill"})   
db.my_collection.find_one()    
for item in db.my_collection.find(): print item["Name"]

Building the Linux Kernel


Ever curious about how you would go about compiling the linux kernel?

This is a quick guide on getting the latest linux code, building new debian packages and installing them.

Warning!! / Disclaimer!! / Common Sense Alert!!

You guessed it! This can hose your OS, so best do this on a virtual machine!

##Installing the dependencies

First we must install the version control management software GIT, this is required so that we can pull down the repository where the source code for the Linux Kernel is maintained. This is not an entirely necessary step as the source could be downloaded as a Tarball and extracted to the disk, but GIT is the preferred way to alter Linux and provides some excellent tools to manage changes - as we will see later when we create a diff of all our changes to the source code.

Execute the following command to install GIT.

sudo apt-get install -y git-core

We then require the build-essential package. This is required for compiling the source code into binaries and building Debian packages. It includes the g++ complier, c libraries, make and the packager builder (Mepis, 2013).

sudo apt-get install -y build-essential

The next dependency kernel-package provides the capability to create custom Debian kernel package images and their associated headers into a header image.

sudo apt-get install -y kernel-package