Guards vs Skeletons

Hi folks,

So I’ve done a little more work on my project.  This time I’ve sandboxed the progress in a new scene, with a road and some buildings.  The main aspects of experimentation have been Unity 4.1’s new MecAnim animation system, patrol pathing, and basic AI for recognition, attack, retarget, knockout and respawn.

TL;DR – here is the video:

As you can see the combat behaviour is not totally optimised but the general idea is there.

In terms of working materials, I have used a couple of assets from the asset store (one purchased – the guard and associated mecanim animations, the other free – the skeleton model and animations), and also some AI scripts following a bread trail starting  here.  Working with the AI scripts was quite interesting.  Amongst the key learnings I gathered (or rather, the key bugs), I discovered that quite a few were simply due to the fact that I had transforms in the wrong location.  Making extensive use of Debug.Log statements to check that the flow of the script was working as I expected was very useful and helped guide me to avoid various pitfalls.  I also found that simply defining obvious booleans (eg, Engaging, Attacking, Friendly) was helpful for debugging.

Basically what I wanted to implement was the following – a situation where there are three types of creature: players, guards, and mobs (enemies).  Enemies view players and guards as viable targets, players and guards view enemies as viable targets.  If there are none of the other present, guards (or monsters) will path on a preset sequence of waypoints.  If a hostile rel them passes into their line of sight (I found that checking for ray collision was largely empty unless I raised the ray emanating from the creature a nominal height; this was due to the nature of capsule colliders I am using for creatures), or is sufficiently close (their “noise” > given threshold value) then they move to engage that target.

Once they are adjacent to the target they move to attack it (I found that I needed to reset the transform periodically for creatures when they were attacking, otherwise it bugged out, ie they did not stay fixed in place.  Even when I did this I became confused since it was still bugging out, but then I realised I need to fix the rotation as well.  So prior to attack I calculated the initial position and rotation information and then fed these as temp vars into the attack function).  If the target moves out of range they follow and re-engage.  If the target is reduced to < 0 hp it is destroyed; the associated spawn point for that target is then empty.  The spawn point then detects this and a cooldown timer is initiated.  Once this cooldown timer reaches 0 a new creature is popped at the spawn point and starts to patrol, etc.  As part of the spawn process the list of targets for the creature which struck the knockout blow is refreshed, and a new goal (hostile creature) assigned if there are any in range.  It then proceeds to attack the new hostile creature.

I decided that skeletons should have 50hp and guards 100hp.  They both do a similar amount of damage.  In the video you can see the cycle of destroy-respawn-destroy-respawn, an unending tide of guards and skeletons leaping to rejoin the fray to replace their fallen comrades.

One more thing is worth mentioning.  I also kept track of variables to make sure that the animation playing is appropriate – this is the MecAnim part of the picture.  So the guards and skeletons have state machines for their animations, as well as for their AI behaviour.

————————————-

I am reasonably satisfied with the outcome, but I know that in theory the implementation could be a lot cleaner.  My code is not totally unreadable but still is, for some scripts, way too long and should be written in a more sensible, concise format.  I’m also certain that in a few places I’ve written out the same functionality more than once; a bit more focus on reusability certainly would not go amiss.  And also redundancy – I’m fairly certain that the code is not as tight as it probably should be, in fact, I know that it isn’t.  This applies more generally to the project at large.  There are many places in my work where I’ve coded the same functionality for different things in different contexts.  Or even functions that have not been used.

So a little work needs to be done at some point on said matters.

In particular, todos that spring foremost to mind with this particular line of work (many of which, such as style, readability, best practice etc. I likely will not implement since this is primarily a “finding my coding feet” ongoing exercise):

  • make it clearer if a creature is in combat (ie, none of this running around in circles spontaneously business) – it could be that artifacts such as running around in circles occur because noise isn’t refreshed immediately for the goal creature when the original target is destroyed.  This could be fairly easily redressed.  Or maybe I might like to simply have a fixed (small) radius wherein if the goal is within that circle the creature automatically moves to attack (this is currently not the case, but it should be, and that is what noise/”sound” detection (generalisation of said idea) was supposed to do)
  • possibly aim to fix creatures in place during combat – try to make things more static
  • morale stat for creatures – chance to run away if allies nearby down / no support (possibly hard) or hp low; then move randomly away from attacker, or seek “wall” tagged object to attempt to throw off attacker?
  • knockout animation & possible option (if player dealt k.o.) for ability to loot the creature; then despawn timer prior to respawn
  • refactor the code to make some of the classes less lengthy and so that they have a more logical structure
  • subclass creature.cs (my main AI script) as part of a SFS_creature.cs script so that it interacts well with smartfoxserver
  • NPC_targeting.cs (my main AI targeting / listing script) – make this dependent more on “Broadcast messages”, possibly local messages.  There is a messaging system I am currently using for health bars – this however is more general and can be extended.  If the world becomes quite large and hence contains 100s of monsters, guards, players etc I do not want every single monster / guard / player to have a list of length 400 encoding and tracking the position of everything else in the world – that would be untenable.  But that is precisely how the program works currently.  Evidently this will have to be fixed, so that only enemies / guards in noise / detection / aggro radius are detected.  Or “targeting radius” which is larger than aggro radius.
  • Incorporate the idea of “threat” levels depending on which creature is damaging which – ie first calculated purely as a function of total damage dealt, then maybe factoring in threat generation abilities (eg taunt – sets to top threat) or threat reduction abilities (feint), and threat reset effects (moving beyond targeting radius – as per point above).  Evidently want the creature with highest threat to be the creature targeted.

The next part of the project will focus on hooking up a mysql database with the smartfoxserver software I am using as described here.  Basically I’d like to aim at storing 8 fields: username, password, spawn location (x,y,z) and last seen location (x,y,z).  Essentially I would like last location to be updated every time the player logs out, and then persisted in the database, so that when they log back in (if it is not a first time logon), they appear at that location.

If it is a first time logon they appear at the default spawn location, and last location is null until populated.

The architecture of the goal application will essentially be

client unity application <-> server SFS2X application <-> mysql database

with <-> denoting two way communication, the client application written in C#, the server application written in Java, as is currently the case; the new component will be the database.  Naturally a database can consist of more than one table, and more than 8 fields.  In a full blown, sophisticated application, there is no reason that all data about the players should be able to be stored in an appropriate database schema.  So certainly there is considerable room for extending this aspect of my learning, once I’ve managed to get this proof-of-principle up and running.

Consequent to this I might look at readapting this patrol example for SFS2X-deployed unity games, or something completely different.

Advertisements

Tags: , , , , , , , , , , ,

7 Responses to “Guards vs Skeletons”

  1. Terry Morgan Says:

    I can make a player with mecanim, but I already have a player
    happening, what I need is to make many enemies with the
    same idle, run, walk, die animations. I can’t figure out how to
    use mecanim for enemies, any ideas?

  2. Blue Minnow Says:

    Hello there,

    Thanks for your question.

    It should not be too different from creating a mecanim process for your player. First, identify the animations (eg, idle, run, walk, die) you wish to use (that you are already using for your player). Note that not all animation assets will necessarily be compatible with MecAnim here (at least, that has been my experience). You will be looking for pure animation files. Then, go to the Unity Project tab, create an animator controller in a folder / location of your choice. Then, drag the animations into the animator controller.

    Once you’ve done all this, select your enemy prefab /or enemy avatar in your scene. Click “add component” down the bottom of the Inspector element, and add the component “Animator”. Drag and drop the animator controller you created before into the “Controller” field. Make sure that in the “Avatar” field your enemybaseavatar is selected.

    Now you’re ready to start scripting. Go back to the animator controller and add a few parameters, such as booleans, etc. Then create a C# or javascript script (your controller script) and also attach this to the enemy avatar. In the script reference the animator controller via relevant commands, eg

    anim = GetComponent();

    and then influence booleans by say

    bool isIdle = GetComponent().IdleBoolean;
    anim.SetBool (“IsIdle”, isIdle);

    or

    bool isAttacking = GetComponent().Attacking;
    bool spottedTarget = GetComponent().Engaging;

    anim.SetBool (“IsAttack”, isAttacking);
    anim.SetBool (“SpottedTarget”, spottedTarget);

    where “IsIdle” “IsAttack” and “SpottedTarget” are booleans in your animator controller. Then define appropriate transitions in your animator controller between the animations that depend on the values of these parameters. eg for isAttacking, I have a transition from a running animation to then a sequence of “Attack0” and “Attack1” animations that play in a loop until the target is null (ie, fragged), or the creature itself is destroyed.

    Hope that helps.

    There is a tutorial on all this stuff, too, at this location:

    http://video.unity3d.com/video/7362044/unity-40-mecanim-animation-tutorial

    It more or less covers all I’ve mentioned above but in greater clarity and detail.

  3. Terry Morgan Says:

    Thanks for the info, but I’m a modeler not a programmer. What I really was asking is how to
    stick an idle, run, attack animation on an enemy bad guy, my
    Monster.cs just has these 3 (so far) I can get my mesh(es) to animate
    like the Mixamo? Bootcamp demo guy with Mecanim, but all I want is to put
    him and his 3 (maybe more later) animations into the game with my existing script, is
    there an easy way to do this?

  4. Blue Minnow Says:

    Hi Terry,

    Sure, no worries.

    It is slightly difficult for me to suggest the right approach for you, since I have rather limited information as to what you are doing, or what you’re after in an end product. However I suspect that the mecanim animation tutorial (linked in my comment above) might be your best bet to proceed with what you want to do.

    There are files that ship with that demo you can adapt for your own purposes. The link to the project files is here: http://files.unity3d.com/will/MecanimTute.zip . If I was in your situation I would unpack those files in a new project and get used to the mecanim system, possibly by running through the video (it is not that long – only about 50 minutes). Then you could import your animation files / creature models etc (that you have built / created / designed / modeled) and translate what has been built in the Mecanim tutorial project to your situation.

    In terms of switching between animations simply and easily or in some sort of logical way, it is hard to circumvent programming entirely since you are essentially dealing with AI type problems. However if you are more of a visual person I have heard good things about the RainIndie AI state machine system from Rival Theory. It is similar in design / feel to mecanim but instead of animation states it governs behaviour states (eg, patrol, run, attack, die, etc).

    However it you want to shortcircuit AI and merely showcase what you’ve built (eg, creatures & animations, say for the Unity asset store), it should be fairly straightforward to write a simple script to overlay buttons on the player view, and set up booleans to switch between different animation states.

  5. hike1 Says:

    Hi Blue Minnow,

    I’m using the Dextero Unity RPG framework,
    http://forum.unity3d.com/threads/169428-RELEASED-Dextero-RPG-Framework-%28-Complete-Project-%29

    it doesn’t use Mecanim,
    although I can see where it might come in handy for multiple player
    characters

    I used the source code from here
    http://www.packtpub.com/unity-4-x-cookbook/book

    The shot shows 2 free blender models and 1 I made with blender
    game rig skeleton.

    The problem is, these guys are animating with the controller,
    but there’s no way to tell my MonsterAI.cs that they have all these swat animations going on, the MonsterAI.cs is made for
    a legacy skeleton. As far as I know.

    • Blue Minnow Says:

      (Apologies for the late reply – your post was erroneously rated as a false positive by an overzealous wordpress spam filter.)

      Ah, I think I understand slightly better where you are coming from now. Also, most impressive with your work on the blender game rig – now that’s some new terminology for me to digest. I attempted to make a start learning Blender a couple of months back, but stopped due to the steep learning curve (not to mention the demands on my computer). So well done!

      Thanks very much for giving me the context, ie the assets and references you are using. In order to help you more specifically, however, I’d probably need to have a look at the actual source for the script MonsterAI.cs of which you speak, and also probably see a screenshot / set of screenshots of the Inspector associated to your monster avatar (ie, what scripts / objects have been associated to your monster prefab, etc.) so that I could obtain more complete information as to how you’ve built up your creature model / behaviour and associated animations.

  6. Terry Morgan Says:

    Mail me from a real email address and I’ll send you some info

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: