KittenVR: Testing out Collisons

Last week, I introduced KittenVR – a living development experiment where I attempt to document as much of my virtual reality development experiments as possible. I am a Unity n00b and VR fan girl, and my hope with this project is to inspire other aspiring developers to feel confident jumping into their own VR applications, regardless of experience level.

Disclaimer: I ended up not using the Linecast for this, but I wanted to document the pitfalls that I ran into with this attempt. Might as well document the failures as well as the successes, for posterity and all! The solution that I’m currently working with is documented below.

Experimenting with Physics.Linecast

Last week, when I introduced this project, I mentioned that I had mainly gotten the non-VR version of KittenVR working – but I had been stuck for several days on an issue with the Oculus camera rig interfering with my OnClick() raycasting. I sat down on Tuesday night with TheNappingKat from kaharri.com and we spent some time trying various debugging techniques, and had some weird results – after we drew the Ray with the debugger (ADD FUNCTION) we noticed that it was being drawn in completely weird places on the scene. I grabbed a code snippet from one of her upcoming tutorials, but still had issues with nothing colliding properly. I tried:

  • Raycasting from the center anchor of the OVRCameraRig
  • Creating an empty camera that sat in the middle of the OVRCameraRig to use as the MainCamera in an attempt to reset the offset
  • Using the standard FPSController character and adding the OVRCameraRig (this just seemed to create even more problems)
  • Looping through the objects and tagging all of their child objects in case the raycast was hitting a smaller mesh component

Much to my frustration, none of these worked! I dug through the Oculus forums and found a few similar problems, but none of the solutions were working for me. The nature of under-development SDKs is that a lot of things change rapidly between releases, and I had just about everything working against me: I was developing on a Mac, which as of last week Oculus has halted developing for, I was using the 0.4.4 version of the SDK and plugin, and I had the 0.5.1 version of the runtime. Not withstanding all of the other potentially breaking things I had done to my code attempting to fix the raycast, it wasn’t a surprise at this point it still wasn’t working!

I then decided that I was giving up on my attempt at raycasting from the camera, and instead including a target and anchor object in my character controller on Kat’s recommendation. The idea behind this is that I no longer had to worry about raycasting from a specific point on the camera, and instead would attempt to detect a collision between a ray from the anchor object, which sat right in front of the character, and the target, which was ~4 units in front of my character. If they weren’t connecting together, I would know I had hit something.

IT STILL DIDN’T WORK.

There still seemed to be a strange offset, things weren’t registered as being solid despite working perfectly with a normal camera in the scene, and at this point, I stumbled across Physics.Linecast, which was a better solution for checking between two objects than the raycast was in this particular case, because it finally worked! I was (awkwardly) able to collect the kittens in my scene, but it wasn’t without some compromises. For one, I didn’t have my Rift plugged in at the time, so I couldn’t move the direction of the camera (and subsequently, the anchor+target objects). I eventually decided to scrap the Linecast entirely, though, after Kat published her series on creating an FPS with the Oculus Rift and after I saw a post from a Unity meetup in Boston about performance differences between Linecast and Raycast.

Raycasting: It’s finally working!

It was time to dive back into the problem and get to a proper solution! It ended up being a hybrid of the earlier attempts and partially what Kat discussed in her tutorial – but I’m excited to say that as of about two hours ago, the kittens can be collected from within the Rift!

When I originally posted my sample code for the non-VR version of the application in my previous post, I had the PlayerController script attached to the character itself. I made a few changes to the project: for one, I’ve switched my development environment over to Windows, and updated the version of the SDK and runtime that I’m using. I ran into issues with the latest one, so I’m using the 0.5.1 versions and it’s running pretty well at this point.

What ended up working:

  • I completely scrapped the Oculus asset package from my project and reimported it fresh – the newer version of the UnityIntegration package from the Oculus developer site
  • Basing my hierarchy off of Kat’s guide, I created an ‘anchor’ GameObject from a sphere and stuck it under the CenterEyeAnchor from the OVRPlayerController -> OVRCameraRig. It sat 3 units on the Z axis in front of the character, which is a fairly comfortable distance to use as a look-target
  • I then attached my PlayerController to the anchor, rather than the PlayerController itself – this probably could be done a little bit more cleanly with a little refactoring, but for now it’s been working out. Since the OVRPlayerController doesn’t have a jump put in place, I didn’t need to check the position anymore, but that may get changed in the future.

The new code for the PlayerController:

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class PlayerController : MonoBehaviour {

	public int kittens_collected = 0;
	public bool isVisible = false;
	private float timer = 0.0f;
	private string message;

	/**
	 * Use this for initialization
	 **/
	void Start () {

	}
	
	/**
	 * Update is called once per frame.
	 * Check for various game play components. 
	 **/
	void Update () {
		MouseClickListener ();
	}

	/**
	 * A function to check if the player has clicked on a kitten.
	 * Eventually update this with a different, more interactive input type.
	 **/
	void MouseClickListener()
	{
		if (Input.GetMouseButtonDown(0)) {
			RaycastHit hit;
			if (Physics.Raycast(transform.position, transform.forward, out hit, 10))
			{
				Collider _hit = hit.collider;
				GameObject _VICTIM = hit.collider.gameObject;
				if(_VICTIM.tag.Equals("kitten"))
				{
					kittens_collected++;
					Destroy(hit.transform.transform.gameObject);
					Debug.Log("You've collected " + kittens_collected + " kittens!");
				}
				else if (_VICTIM.tag.Equals("leader")) {
					Debug.Log("Hit Leader");
					if(kittens_collected == 0)
					{
						message = "Help! My kittens have gone missing! Can you help collect all 7 of them?";
						isVisible = true;
					}
					else if(kittens_collected == 1)
					{
						message = "You've found one kitten so far! Just 6 more to go!";
						isVisible = true;
					}
					else if(kittens_collected < 7) 					{ 						message = "You've found " + kittens_collected + " kittens so far! Just " + (7 - kittens_collected) + " left to go!"; 						isVisible = true; 					} 					else 					{ 						message = "You've found them all! Thank you so meouch!"; 						isVisible = true; 						System.Threading.Thread.Sleep(2000); 						Application.LoadLevel(Application.loadedLevel); 					} 			 				} 			} 		} 		GUIFunction(); 	} 	void GUIFunction() 	{ 		if (isVisible) { 			timer++; 		} 		 		if (timer > 300f) {
			isVisible = false;
			timer = 0f;
		}
		Display ();
	}

	void Display()
	{
		if (isVisible) {

		}
	}
}

There’s still some empty code blocks in the PlayerController, since I’m working on getting the GUI functional with the VR headset. From my precursory experiments, it looks like OnGUI() and the old drawing functionality isn’t idea for VR displays, so that’s next on my list to tackle. Once the basic UI is in place, version 0.1 of KittenVR will be available for play testing!

Note: all of the code from the KittenController file has been integrated into the PlayerController script, so the updated source code may look different from last time around!

An extra big thanks to Kat (TheNappingKat) for her help sorting out the raycast problems. She’s working on a VR-enabled infinite runner!  

Related Posts

Leave a Reply

Your email address will not be published.