Thursday, 20 December 2012

Unity - Playmaker - Poison Damage

As I've been using Unity a lot in recent university projects I thought I should write up some of what I've done to show people how I managed to get certain parts working.

For this I used Playmaker which is a visual scripting tool available on the Unity Store but everything can be done in code providing you know how, I'm not going to explain it like that here though as I am not a programmer and will end up confusing you all.

First off I'm going to do an article about poison damage, this is applied randomly with a 1 in 4 chance on taking a hit and will do damage over time until the players health is too low or they heal using an object.

Setting the Health

First off it's important to set the health for the player, so on the Player Character you need to set up a Playmaker FSM, I labelled it health so I don't get it confused with other FSMs. The first thing you need to do is set a global float variable, I called it 'Health'.

Once this is made select the first state and add a 'Set Float Value' action which sets the global variable 'Health' to 100 (or whatever number you want).

You can also add another 'Set Value Float' for 'Max Health' and then use a 'Float Clamp' where you set 'Health' to a minimum value of 0 and a maximum value of the variable 'Max Health' before ticking the 'Every Frame' box (If you do not set up your health in the idle state then you need to move the float clamp to your idle so that it checks it constantly) that way our health can never exceed the maximum health if something does damage to our total amount of health. This will not be used with out poison but I mentioned it anyway so you can have more freedom to experiment.

Finally you will want to set up a health bar so you can see you damage in action. The best way I found to do this was to set up a new FSM on the main camera and then add the action 'GUI Horizontal Slider' and setting the float variable to 'Health'. The slider will show your health and can also be controlled by the designer for play testing, but is obviously not a final solution to a health bar.

Setting up the Poison

To set up the poison in my scene I used a simple cube which damages you on collision, if you have a better AI in place by all means use that, but if this is just a test as mine is then a cube will suffice.

To quickly set up the AI to do damage on contact then add an FSM to the AI, I called it 'Damage'. In the first state set a 'Collision Event' action which 'On Collision Stay' with the tag 'Player' sends an event, in my case I created an event called 'Damage'.

Now I'll create a random element to the poison damage, this is not important but can be added to add some variety. I created a new state which was linked with the 'Damage' event so that on contact with the Player it goes to this new state. I then added the 'Random Float' action and set it to pick a random number between 0 and 3. It then stores this result in a variable called 'Poison_Random'. Then on the 'FINISHED' event send it to a new state.

This new state will now test the random number and if it matches then the player shall become poisoned. To do this we add an action called 'Float Switch' which tests the float variable 'Poison_Random' with 1 float switch which looks to see if the variable is less than 1, if so send event 'Poisoned'. Then add the transitions of the 'Poisoned' event and 'FINISHED'.

First we will link the 'FINISHED' transition to another state as this is easier to set up, in the new state simply add a 'Wait' action which waits for however long you want between attacks and how often it tests poison, in my case I used 6. Then link the 'FINISHED' transition to the 'Collision' state so it loops again.

Finally we finish off this FSM by adding  a new state which happens when the 'Check_Random' state finds he is poisoned. This state will have a 'Set Bool Value' action and it will set a new global boolean variable called 'Poisoned' to true. That's all there is for setting up the poison. Next we need to effect the health of the character, this will be done on the character himself.

Now we move over to the Player Character and set up a new FSM separate from the Health set-up. This starts in an state I named 'Idle' as it currently does nothing. It has a 'Bool Test' action on is which tests every frame to see if the global variable 'Poisoned' is true, if it is false it does nothing, if it is true to transitions to a new state.

This state then takes you to a damage state, where a 'Float Add' action is waiting which adds -1 to the global variable 'Health' meaning it takes 1 HP away. This then has a 'FINISHED' transition to another state which contains a 'Wait' action which waits a second. This connects on a 'FINISHED' transition to another state which has a 'Float Switch' action which looks to see if the global variable 'Health' is less than 11 (this can be changed to suit your game) if it is then send an event called 'Stop_Poison'. There is also and action underneath this called 'Bool Test' which double checks that the global variable 'Poisoned' is still true, this will come into effect when you are cured of the poison.

We then need to link these in a specific way. The start 'Idle' state should go to the 'Test_Health' state, then on the 'FINISHED' transition link it to the 'Damage' state which then links to the 'Wait' state and back round to the 'Test_Health' state. This means it will continue to do damage unless the Player's health drops below 11 or if he heals.

The final state you need to add is to stop the poison. Link the 'Stop_Poison' transition from the 'Test_Health' state to a new state which has a 'Set Bool Value' action in it, then get it to set the global variable 'Poisoned' to false before linking it thought the 'FINISHED' transition back round to the idle so it waits for the Player to be poisoned again.

Congratulations you have working poison (hopefully).

Curing the Poison

So now the Player can get poisoned, great! But it sucks that he can't cure it. Here I'm going to add a simple object in the environment which when the player is near it he can press a key to heal himself and remove the poison.

You can create a new FSM for this but I used the same FSM we used to set up the health, it's up to you what you decide. So after setting up the 'Health' variable it transitions to an 'Idle' state where it checks for collision using the 'Trigger Event' as my healing cube has a collision box around it, I then set this collision cube up with a unique tag which it checked for. This checks for the player entering the trigger, and if it is found to be true then send the event 'Fountain' (as in this case the healing cube will eventually be a fountain) This then links it to a new state.

This state has an action on it called 'Get Key Down' which checks for the Player making key presses. In this case I used the 'F' key. If this is pressed then send a new event I called 'Heal'.

This new state also has another 'Trigger Event' which checks if the Player has left the trigger with the correct collide tag, if so it sends an event which links back to the idle state, so if he leaves the trigger box he can no longer heal.

Then simply add a new state which the 'Heal' event is connected to which has an event on it called 'Set Float Value' which sets 'Health' to 100 again and has another action 'Set Bool Value' which sets the global variable 'Poisoned' to false. This comes into effect back when we set up the poison on the AI as it will break to damage loop and return to idle awaiting more poison.

When this state is finished link it back to the 'Fountain' state so that you can either heal again or it checks that the player has left the fountain and your done, healing and curing the poison complete!

This is by no means the only way to set these functions up, probably not even the best, but for testing or for a something that doesn't require top end programming such as the university course I'm on it works just fine.

Hopefully you got all that, if you found any of it confusing or found a problem with it then drop me an email, if can be found on my contact details page. Alternatively you can check out my beginners guide to Playmaker if you are confused with how to work Playmaker.

1 comment:

  1. Its old now

    but thanks if possible plz add how to build a enemy ai that shoot the player