Project: Gauntlet - Current Iteration

Saturday, December 19, 2009

Day X1: Main enemy model and unwrap.





Short clip demonstrating the model outlined below, in Unity with fog and awesome laser beam.

Main enemy - Giant Robot. 370 polygons.

Time to model, rig with skeleton, unwrap and animate with walk cycle and stop-and-look animation: 3 hours.

No concept art - the character was modelled from a brief idea in a dream. True story.

Model:




T-pose - which appears to show an unnecessary number of edge loops.
However - for the manner in which I wanted the robot to move, they were necessary - observe:




Unwrap:





As the robot will be very very big, and the player very small - most detail is required in the legs, the underarms, the fists and the lower chest.
The unwrap reflects this.

Day X1: Main human model and unwrap

A few models with their respective polycounts and unwraps for you to observe and consider.

Main Character - human biped: 350 polygons.

Time to model, rig with skeleton and unwrap: 3.5 hours.

Concept:


With kudos to Jessica Ellis for the concept art and design.

Model:




Unwrap:





Factoring the context in which the model will be viewed (small screen, above and behind) - the most space for detail was allowed on the arms, the back and the legs. When the character is throwing a projectile, the camera will pan to be beside him.

The player will only ever see a small portion of the characters face, and very little of the characters chest.

Thursday, December 17, 2009

Day Z: Raycast performance, Unity Profiler, unavoidable performance issues and damage mitigation.

As our giant robot rolls along - to uncertain horizons, his head-mounted laser moves too - relative to his skull.

Now, the aim is - to avoid this laser, whether it be by hiding behind a building, a car etc.

Technically - the laser is a basic primitive (a cylinder or cube) - with an Additive Particle shader that gives it the glowing/half transparent appearance.

The issue is this:

If you are hiding behind an obstacle, the laser will appear to come through this obstacle - which would negate the point of hiding.

As the laser is not a light source or physics object, the way I am assuring this does not happen is as follows:

  1. From the parent rotation object (the skull) cast a ray along the axis of the primitive (the laser).
  2. If the raycast strikes a collider, find the distance to this collider.
    1. Scale the laser to equal this distance.
      1. Assuring the laser has a starting scale of 0 along the length axis.
    2. Offset the laser by half of this distance.
      1. As primitives in unity begin with an origin directly in their centre.
  3. Presto, your laser is not penetrating the obstacle.
Now this is fine and functional, but if we refer to our beautiful unity profiler, you see that each raycast is causing a noticeable drop in framerate.

As our laser does not have to be 100% accurate, I have offset each check for boundaries (parametrically).

In a very primitive fashion....

Each listener has a counter, when the counter hits the defined check rate, it will check for a collision.

We mitigate the average damage, while still taking damage at the predefined rate.

The aim is to use this concept over all performance-detrimental tasks (collision detection, raycasting, etc), and offset the counters to assure that not all checks are occurring in one enormous spike.


A glimpse of my hilarious test scene, replete with a random cube (right), an orb flashing at 120bmp (center), a wall and the ray - white. As you can see, the ray does not penetrate the wall.

Wednesday, December 16, 2009

Day Y: The ADHD mindset, the beauty of code modularity - and how I learnt to stop worrying, and love the Giant Robot

As things will tend to do - and as the recent, slightly cryptic post has highlighted - concepts have drifted dramatically - and we have landed on a concept that I think is just as - if not more, engaging and purely awesome.

Allow me to set the scene for you:

A desolate street - cold stone buildings surround you.

You look at your watch... but it doesn't tell you the date - but if you were to guess from your surroundings, it's probably reminiscent of some time between the 1920's and the 1940's.

And where is everybody?

No idea. You're alone.

But what is that in the distance????

It's a GIANT FKING ROBOT WITH A MASSIVE LASER IN IT'S HEAD!


And what's it doing??


You don't know, but you can't help but feel it's your responsibility to stop it.

Quick, take that half-brick, and rain sedimentary destruction down upon his turbulent brow.


That's it, effectively.

One man against an enormous foe. Using nothing but projectiles (using the hold-to-power-up mechanic).
Avoiding certain vaporization at the touch of it's awesome laser eye.

Stay tuned, we have videos, models, concepts - the works!

And what will it be called???

No idea.

Friday, December 11, 2009

Realtime manipulation of an animated mesh and bones in Unity



As mentioned - this is a short and.... ok... video demonstrating realtime modification of a standard animated biped mesh. You can do anything really, this is just a simple demonstration of making an Alien-esque creature from a biped.

Await, with trembling anticipation, the performance of multiple realtime-modified entities on the iPhone.

Forecasts? Hypotheses?

Tricky.

Thursday, December 10, 2009

The Story: The Tree of the Knowledge of Good and Evil

That always bothered me about the Garden of Eden parable... wouldn't God want his children to reach for their fullest possible potential?

I think perhaps it's a reflection of Oedipal fear - that the child will grow to be stronger than the Father, and kill him and take his wife.....

In any case - you - you - you are a man. A man driven by a desire not for gold, or women, or hunger - but a desire to be the best that you can possibly be. To reach the maximum of your human potential.

During your childhood - this desire made you a prodigy, a boy who stood out amongst his peers as an individual who was going places. But - as your intensity grew, so did your distance from your peers and the societal bonds that hold us all from reaching their full potential.

Tortured and exiled by your society for daring to exceed your own capabilities through socially unacceptable means, you journey into the world - to become the most powerful man you can be.

The scenario:

You are an exiled monk - a scholar and martial artist. After having your right arm severed as punishment for your pride, you are left to roam the world - in search of power - whatever form that may take.

In Scene 1 (initial release) - you resolve to seek out the Kings of the four seas (Chinese-styled dragons) - in order to ask their blessing and gain from them some knowledge that will increase your power.

By capturing the Pearl that each Dragon chases, you may ransom it back to the Dragon in exchange for power of your choosing.

Each level will consist of two phases:
  1. Chase the dragon from the ground, attempt to leap onto it's back - avoiding obstacles and building speed until you can successfully make the leap.
  2. Run along the dragon's back - assuring you are not thrown off, until you reach the head and can leap to claim the pearl.
At the culmination of these phases, you are given the choice of one power - be it increased speed, increased jumping ability etc.

At the culmination of all phases, you will be granted your lost arm, and may begin your path to Martial Arts glory.

That's the thought, in any case.

And, in classic style, here's a drawing I made while I got distracted designing a UI communication system for my rent-paying job.



He's clearly got two arms there......

That's the thought, at this point in time. Story may or may not change over the coming weeks - but will be locked (obviously) by the time design and modelling begin.

Thoughts? Feelings?

By summary, the gameplay will be:
  • Run run run!
  • Jump jump jump!
  • Avoid stopping!
By even more abstract summary, the gameplay will be:
  • Build your speed!
Simplicity.

And then we'll see how the iPhone performs and grow from there.

Progress: Day Twenty-Three - Event handling, A modular component-interaction system, Procedural bone transformations on an animated mesh, and all at 120 BPM.

Nearing that oh-so-festive time of the year, and the accompanying professional panic that ensues when people feel the fine-grained sediment of their life slowly ticking away -
That's my romantic way of saying that I have been busy with rent-paying projects these past weeks >.<


But let's not dwell - what have we been doing?


Let's start with a picture, something relatively (relatively) pretty to maintain your interest:





That happy camper is a procedurally-modified version of the low-poly biped that featured a few weeks ago. We'll say he's some sort of.... alien ape of husky head.

As you can see, regardless of the manipulation of his body parts, he observes the original bone animations applied to the biped.

The process is as follows:

  1. Starting with a standard animated biped (using Bones, exported as FBX)
  2. For each body part we wish to modify:
    1. Apply rotation (x,y,z) to the body part
    2. Apply scale (x,y,z) to the body part
    3. Apply offset (x,y,z) to the body part
  3. And presto! play that bad-boy and you can (more or less) make any number of good-looking entities from a standard animated biped.
There were a few technical issues with this that you may need to understand:

  • Applying animated Bone transforms in Unity 
    • Transforms will appear to function until you play an animation on your model - this will reset your transforms (as that is what an animation is)
    • In order to consistently apply your transforms during animation, you must reapply the transformations during your LateUpdate() call.
    • Enjoy!
    • As to how this will perform on a mobile device (iPhone) I have absolutely no idea - stay posted as I purchase Unity Pro and run the profiler over this bad-boy!
You know what?

I might leave that post right here, so you get a succinct little package, and I'll repost with the details of my (now refined) message and event handling system, explain my cryptic 120BPM comment, and get into the real meat of it - gameplay!

Tuesday, December 8, 2009

Unity - Moving Platforms and You. (Triggers, Colliders, Rigidbody and the Character Controller)

Busy busy paying the rent, but here is a little snippet that you may find helpful in your Unity Endeavours.

To my surprise a Character Controller in Unity does not automatically observe moving Colliders within the game world - net result, a platform that moves around (up/down/left/right) will not support a Character Controller... you will just... fall through.

Here's my quick little solution - reasonably elegant - be wary of using CharacterController.isGrounded if you are observing a 'jump' effect - I recommend defining a global "isFalling" state that you can trigger in one of these functions.

Requirements:
A gameobject with a CharacterController
A gameobject with a Collider and a Rigidbody - tagged as "Platform", or utilizing any defining mark that you care to use - I usually use a small component that contains myriad tags and category information about an entity.


Apply these functions to a script on your your CharacterController:

   void OnTriggerEnter(Collider t)
    {
        Debug.Log("On trigger enter in " + gameObject.name);
        if (t.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = t.gameObject.transform;
            Debug.Log("Parented");
        }
    }

    void OnTriggerExit(Collider t)
    {
        Debug.Log("On trigger exit in " + gameObject.name);
        if (t.gameObject.tag == "Platform")
        {
            gameObject.transform.parent = null;
            Debug.Log("Unparented");
        }
    }

Effectively, your CharacterController will move and be moved relative to the Platform while colliding (standing on), and relative to the world when not colliding.

It's really just a quickly-written piece of code for something you may or may not come across. Take it and use it in the spirit in which it was created.

Saturday, December 5, 2009

Progress: Day Eleven. Signals or Messenging in Unity / C#, the battle between modularity and performance.

A busy busy week of paying rent - was this week past, and it is this moment that we take the time to reflect on those who didn't make it to Sunday.
Free time *hold for applause*
Energy and enthusiasm *hold for applause*
x-hundred dollars for a one-use suit *hold for applause*


Yes, it's been one of THOSE weeks - a week of fulfilling the old 'non-optional social obligations'.


But rest assured, my dear friend - that you have always, always been in my mind. And with that, allow me to give you a rundown on what we have been doing in Unity and C# this week.

Signals and Messenging.

This week I was quite concerned with developing a small framework that would handle the management of states and variables between objects in the gameworld.

This framework had to fulfill a handful of contradictory requirements:
  • Modularity / Abstraction
    • I would prefer this framework to be applicable to ANY game design scenario, to allow reuse in the future.
    • HOWEVER the issue with this is that it extends the due-date of a deliverable. Working on frameworks is fine, BUT it must be actually used to make something. Keep on the straight and narrow.
  • Efficiency
    • Obviously, for iPhone, efficiency is key. So the elimination of un-necessary function calls is key.
  • Small memory footprint
    • I believe the iPhone has something around the 43meg memory mark for an application, which means that we want to eliminate sprawling data structures and retain memory for graphics and sound.
Unfortunately, these are relatively contradictory - as modularity and abstraction usually increase the memory footprint of a program and decrease (slightly) it's efficiency.

I understand this is an arguable statement without qualification, but it is generally correct.

We can try though, can we not?


So here is a breakdown of how the game object code is put together:

There are four main classes in the Game Object:

  • Event
    • An event is an action that is performed in the gameworld.
    • It may be user input (key down), or an internally-initiated event (game object-to-game object).
    • As the result of an event, one of many variables may be altered, and one or many states may be changed.
      • E.g: Key down - jumping = true, gravity = 20.0f, something = false and so forth.
  • Variable
    • A variable is set as a result of an event.
    • It may be the value of the input (axis value) or a predefined value (eg: speed += 10)
  • State
    • A state is a true/false indicator that the game object is in a given state (eg: jumping).
    • A state is evaluated either per Update() or upon state change, and will trigger one or many actions.
  • Action
    • An action is initiated when the game object is in a given state
    • An action has a lifespan that is internally defined and regulated
    • Upon completion, and action will revert given states and set given variables (through the use of an event).
    • The Action is the core of all gameplay-specific logic - all gameplay is contained in actions.
So this is the core of the state management logic - as all gameplay feeds from a common repository of variables, communication between gameplay elements can happen in a relatively transparent manner.

I have some very nice graphical examples to include later - stay tuned.