Thursday 28 February 2013

A Matter of State

So I've been delving into mecanim a bit more, Ryan has some new animations for me to look at but i'll be lagging behind a bit on that - need to nail down some blending between combat and non combat camera mode here.

One aspect that seems to be taken care of is the ability to trap state transitions (start and end).  This is a huge help because it means that reloads/pickups/firing/etc... can all have a state guard changed at the very start or finish of them, which allows me to keep things in sync fairly well.  I'm still seeing some slop in that you can get stuck in a state of Firing - so working out these bugs before deploying a new webplayer.  The resulting code for tonights herculean struggle with Mecanim looks as follows:


Basically the approach here is to poll for the current and next animation states.  Since the mecanim API does not expose names, we use the name hashes.  I've added a little "rules" string array that takes and maps all the events on the RHS to the name on the LHS.  Normally this code will generate method names per state, something like:

Pistol_Draw = OnPistol_DrawStart( ) & OnPistol_DrawEnd( ).

You simply define those methods in one of the target transforms scripts and it will catch the event and away you go.

This can become quite onerous however with the number of state combinations you'll need to track, so  the "rules" array lets you map multiple events to the same basic "name".

For example, if you go with :

Draw=Pistol_Draw,Rifle_Draw

The string above maps two states, Pistol_Draw and Rifle_Draw to a single method, Draw.  Now in the target transforms script you can use the following:

OnDrawStart( ) & OnDrawEnd( ).

So far it's working well and supplements the other mecanim event library i'm using.

Anyhow, lots and lots of code refactoring and testing left to do here, getting swappable weapons in place started out easy enough but it soon became obvious if I wanted to minimize the amount of code and simplify things, some core framework was needed.  I think that's over with now, it's just a matter of refining transitions and such ... and of course getting the updated animations in place :).

Saturday 23 February 2013

Guns ... Lots of Guns.

Alright, done roughing out the mounting locations.  A couple things I'm going to have to consider either as weapon creation guidelines or in changing mount locations include the SMG holster placement (it will clip through led and right arm easily once you get twisting and turning).  Also, need to think about backpacks and armour, how that will work.  My initial thought here is that armour pieces will come as a prefab, and each piece will have "mount points of type 'weapon'" or "holsters".  Then, if the armour is bulky or wants to have a funky holster location (i.e. perhaps a horizontal holster at bottom or top of pack / chest piece) we can define that in the prefab.  When the item is worn, we will now have another slot to scan for weapon placement ... the problem there is in animation for each case etc ... so this will likely be toned down to simply assume the locations you see now as mount points for each weapon type, and then each armour piece in that area needs to define the offsets/rotations to use for mounting weapons on it.


And another view when the rifle is drawn:


Holster It!

Worked out some code to handle weapons a bit closer to what i'll be aiming for when the game as a proper inventory and scene item framework in place.  So far, tested working with the pistol, take a look (and marvel at the awesomeness of my in-unity 3d cube based gun holster!):


Of course he can draw and holster the gun, and everything looks good, the holster of course is fixed to a mount point on the character, in this case, i'm just using the right thigh with an offset and local rotation to place it nicely.



If you look at the second picture you'll see my approach with aligning the gun to holster, basically what I'm doing here is parenting the gun to either the Avatar.RightHand joint or the Holster.  Each weapon will store its own offset/rotation preference for being mounted within the hand, this may change as I refine the rigging of TheMan more here so that there is a defined "mount point" which provides a pre-oriented transform which weapons can mount too.  But in that case, instead of using a couple of public properties on each weapon (Vector3's), instead i'll just be pre-rotating the weapon so when its mounted and it's position/rotation zero'd out - it will line up still.  I'm not sure at this point if i'll attempt to standardize this too much, most likely yes but it may still be a good idea to retain the ability to manually adjust these position/rotation values (i.e. perhaps to allow for carrying a knife blade down instead of up?).

Now to know which holster to use, I'm defining a few rules here.  Right now my weapons each have a "type" and that weaponType determines which animations to apply.  So i'm re-using that for holsters, which creates the follow scenario:

1. Only one holster PER WEAPON TYPE may exist at a time on TheMan, so for example, no dual shotguns, smgs, knives, etc....

2. A weapon will be matched to a holster of its type, the search done on holster, and parented to that holster.

3. Holster meshes will need to be designed so they can be adjusted on the body for proper engagement of the target weapon.

Right now, I'm assuming zaxis foward and Vector3.zero offset for mounting the weapon to the holster and using the offset/rotation in the case where we mount the weapon to the right hand.  It's looking great, nasty cube mesh aside.  So back to it, now i'll need to set this up for 1h, 2h, shotgun, rifle and smg as well - the animator and I have spots in mind for each of these :).  Will post a new weblplayer as things progress.

Update: Got 2HD working, that was easy :) (knock knock):


Friday 22 February 2013

Falling Through Ground!

One of the interesting issues that comes up when using Rigidbodies and Animation Control is that of Collisions.  I'm not an expert in this matter, but one thing is for sure - i'll need to put some guard conditions in place if i'm to avoid issues like falling through the ground or being able to "brute force" the characters capsule collider through a thin collider.

Encoutered a situation tonight where TheMan would, if dropping from a great height, actually hit the ground but because the physics simulation was a frame behind - would end up falling right through the ground, looking something like this:


The solution for me was to ensure that when we switch from a non-grounded state to a grounded state, use the last known "point of contact" and set the player position to it before exiting the FallingHandler - this cures the problem because it's done in LateUpdate() and will always ensure that BOTH the velocity is Vector3.zero and the position is set above the grounds surface at the end of the game loop and after physics calculations have taken place (so they do not occur and adjust us down again to defeat the guard condition).

End result, looks like this:


One issue i'm seeing still with animations like "LandHard", "LandSoft", etc... is that it can be a real pita to avoid the hands/feet clipping a bit into the ground.  At first I took some time to try and get rid of this and was largely successful, but as you can see above not entirely (take a close look at toes and fingers).

In the final analysis though, this is actually not noticeable at all during a regular playback speed (or what you'll be seeing in-game) and frankly the player will have many other effects that are going on to obscure (hopefully) any anomalous behaviour like this.  For instance, I plan on having a thin ground fog in most areas, weather effects, dirt/refuse, etc... so when it comes together this will be a non issue, at least that's my thought, and if not i'll just use offsets to account for it.

So I finished up the grounded code and went back for some refactoring to optimize it - thought i'd share my results and if anyone has other suggestions, please advise!

Lets start with the roughed out initial code:



So it looks reasonable but there are several issues with this code that make it fragile, less readable and annoyingly verbose, first lets add some comments to the code here and delineate clearly where things happen and why.


So now looking at the spherecast, i'm creating a ray here to perform the sphere cast but is it necessary to create a new object EVERY game cycle just do define the direction? No, in fact there is an alternative method we can call that takes the origin and direction instead of a Ray object instance, lets do that and eliminate the Ray altogether.  It'd be nice to get rid of startPosition as well, but it IS necessary, because it must be calculated each game cycle and the Physics::SphereCast method has no overload for x,y,z instead of a Vector3.  

That hitRadius though, it uses the player collider radius .. will that change somehow during a fall?  Currently, it does not, so this is something we could move right out of the GroundCheck method and initialize once during startup, saving object churn and processing time.  The programming vernacular for analysing where lines of code impact performance the most is "finding the critical path of execution".  The GroundCheck() method is run every game cycle and therefore inefficient code here can have a profound impact on the overall performance of your game, so in this case, regardless of readability, i'm going to cut and slash anything possible to make this as fast and efficient as possible, lets look at what we have after this round of refactoring fun:


That is starting to look a lot better, much more readable and concise despite the extra comments.  We are not done however, there is a BIG hit here which concerns me in the form of:


The problem here is that we have several operations happening.  First, the "Player" static string can mean there is a temporary object created for a string literal, which i know is the case for Java but perhaps C# uses some optimizations like Java's static string pool?

http://stackoverflow.com/questions/4286614/c-sharp-do-string-literals-get-optimised-by-the-compiler

Not too clear to me, and frankly we could be running in a variety of target platforms so why even chance it, besides, there is more.  Another issue is that we invoke NameToLayer each game cycle, I'm not sure on the performance of this, but it's not better than avoiding it in the first place that is for certain.  Then you have the bitwise shift operation and finally applying ~ to do a bitwise complement on the resulting value.  That is what, at least 3 operations and one object creation (potentially).  So looking at this, do we even NEED to have this calculated each time? No, because the players layer never changes so lets wrap this in a constant and use that instead.

There is one final optimization to consider, is the following:


But in this case we don't know that the player collider will always be the same HEIGHT, for instance, we could be moving along in a crouched position or doing a dive roll.  So this seems a reasonable calculation, using Mathf.Infinity to sphere cast downwards with avoids this calculation at the cost of finding more "hits" due to the distance, so let's adjust that to a smaller value that we still know will be further than what grounded distance should be and call it a day.  

The resulting code is like so:


Seems to work well so far!



Tuesday 19 February 2013

Beasties - Meet Louisville!

Roughed in 2HD melee weapons - all pertinent animations are there and it's looking good so far, need to go over attack animations and crouched lower body movement once all bits are in place.  Also captured forward movement into some blend trees and added some guard logic to ensure that even if an animation is not played out correctly, we still can fully holster a weapon.

2HD weapon pose below and its corresponding mecanim state machine.



Tonight, I think i'll push and get 1hd melee in place as well, possibly rough in rifle/shotgun too :) - though i'm thinking that shotgun will require its own unique animation set from rifle, will try it out and see what things look like however.

One comment already was in regards to arming a weapon at the start - i'd like to avoid that but understand the reason for the ask, it's hard to know what is what atm.  Going to look into adding question location tracker and add some quests / hud as things progress, not a priority though as there's still lots of work to be done with animations - rifle/sg, 1hd those are focus tonight - after that it really comes down to a lot of testing and note taking to discuss with animator here and get things looking just right.

Something i'd really enjoy starting in on are mountable gear items - things like backpacks, armour/clothing (yay!), weapons, etc... they need to be encapsulated with their own scripts/prefabs and handled dynamically instead of just mounting each one and disabling its mesh renderer.

So back around we go again, finishing up the remaining core combat animations then going back and testing tweaking and more testing - still lots of areas that could be improved in target matching and smoothing out animation transitions/looking.

Monday 18 February 2013

Simplifying

With such a complex character controller, it's really important to cut down on my mecanim state machine layout - that's just what i'm working on now.

So when I started out with animations, there were no weapons - it was just about getting a GTA/APB style orbit TPC up and running, which was done and it looked pretty good.  The state machine for movement was quite simple as well, requiring only a few states for movement since in this mode there is no strafing or backing up style movements, its just run/walk forward.

Then came combat mode and in order to give combat mode a narrower but more accurate/useful perspective, my thought was to switch the player into a strafing mode with camera above the shoulder.  This meant I needed strafing movements for both standing and crouched stances and the ability to walk backwards in both standing and crouched stances.

The problem is that limiting things to just N, E, S, W movement leads to a lot of wierdness in the legs when transitioning between them.  To smooth this out and clean up motion in general, I've found it necessary to move to N, NE, NW, E, W, S, SW, SE - or 8 directions instead of 4.

That's all well and good but another problem arises with this - using the states and building a network of transitions gets real ugly real fast.  So tonight was time to figure out another approach and since mecanim only supports ONE variable PER blend tree, using blend trees was not going to be trivial.

So the approach i've taken is to build four blend trees and have each tree blend between 3 related animations for it.  In this case, I have ForwardStrafing (for example), which blends NW, N and NE strafe movement.  Then theres RightStrafing which blends NE, E, SE.

In order to facilitate these blend trees it was necessary to use a couple speed variables hSpeed + vSpeed (or horizontal aka. left/right speed and a vertical aka. forward/backward).  That worked for determining states but it still presented two issues:

1. Grabbing the input from keyboard is essentially binary in nature - it sees full values immediately, so either you are moving E or moving W, no degrees between

2. Strafing movement tended to route through idle, causing blips in the animations.

Those issues where both solved by also creating vSpeedSmooth and hSpeedSmooth.  These values "lerp" between the current smoothed value and the target h/vSpeed.  This solved (1) by more gradually switching directions for a smoother turn and (2) by checking against smoothed values to return to idle, which will only be called if the user releases the keys for long enough to lerp back down to idle.  The only issue I have with this solution atm is that the player will not stop on a dime, which often is desirable if you want to peek around a corner or over a ledge without animating past them.  Adjusting the smoothing speed should resolve that.

So here is a comparison between the new approach and old, note the left hand side is the new blend tree approach for standing strafing, while the old is the right side (to be replaced soon!) and represents crouching.


Saturday 16 February 2013

Crawling Under Things

Everyone starts on all fours and now TheMan is doing it again!


So in the game, where there are openings that require you to crawl through them - this is the animation sequence we'll be using.

Still loads of tweaking work to do, I've solved a huge number of combat transition issues - still finishing out combat/interaction transitions now.  After that, i'll need to work on restricting what interactions can be done from within 'combat' mode.

One change i've made is to disable combat mode during an interaction temporarily.  So for example, if you have a weapon in hand (combat mode) and start crawling - it will revert to the non-combat camera mode which lets you orbit TheMan and see around you.  After he gets back up, the camera switches back to combat mode and aligns you appropriately behind the shoulder.

Changing from combat <-> non-combat is nice at the moment, I'm pretty happy with how it quickly but smoothly rolls the camera back into combat position, here is what combat mode looks like right now:


That's only half the screen, but imagine the crosshairs just NE of his elbow, maybe just in the busted out portion of the concrete wall ahead of him in this case.  So it's sort of a quasi-fps view in that your still third person, but moving the mouse around also rotates TheMan to keep pointing in that direction.

I have thought about animating him so you can be running with the camera at his side and shoot to his left, animating the arm(s) out in that direction - but frankly it seems like a lot of pain to implement and one thing i like about 'combat mode' as it sits, is that it reduces your field of view and makes it desirable to want to switch between modes - non-combat for view space and exploration, combat for combat - as it should be.

My goal is to keep tweaking things and try to get a webplayer demo up on logicwell.com here soon, right now that's looking to be another week/end out.

Also have all the remaining animations for combat to get in place - rifle/shotgun, 2hd melee and 1hd melee.  Those should be a riot.  I have a lot of concept art to share coming up as well as a look at the first main "monster" in the game, conveniently called TheBeastie.  He looks awesome, but i'll save that for another post.

Thursday 14 February 2013

Running Slides

Travis, a friend of mine - requested the ability to slide under some obsticles.  So, here it is - while SPRINTING you hit the (C)rouch key, TheMan will go into a slide, take a look:


So that is that, created the RunningSlideHandler to handle this form of player interaction - ok enough fun side bits, back to the real heavy lifting of re-integrating combat motions (melee and rifle/shotgun), handling combat transitions again, combat sprinting and finally dealing with the "any state" properly so I can reduce all the various connections in my animation state machine, heres a taste of what the main layer looks like:


So, some reduction in transitions between the various animation states would be nice :).  You can see i'm starting with the "Slide" animation (Any State is blue box at bottom), the problem is once a condition is met, the AnyState is treated as an asynchronous state, which means that it keeps restarting the slide animation each time.  To prevent this, I'm going to create a "anyLock" parameter, which will be added to each transition from an Any State so that it runs if and only if anyLock is "false".  Then I'll slap in code to the base handler to always set anyLock true OnStart and set it to false OnEnd.

Climb Up And Over

Implemented a new feature tonight - it's similar to the Vault Over + Hop Onto animations.  Basically when you come to a wall where it doesn't make sense to "jump and hang" on it, this animation will fluidly jump up, grab and pull you up to the ledge and the hop forward off of it.

For map design, this will mean I need to ensure these interactions occur where you don't "hop" over to your death on the other side (i.e. a wall segment marked "Climb Up And Over" which has a bottomless pit on the other side :).

Not a big deal, and the nice thing is how this round out wall interactions quite nicely.  My only problem is how difficult it can be to coerce animations to match target cleanly, in this case my solution was to use my own match target code to try and ensure that the player does not clip into the wall when approaching at a run, this can cause a little "snap" in transition from run -> climbUpAndOver, however it's preferable to the alternatives (clipping into wall).

Have a gander at how things are shaping up for Climb Up and Over!







Wednesday 13 February 2013

Climbing Through Windows

Already had this in place but noticed that my code assumed a fixed y-axis, which means that if a window were to be higher or lower from the ground then the player would stand too low/high to look as though they are using the window ledge to step through the window.  All fixed, looks something like this:


My animator (Ryan) has some combat strafing updates, working on integrating that and restoring the appropriate transitions (i.e. combat -> sprinting -> combat, etc).  So that'll be on the menu for a while, one thing I'd like to focus on soon here is the camera code, it needs to use a curve for following player mouse up/down movement.

I'm really needing to find a solid environment modeller/level designer right now, someone who can put out very good work at a reasonable cost (to hobbyist/indies) :).  Will keep on the lookout for that, right now i'm still hip deep in animation work.

Once combat upper/lower blends are refactored and cleaned up for pistol/smg, it's time to use the new 2hd, 1hd, rifle and shotgun animation sets.  With those in place, I'm done general animation bits aside from a few more "candy" animations  - Travis's request for a spriting "slide" animation should be fun to implement and we want to have a few variations on "pull up to ledge".

For instance, my current climb code assumes you want to climb in a few steps - jump and grab, hanging idle, pull over, let go.  This is fine for climbing centric aspects of the level, but there are cases where you'd really want to just jump up, pull over and drop down in one motion - climbing over a fence for instance.  So we'll be adding that variation in.

Jumping is the last big one, for some reason this animation really annoys me - i have two issues with it:

1. I LIKE using SPACE to interact with anything, and being able to hold it down is good for sprinting/parkouring through an area ... how do i retain that with jumping in place and not wanting to use another button?  It'll take some thought, don't like the idea of a player being close to a ladder and not quite ready to interact, then having to wait for a jump animation to complete because they "mis-targetted".

2. Jump can actually be a real pain to implement in a way that syncs up the animation with physics, if we do put it in, i'll likely be a simpler fallout3 style where you just "start" the animation from when hes in-air and don't worry about cool take off/landing transitions.

Tuesday 12 February 2013

Sliding is IN!

Alright another update from the front!



Added a new feature to the TPC - "Sliding"!  So it will detect an uneven surface (must be tagged) and go into a slide .. going to add particle effects for "dust" and sliding sound at some point.

Finished up standing combat stance and camera, working on crouched animations for combat.

The way combat will work is you'll have that APB style free form orbit camera when running around.  When you draw a weapon the camera eases over the right shoulder and changes the field of view angle down to 65deg so your looking at the top half of him, then it offsets to the left a bit so crosshairs are no obscured, heres how it looks now (due to change):



Also have some cool stuff where it uses lookat weighting to adjust the rigs controls to orient certain body parts to a position in 3d space, right now i'm using it to give cool "look over edge" and "look up at" effects, for example:

looking down a slide:



looking back up at a building:



But I'm also using it to handle weapon angle adjustment for shooting:

shooting upwards:



shooting downwards:



A ways off from having a solid webplayer demo yet, as i refactored a TON of animation state stuff, figured out quite a bit on the mecanim side and ended up rebuilding things to layer properly etc,.. about 1-2 weeks out i'd say, but once done it'll encompass, for the most part, the core functionality of my TPC - adding some new interaction animations here too so as to round out the experience a bit and the base you see is a pos model i bought off turbosquid, but it gives me a great "playground" for the demo and helps me playtest controller, going to have it concepted out properly here and a level designer tweak it to play really well - it'll be one of the first "useable" bases the players can clear and control in the sandbox.

Fun fun!

Welcome Survivors

This is my hobby game project, tentatively named 'Nightfall'.  The premise is straight forward - a persistent sandbox game with random/escalating quest drops which revolves around cooperative game play to survive a "session" from beginning to end.  Think of the format here as something like a Killing Floor (action/co-op) meets STALKER (exploration/open world), all with a core AD&D depth of character building and friday night gaming feel :).

There will be npc factions to interact/deal with, loads of beasties to blast and instead of the same approach so many of these games take, my focus will be on a rich interactive TPC which allows for vaulting over subwalls, crawling under obsticles, sliding down surfaces, climbing up ledges, etc... Each aspect of the environment needs to make sense - NO fake doors, invisible barriers, etc... and where those mechanics/shortcuts need to be applied, lets ensure there is a reason and it's not misleading or immersion breaking to the player (i.e. collapsed door entry, mountain/rubble borders, etc).

Along with quest drops and an over arching wave like progression, the underlying game will play in a randomized fashion similar to Wrath of Ashardalon/Ravenloft in its apporach to dealing out events, spawns and situations for the player to progress with.

We'll have level progression in a nice skill based system not unlike SWG, which will also allow for weapon + armour progression/crafting and customization.

I'd like this to be a game that focuses not on PvP or MMO, but brings the game back to those close knit groups of gamers who enjoy a friday/saturday night gaming session that is challenging and engaging.  The world needs persistence so we can get up to put the kids to bed or miss a session driving the family that weekend and still drop back in the game the next week to carry on.

In short, a hardcore game with a casual attitude.