Posts Tagged ‘Game Development’

Disabling Frustum Culling on a Game Object in Unity

Thursday, December 19th, 2013

You should never disable frustum culling in a release build.

But sometimes it can be useful to do so for debugging or when dealing with a really wacky vertex shader where mesh bounds don’t make sense anymore. Here’s an easy way to disable frustum culling on a game object by moving its bounds into the center of the camera’s frustum:

// boundsTarget is the center of the camera's frustum, in world coordinates:
Vector3 camPosition = camera.transform.position;
Vector3 normCamForward = Vector3.Normalize(camera.transform.forward);
float boundsDistance = (camera.farClipPlane - camera.nearClipPlane) / 2 + camera.nearClipPlane;
Vector3 boundsTarget = camPosition + (normCamForward * boundsDistance);

// The game object's transform will be applied to the mesh's bounds for frustum culling checking.
// We need to "undo" this transform by making the boundsTarget relative to the game object's transform:
Vector3 realtiveBoundsTarget = this.transform.InverseTransformPoint(boundsTarget);

// Set the bounds of the mesh to be a 1x1x1 cube (actually doesn't matter what the size is)
Mesh mesh = GetComponent().mesh;
mesh.bounds = new Bounds(realtiveBoundsTarget, Vector3.one);

[Download C# Unity Script Component]

Visualising the OpenGL 3D Transform Pipeline Using Unity

Saturday, October 12th, 2013

Download

Download Unity package

Transcript

“Hi, I’m Allen Pestaluky. I’m going to go over a simple tool that I’ve made in Unity that visualizes the 3D transform pipeline in OpenGL. You can download it and find the transcript of this video on my blog at allenwp.com or via the link in the video description.

This tool was designed to provide a quick visual refresher on the coordinate systems used during the 3D transform pipeline in OpenGL and Unity. If you’re planning on doing any advanced non-standard vertex transformations, especially in the vertex shader, this tool might help you refresh your memory and will enable you to simulate your transforms in a visualized, debuggable environment rather than blinding coding in the vertex shader. Or, if you’re new to 3D graphics, this tool might help you gain a better visual understanding of 3D graphics theory.

The tool that I’ve made is nothing more than a few scripts and a prefab in a unity scene. These white cube game objects represent vertices that are being passed into the vertex shader. This script assumes that these vertices don’t need any world transformation, but it would be easy to modify the script to add in other transforms to any point in the pipeline. The transform manager hosts the script which creates game objects that represent these vertices as they are transformed by the view, projection, and viewport transformations.

The Scale property adjusts the scale of the generated game objects. The Transform Camera provides the view and projection matrices. You can add any number of game objects to the vertices list to see how they will be transformed by each step of the pipeline. Finally, the View, Projection, and Viewport Transform boolean properties are used to toggle visibility of each transformation step.

You can see that, when run, new orange spheres are added to the scene view. These represent the vertices after they have been transformed by the view matrix of the camera. In Unity, the view matrix is exposed as the “worldToCameraMatrix” property of a camera and it does just that: the view matrix transforms vertices from world coordinates into camera coordinates, also known as eye or view coordinates. As you can see, these coordinates are relative to the eye of the camera. The vertices that are closer to the camera have a smaller z component and vise-versa. But it’s important to note that what you are seeing is not the exact result of the 4 dimensional view transform; first, a homogeneous divide must be performed on the resulting homogeneous 4 dimensional vector to transform it to 3 dimensional space that we can see in the scene view. Or, in this case, we could simply discard the fourth “w” component because it is 1. For each of the transformed vertices, you can see the original 4D coordinates in the “Homogeneous Vertex” property and the 3D coordinates in the position property which is visualized in the scene view.

Next, I’m going to configure the transform manager to show the result of the view and projection transforms. This results in a 4 dimensional coordinate system referred to as “clip space”. Clip space is what most graphics pipelines expect you to return from your vertex shader. No surprise, clipping is performed in this coordinate system by comparing x, y, and z coordinates against w. Any x, y, or z component greater than w or less than -w is clipped. Note that DirectX is slightly different and clips the z axis when it is less than 0. The flashing vertices that you see represent those that are being clipped.

Next, we transform into 3D space known as the normalized device coordinate system by performing the homogenous divide on the clip space vector. You can see that this coordinate system hosts your camera’s view frustum in the form of a canonical view volume between negative 1 and positive 1 on each axis. This volume is represented by the cube outline. All clipped vertices lie outside of this volume. We are now very close to what we see rendered.

Lastly we perform the final viewport transform. This tool doesn’t take any x and y offset into account, but does scale the normalized device coordinates to match the viewport width and height. The transformation into 2 dimensional space is as simple as throwing away the z component from the normalized device coordinates. You can see that this puts us in a coordinate space that matches that of our final viewport.

Hopefully this tool is useful. Please let me know if you have any questions by posting a comment on my blog — you can find the link in the description of this video if you need it. Thanks!”

Two Game Messaging Systems using Observer and Visitor Patterns

Saturday, September 22nd, 2012

Maximum output for minimum input.

…That’s the idea behind Juicifying Your Game. But this can lead to some pretty messy code if you start injecting extra code at every event that happens in your game. This is where messaging/event systems come in handy to ensure that every component of the game is given an opportunity to provide their own juice.

This article is a quick overview of a couple different ways to implement a messaging/event system in your game engine. Typically something similar to the straight observer pattern is used, but there might be situations where using a visitor pattern could assist in more readable and maintainable code.

Straight Observer Pattern

Typically, the observer pattern allows an observer to be registered for notifications when a state change occurs in the system. In this case, we will use it to send game messages to a list of all registered components by calling their handleMessage(GameMessage*) function. This will require all observers to implement a common interface which includes this function and register themselves with the Game Message Manager to receive messages.

observer_message_system

void Component1::handleMessage(GameMessage* message)
{
    switch(message->getMessageType())
    {
    case MessageTypeTargetDestroyed:
        // Do stuff to this
        break;
    // etc.
    }
}

Observer-Visitor Hybrid

A strong benefit of the visitor pattern is full encapsulation of logic within the visitor. In this case the GameMessage will be the visitor which will visit all observers rather than relying on the observers implementing their own handling logic.

visitor_message_system

void GameMessageManager::sendMessage(GameMessage* message)
{
    foreach(std::vector::const_iterator it = components->begin(); it != components->end(); ++it)
    {
        message->visit(*it);
    }
}

class GameMessage
{
public:
    virtual void visit(Component* component) {}
    virtual void visit(Component1* component) {}
    virtual void visit(Component2* component) {}
    virtual void visit(Component3* component) {}
    virtual void visit(Component4* component) {}
}

class TargetDestroyedMessage : public GameMessage
{
public:
    virtual void visit(Component1* component)
    {
        // do stuff to the component
    }

    // etc.
}

This second pattern may promote flexible and reusable public interfaces for certain components because the visitor must perform all actions upon those public interfaces of the components being visited. If you are concerned about your components becoming overladen with message-specific functionality, this pattern may assist in relieving that coupling.

IGDA Ottawa: Indies in the Classroom Talk

Friday, April 22nd, 2011

At a recent Independent Game Developers Association meeting I was asked to talk about my experiences taking Hideout!, a project originally developed as schoolwork, to the Xbox 360 for public sale. The slides and a video of the presentation are below. As always, please pass on any feedback; it’s always much appreciated!

The presentation began with a brief introduction of myself and Hideout! including Hideout’s promotional video.

This meetup was focused on students going above and beyond class requirements and taking their games to the next level. The audience was comprised mainly of students in game development programs or recent graduates. The topics covered include the following:

  • Porting from Windows to Xbox 360 with XNA
  • Xbox Live “Indie Games”
  • Other general game design topics for Hideout!

Download Slides (PPTX)

Changing the Windows Mouse Cursor in XNA

Monday, April 4th, 2011

aero_arrow

Background

For anyone who is looking to develop a mouse-based game for Windows using the XNA framework, it’s pretty critical to be able to change your mouse cursor in game. The first method is to hide the mouse cursor and draw a custom texture in place of it – but anyone who is developing a game that might not be running at a full 60 frames/sec will know that this is does not work well, as it results in a very slow and unresponsive mouse movement.

The Windows operating system is designed to give extremely responsive mouse movement no matter how slow your applications are running, so we’d like to harness this power in XNA while also giving us the power to change our cursors.

Overview

The following will allow you to change the windows cursor in XNA to any .cur or .ani file (full colour, animated, just like through the Windows Control Panel). This is done by changing the cursor of the windows forms handle for the XNA window. To load full colour and animated cursors, we will use the IntPtr LoadCursorFromFile(string) method from user32.dll, as suggested by Hans Passant.

Step 1: Add References

  • Add the “System.Windows.Forms” reference to your game project. Do this by right clicking on the References folder in the Solution Explorer for your project and select “Add Reference…”. It can be found under the “.Net” tab.
  • You will need to include the following namespaces:
using System.Windows.Forms;
// For the NativeMethods helper class:
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Reflection;

Step 2: Add your Custom Cursor

  • Add cursor to your project (let’s say it’s called “cursor.ani” and you put it in the “Content\Cursors” directory).
  • Go to the Properties of this cursor in your Solution Explorer and set the “Build Action” to “None” and “Copy to Output Directory” to “Copy if newer”.

Step 3: Loading The Cursor

You will need something like the following helper method to load your full colour animated cursor into a handle that Windows Forms can use:

// Thanks Hans Passant!
// http://stackoverflow.com/questions/4305800/using-custom-colored-cursors-in-a-c-windows-application
static class NativeMethods
{
    public static Cursor LoadCustomCursor(string path)
    {
        IntPtr hCurs = LoadCursorFromFile(path);
        if (hCurs == IntPtr.Zero) throw new Win32Exception();
        var curs = new Cursor(hCurs);
        // Note: force the cursor to own the handle so it gets released properly
        var fi = typeof(Cursor).GetField("ownHandle", BindingFlags.NonPublic | BindingFlags.Instance);
        fi.SetValue(curs, true);
        return curs;
    }
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    private static extern IntPtr LoadCursorFromFile(string path);
}

Step 4: Changing the Cursor

First, set the mouse to visible:

this.IsMouseVisible = true; // in your Game class

Next, load your cursor using the above static helper method:

Cursor myCursor = NativeMethods.LoadCustomCursor(@"Content\Cursors\cursor.ani");

Now load up the window handle that will let you change the window’s cursor:

Form winForm = (Form)Form.FromHandle(this.Window.Handle);

Simply do the following to change the cursor:

winForm.Cursor = myCursor;

That’s it! Happy game dev-ing!