Unity

Last time on Unity Gaming – Getting a hold of learning how to aim and shoot…lol.

We created a scene where we aimed by getting the orientation of the camera and where we were looking. But then, when we tried using this same technique with the Oculus it didn’t work! Now our heroes are stuck. How will they get around their null reference exception and get their shooting ability working!?!?!

Well I mentioned it before.

“The other [method] draws a line from an object, like a gun, or hand out to a target.”

So let’s continue on!

Vector/Object Raycasting

There is no main camera in the scene. So now we need to implement the second common way of aiming and shooting. Which is from an object. Because we can no longer rely on the camera we can create a ray from an object right in front of our character to an angle created by the mouse that will still aim straight to where we are looking. =)

Create an empty GameObject and call it ShotSpawner (this object will act as the origin of our raycast). Child it to the OVRCameraRig.

Note: Remeber this can work without the oculus as well. So you can do this for shooting a gun. Just put the ShotSpawner on the tip of the gun!

ShotSpawnerOVR

In my scene I have moved the TargetCube to (0, 0, 15) to move it out of the way, but still give me a reference. And instead of drawing a Line in debugging I’m going to get the tag of whatever my raycast hits in debugging.

So let’s write the script that will do this.

In ShotSpawner add a new C# script component and name it OVRShoot. Unlike the other scripts we will be saving the gameobject our ray intersects; so we need a RaycastHit object, and a GameObject.

RaycastHit hit;
GameObject hitObject;

The Update method will then look like this:

 void Update()
{
    if (Physics.Raycast(transform.position, transform.forward, out hit, 10))
    {
        hitObject = hit.collider.gameObject;
        Debug.Log(hitObject.tag);
    }
}

So whatever the raycast hits will be stored in the hit parameter of the method if it is true. We can then get the hit’s object, IF it has a collider! So remember if you want to be able to interact with an object it’s top most parent object needs to have a collider we can interact with! (<<– this is super important, and causes a lot of people grief because the raycast will hit a child objects collider instead of the parent’s and then the code breaks. So avoid that grief and remember this tid-bit, TRUST ME! Avoid common mistakes and developing will go a lot more smoothly.)

Before we run the Script now we need to add tags to the cubes in the scene. I’ve added the Enemy tag to them in the Tag drop down in the Inspector.

OculusRaycastWorking

And there you have it! It’s printing the Enemy Tag! So now you can use these methods in your own code. I’ll eventually show you how to use it in the Infinite Runner because I use a slightly different method there becuase of some assets I use.

Happy Coding!

-TheNappingKat

Unity

So there are two main types of aiming. One, uses the camera’s view to shoot a ray directly out in front of you. This is great if you want to look at things to target them. The other draws a line from an object, like a gun, or hand out to a target.

Let’s do the camera one first.

Camera Raycasting

For this I am using the same scene I made in part 1 but I’ve added some cubes to aim at that are in the air to test out my targeting.

So I’m going to create a cube called TargetObject and attach it to my FirstPersonCamera under a gameobject. Then I’ll change the position to (0, 0, 10), and set it’s box collider to Is Trigger so it doesn’t interfere with my characters movement. I do this so I can get a good idea of where my ray is going to pointing. In Unity you can’t see the raycast that emitted unless you draw it with a line render or call debug.drawline (but that only draws it in the scene view). If I were to play the game now. I should see a cube 10 units away from where I’m looking at all times.

TargetObject

Great so now let’s write the raycast like before. Create a new C# script called RaycastShoot

In this update add the following lines:

 void Update () {
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100))
        Debug.DrawLine(ray.origin, hit.point);
    }

What the script is doing is creating a Ray where the orgin is the main camera and the direction is related to the mousePosition and the angle between it and the camera. Then if the raycast hits anything draw a line. In our scene the line should always be drawn since our target object is in front of our character.

DebugRaycast

It’s difficult to see the line, but you can tell in the pic it’s slightly darker than the others.

Now let’s try with the Oculus! You’ll see why we have to change our methods of aiming in a second.

Oculus and Camera Aiming

If you haven’t set up your environment to integrate oculus don’t worry I’ve posted about it before, here, Oculus setup! Again you don’t need the hardware to develop for VR.

First let’s disable our main Character by clicking on the checkbox in the upper left hand corner in the inspector; in disabled mode there should no longer be a check and the object should be greyed out in the hierarchy.

Cool now click and drag in the Oculus Player Controller.

OVRStartScene

Then create another Target cube so we can have a reference as to where we are looking. I moved it to under the OVRCamerRig to (0,0,5) position.

Next we need to add the Raycast script like before. I’ve added it to the OVRCameraRig.

OVRTargetCube

Now when we run it the game still plays but we don’t see the line in the scene view like before. This is because we get a Null ReferenceException from the RaycastShoot Script.

OculusError

The error above is referring to this line of code:

 void Update () {
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); //this one
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100))
        Debug.DrawLine(ray.origin, hit.point);
    }

There is no main camera in the scene. So now we need to implement the second common way of aiming and shooting; which is from an object. Because we can no longer rely on the camera, we must create a ray from an object right in front of our character, to an angle created by the mouse. And since the mouse dictates the orientation of the head, we will still aim straight to where we are looking. =)

Correct Oculus shooting and the second type of shooting will be in part 3…

Happy Coding!

-TheNappingKat

Unity

Okay so this is a little jump ahead of the Unity Gaming Infinite Runner Series. I’ve gotten a lot of questions about this so I’m writing about it now. Because it’s out of order, the examples are in a blank scene, not the Infinite Runner main scene.

Okay, so, most likely when you are shooting something it’s from either right from of the center of the screen or it’s, for the most part, originating from another objet like a hand or gun. This gets kinda complicated when all of a sudden you are using two cameras to judge the “center” of what you are looking at; like when using an oculus…

But no fear learning the general method of shooting isn’t too bad; and then adding the oculus bit will be easy to understand.

Raycasting

So when you aim for or align something in real life do you draw an invisible line from where you are to the thing you are trying to hit? Yes, Great! If not well, cool, but that’s what Raycasting is.

There are 5 possible parameters for the raycasting method in Unity.

  1. Vector3 origin – which is the position in 3d space where you want the ray to start
  2. Vector3 direction – which is the direction you want the ray to point, the first to parameters make a Ray.
  3. *RaycastHit hitInfo – get whatever the Ray hits first and store it in this parameter
  4. *Float maxDistance – this is the magnitude of the Ray aka how far out you want the ray to point
  5. *Int layerMask – what the Ray can Hit

* Indicates that these parameters are optional

There are also two main ways the Raycast method is written.

  • Raycast(Vector3 origin, Vector3 direction, float maxDistance, int layerMask)
  • Raycast(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)

In Unity Raycast method return a Boolean value. True, if the ray hit something, and False if nothing was hit. I should also mention that in Unity Raycasts do not detect colliders for which the raycast is inside. However if you are creating an animation or moving, you should keep the Raycast method in a FixedUpdate method so that the physics library can update the data structures before the Raycast hits a collider at its new position.

Aiming

Now there are 2 types of aiming. One is simply shooting in the direction that the player is facing and one is shooting in the direction that the player is looking.

Let’s do the easy one first – aiming where the player is facing aka not aiming just shooting.

Cool so in my scene I have the regular First Person Character from the Unity Sample Assets package and created some ground by scaling a cube to have dimensions (10, 1, 30).

StartScene

Now lets create a shoot script called simpleShoot.

CreateSimpleScript

In the Update function we want to shoot a new sphere every time I click and shoot it in the “forward direction”. So let’s add the following lines.

 void Update () {
    if (Input.GetButtonDown("Fire1"))
        {
            GameObject clonedBullet;
            clonedBullet = Instantiate(GameObject.CreatePrimitive(PrimitiveType.Sphere),
                transform.position, transform.rotation) as GameObject;
            clonedBullet.AddComponent<Rigidbody>();
            clonedBullet.GetComponent<Rigidbody>().AddForce(clonedBullet.transform.forward * 2000);
        }
 
    }

Cool and if you check it out I’m shooting and the bullets go in the forward direction of the transform of my character! YAY!

SimpleShootScene

Mouse Aim

Okay but that doesn’t shoot the ball in the upward direction when I’m looking up, you say to me. Yes I know that’s the next thing we are going to do. =) …in part two!

Happy Coding! Part 2 coming soon =D

-TheNappingKat

Unity, XR

Hi All,

I solved the NO HMD DETECTED, Tracker Connected error you get with trying to do extended screen when using the headset for the Unity Editor.

NoHMD

Well I got it working, not necessarily solved.

Specs:

  • Lenovo X1 Carbon
  • Intel Core i7 – 3667U CPU 2.0ghz
  • 8gb ram
  • Windows 8.1
  • 64-bit
  • Intel HD Graphics 4000
  • Oculus DK2
  • SDK 5.0.1

To start I detached my oculus from the computer. Reattched the oculus, made sure it was working in the normal Direct HMD Access mode. It was.

1) Then I hit “Windows + P” and made sure my Projection setting was on extended.

2) Then I switched the mode to Extended in the Utility

3)  Then on the desktop I right clicked and hit Screen Resolution.

4) I selected the second screen and hit “Detect”, a window came up with Another display not detected.

5) I made the Oculus screen primary and then switched back to the main computer being primary and it worked. The screen now appeared in the Oculus but the orientation was off. so I just adjusted it in the Screen resolution window.

DisplaySettings

Now the Oculus Configuration Utility looks like this, but it works.

AttachedNoTracker

In the Unity Editor I can move the game tab to the Headset Screen and maximize it, I can still see the awkward black rim around the screen but it’s better than nothing. Hopefully the Oculus team can fix this soon.

OculusExtendedScreenFull

Hope this helps, Happy Coding!

-TheNappingKat

Unity

SignalR and Backend Coding

Hey Everyone. So the backend part of games tends to be some of the most difficult code to write in the project. I’m also not of fan of backend Server code (but that’s just me). In this project I pushed out of my comfort zone to step more into the hardware back end world.

Really this tutorial is about Signal R in general. That way you can follow along and make a hide and seek game, or create your own game based on these principles and fundamentals.

Getting Started

So for those of you that haven’t used Visual Studio, that is the IDE I’m programming with in this tutorial. You can get for FREE here: http://www.visualstudio.com/ 

  1. Make a new empty project

Signal R – Backend

Create a new Project in web

Then, in the New ASP.NET Project window select MVC and Change Authentication to No Authentication.  Click Create Project. Now you need to get the nugget package from the Package Manager.

Tools> Nuget Package Manager> Package Manager Console

Then type:

PM> install-package Microsoft.AspNet.SignalR

If you expand your Scripts folder you will see that the libraries for SignalR have been added.

Now Right-Click the Hubs folder, and click Add | New Item, select the Visual C# | Web | SignalR node in the Installed pane, select SignalR Hub Class (v2) from the options. And Create a new hub called GameHub.cs.

This Hub will be the host of your server and game logic. It will also be what all clients send their messages to.

Add the following code:

Under our project create a new class called Startup.cs, by right clicking the project Add > Class.

using Microsoft.Owin;
using Owin;
 
[assembly: OwinStartupAttribute(typeof(SRHS2backend.Startup))]
namespace SRHS2backend
{
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
app.MapSignalR();
}
}
}

Now go to HomeController.cs in your Controllers folder.

Add the following code snippet:

public ActionResult Game()
{
return View();
}

Now this next part is mostly for seeing which messages are getting to the server and displaying them for the developers to see. We didn’t implement it in this code but there are sources online that show you the javascript and jQuery needed to print to the new view we just created her http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr-and-mvc

Now, your gamehub.cs class is derived from SignalR’s Hub class. This allows you to access all the currently connected clients and the methods within those clients.

To understand it better, the CreateGame(User user, Game g) method would be called in the client code, and defined in GameHub. While the Clients.All.gameGreate(g, sm) is defined in the client side of the code.

The User, Game, and ServerMessage are classes that I created for this specific game. They hold information that is required by each User, Game, and ServerMessage. While AllGamesList and AvailableGames, are Lists that I create in GameHUb so the server can reference all the active and passive games currently in progress.

Signal R – Front End

Now we will make the front end that links with Signal R.

First we want to create a new blank Universal App.

Next we install the SignalR Client NuGet package for both the phone and the windows 8.1 project.

Now the way that the client interacts with the server code that was written is by connecting with the hub and sending messages through that hub.

For the SignalR portion of the client code create a new folder call SignalRCommunication, that contains the following classes: ISignalRHubs.cs, SignalREventArgs.cs, SignalRMessagingContainers.cs, and SignalRMessagingHub.cs.

The ISignalRHub is the interface for your SignalRMessagingHub.

And the SingnalREventArgs.cs acts as the interface allowing all parts of the project to access the messaging events.

The SignalRMessagingHub is where the connection is created between the server hub and client is initiated.

Now to connect with the Server Hub we need the following code:

#region “Implementation”
 
public async virtual void UserLogin(User tabletChatClient)
{
// Fire up SignalR Connection & join chatroom.
try
{
await gameConnection.Start();
 
if (gameConnection.State == Microsoft.AspNet.SignalR.Client.ConnectionState.Connected)
{
await SignalRGameHub.Invoke(“Login”, tabletChatClient);
}
}
catch (Exception ex)
{
 
// Do some error handling. Could not connect to Sever Error.
Debug.WriteLine(“Error: “+ ex.Message);
}

I put mine inside of the first User interaction with the server, so in this case when the User logs in.

For the Phone application if using the emulator you will need to use long polling since the phone emulator uses the PC’s identification number and a lot more work has to go into formatting your computer to run it.

This is the code you will need

#if WINDOWS_PHONE_APP
connection.Start(new LongPollingTransport());
#else
connection.Start();
#endif

Now we need to write code that will listen to events on the SignalR Server and wire them up appropriately

Calling the .On method is how our proxy hub listens to any messages the server passes to the clients.

Lets make this easier to understand by going through .On and explaining what each part is doing.

SignalRGameHub.On<Game, ServerMessage>(“gameCreated”, (g, sm) =>
{
SignalREventArgs gArgs = new SignalREventArgs();
gArgs.CustomGameObject = g;
gArgs.CustomServerMessage = sm;
// Raise custom event & let it bubble up.
SignalRServerNotification(this, gArgs);
});

The .On method can take in as many parameters as needed depending on which server call it’s defining On<x,y,z>.

Before you saw the server gamehub call Clients.All.gameCreated(); in the client code the quotes in SignalRGameHub.On method refer to which ever method we are listening to and then dictates what the client code should do based on the delegate following the On method.

The (g, sm) are the parameters that we defined earlier <x,y> in this case <Game, ServerMessage>. They are a part of a delegate that will create the SignalREventArgs, to parse out a gameObject and a ServerMessage. Then it raises a SignalRServerNotification(this, gArgs) that will trigger an event. You still need to write that event in other parts of your code.

We now need to write the method for the SignalRServerNotification(this, gArgs)

#region “Methods”
 
public virtual void OnSignalRServerNotificationReceived(SignalREventArgs e)
{
if (SignalRServerNotification != null)
{
SignalRServerNotification(this, e);
}
}
 
#endregion

Cool now on to defining calls made by the client that will be sent to the Server.

Make sure to define all the methods that will be sending information to the server. These async virtual methods will be called by the ISignalRHub. The quoted part “UpdateUser”, “CreateGame” and “JoinGame” refer to the methods on the server side GameHub, if the names are not exactly correct the server methods won’t invoke.

SingnalRMesagingContainers refers to the objects that you want to send through JSON to the server to manipulate. Meaning you would define your object classes within this .cs file. However if you already defined your models, in a models(or other name) folder, that will work too, in fact it’s preferred.

Referencing Gamehub

In order for your Signal R Hub to be accessed by all parts/pages of your project you will need to modify the App.xaml.cs in Shared.

public static new App Current
{
get { return Application.Current as App; }
}

Then inside the OnLaunched(LaunchActivatedEventArgs e) method add

App.Current.SignalRHub = new SignalRMessagingHub();

Important! If you are going to be passing objects through SignalR both projects need to have the exact same code for the objects.

Now when calling/listening to the SignalR hub from different pages of your app easy now that we have everything set up.

Inorder to approipately handle the triggered SignalRServerNotifaction we need to add SignalRServerNorification for that page by referencing the App.Current.SignalRHub.SignalRServerNotification

When implementing the SignalRHub_SignalRServerNotification be sure to appropriately handle the dispatcher so the page can still be responsive when events are triggered.

In my code I use the CustomSererMessage to find which state the server is on versus the game. You can implement changing and checking game state however you think best suits your game.

Publishing your Server code

Eventually you want to publish your code to an azure website so anyone who downloads the application can connect to the server.

Use the steps in this tutorial to do so: http://www.asp.net/signalr/overview/deployment/using-signalr-with-azure-web-sites

Sphero

Okay so we finally have the backend set up. Now it’s time to implement more of the front end. Depending on your game you might want to change some of the XAML and front end to suit your purposes but the connection and control of the Sphero will remain the same.

First thing is to add the Sphero SDK that you downloaded to your project references.

https://github.com/SoatExperts/sphero-sdk

Connecting to Sphero

Second is to modify the App.xaml.cs so all pages in the project can remain connected to the same Sphero.

Now go into the page that you want to initiate connection with your sphero. For Hide and Seek I put it in the lobbyPage.xaml.cs since I wanted to make sure users were connected before they started the game. One thing to note about the DiscoverSpheros method; it will only return a list of Spheros that are on and in Bluetooth connection state (blinking red and blue).

private async void DiscoverSpheros()
{
try
{
// Discover paired Spheros
List<SpheroInformation> spheroInformations = new List<SpheroInformation>(await SpheroConnectionProvider.DiscoverSpheros());
 
if (spheroInformations != null && spheroInformations.Count > 0)
{
// Populate list with Discovered Spheros
SpherosDiscovered.ItemsSource = spheroInformations;
}
else
{
// No sphero Paired
MessageDialog dialogNSP = new MessageDialog(“No sphero Paired”);
await dialogNSP.ShowAsync();
}
 
}
catch (NoSpheroFoundException)
{
MessageDialog dialogNSF = new MessageDialog(“No sphero Found”);
dialogNSF.ShowAsync();
}
catch (BluetoothDeactivatedException)
{
// Bluetooth deactivated
MessageDialog dialogBD = new MessageDialog(“Bluetooth deactivated”);
dialogBD.ShowAsync();
}
}

After you discover the Spheros you then need to connect to one.

Controlling Sphero

With your device now connected to the Sphero that you choose, it’s time to implement the controls. Go to the page that you want the controls to appear and open the page’s .xaml file. In this case it was my GamePlayPage.xaml.

Then add the following to the <Page> tag properties:  xmlns:Controls=”using:Sphero.Controls”

Now depending on what else you want to put on the page the placement of this next code block will differ, but the content is still the same.

<Controls:Joystick x:Name=”spheroJoystick” HorizontalAlignment=”Left” Margin=”30,0,0,30″ Grid.Row=”1″ VerticalAlignment=”Bottom” Calibrating=”spheroJoystick_Calibrating” CalibrationReleased=”SpheroJoystick_CalibrationReleased” Moving=”SpheroJoystick_Moving” Released=”SpheroJoystick_Released” PointerReleased=”SpheroJoystick_PointerReleased”/>

The important properties of the Controls:Joystick input are Calibrating, CalibrationReleased, Moving, Released, and PointerReleased. These can be added directly in the XAML or can be added in the Events tab of the Properties Window in Visual Studio.

Almost done, with Sphero. In order for the code in XAML to actually do anything, we need to make sure that the events are implemented and make sure the connection is still active.

private SpheroDevice _spheroDevice;

We check the connection and start the Joystick in the page’s initialize method.

Since we saved the connection in the App.CurrentConnection we can reference even if we navigate to a different page after the initial connection.

And that’s it! You can now get more information from the Sphero if you want to, and track more data. Look in the API for on how to do more with your Sphero.

Hope this helps, Happy Coding!

-TheNappingKat