Sadly due to the current state of UNET, specifically the number of bugs and inconsistencies it suffers from, I have decided to abandon my series of networking tutorials for it for the time being.
This has been prompted by the discovery that my simple MatchMaker based project, which I was writing to demonstrate a custom network manager and HUD, disconnects clients after around 15 seconds due to a bug in UNET (which I have reported, tracker no. 794106). There are also further bugs and omissions in the Matchmaker system that make it difficult to produce a clean and reliable end user experience at the moment.
Consequently I have begun work converting my previous UNET tutorial series to Photon PUN and all further networking tutorials will be based on the same.
Once UNET is more stable I may consider carrying on with tutorials for it, however I think this won’t be likely in the near future.
In case anyone is interested though, here is a link to the abandoned Unity Project I was working on, and these are the scripts, hopefully they may prove to be of use to someone.
It’s been a busy month what with one thing and another, so I haven’t managed to get finished the UNET custom NetworkHUD tutorial I’ve been working on, but I’ll post it as soon as I can.
In the meantime I’ve been doing some groundwork for an RPG idea we’ve had, and one of the first requirements is for an easy way to save and load the state of the various data classes we’ll be using. As this is something that also seems to get asked for on a fairly regular basis in the forums, I thought I’d share what I’ve come up with so far as it might prove useful to others in some situations.
The serialiser as it currently stands is quite simple, it has four static methods, two for serialising the data (one to PlayerPrefs and one as binary data), and two that read in the data and return it in an instance of the corresponding class.
It will serialise any class or struct that is marked as Serialisable and it even works with dictionaries.
This is the code for the serialiser class.
As an example, to save the state of a class to PlayerPrefs you would use something like this:-
To load the data back into the program you would use something like this:-
The way I actually tend to use it though is to wrap the serialiser calls into two methods on the class I want to serialise. An instance method for saving, and a static method for loading the data, which returns an instance of the class populated with the data.
So for example, i might define a PlayerInfo class something like this:-
And then from elsewhere in the program I would load and save the class data like so:-
The Load() function automatically handles the situation where there is no saved data yet, and returns a new instance of the class in that case.
I have made a simple demonstration program that allows you to type in a player name and add and remove items from the inventory. When you exit and restart the program you will see that the changes you made will have been preserved.
Using this generic serialiser it becomes a simple task to save and load even quite complex classes and structs, as long as you remember to mark them as serialisable.
Also remember that if you make any changes to the serialised class definition after you have saved it, you will most likely have to delete the saved data to avoid errors when it tries to load it next.
I hope this proves to be of use to someone, and as always any comments and suggestions are welcome.
What is this tutorial? In this tutorial we will look at how to set up arcade style vehicle physics on a 3D model. As with my previous tutorial, in an attempt to keep it as clear and concise as possible I will keep the game design quite simple, therefore this should be seen as a basis from which to build a game, rather than a tutorial for a complete and finished game.
Who is this tutorial aimed at? This is aimed at people with a reasonable knowledge of C# and Unity as I won’t be explaining in depth basic C# programming concepts or basic Unity concepts, unless it is appropriate to do so within the scope of the tutorial.
Part 1 – The vehicle game object
As this is a tutorial on coding rather than building game objects in the editor, I’m not going to give step by step instructions on how to put together the car and terrain, instead I’ll just give a brief description of the important bits and how they relate to the code, and I’ll provide all assets in a download link at the end of the tutorial.
First of all I should point out that the method we will be using isn’t a realistic physics simulation, instead it uses forces to ‘fake’ the physics, but the outcome is reasonable and gives a nice Mario Kart style feel to the vehicle handling.
The way we’ll achieve this is by firing a raycast down from each corner of the vehicle a certain distance (hoverheight), and if it detects a hit, it adds an upward force. We also adjust the strength of the upward force depending on the distance from the vehicle that the raycast detects the hit. So effectively the closer the vehicle gets to the ground the stronger it is pushed back away from it, and vice versa.
The length of the ray we fire can be adjusted, and the longer it is the further the vehicle will float above the ground, we will be using a fairly short ray, because we want this to appear as if it is actually on the ground. However by increasing the hoverheight and hoverforce you can simulate a nice hover car type behaviour instead.
This is a very basic example of how we would set up the vehicle game object with the hover points. The red circles indicate where the hover points are positioned. Notice that they are placed vertically above the centre of the vehicle, this is because of the way we simulate gravity in our code, as I’ll explain a bit further on.
We’ll also attach a rigidbody component, and for this example we’ll give it a mass of 70, drag 3 and angular drag 4. These figures work quite well as they are, but you can achieve different handling effects by tweaking them also.
Lastly we give it a box collider to detect collisions with other scene objects and also to prevent the vehicle from falling through the terrain when the downward velocity is very high and we’ll put it on its own layer (vehicle), so we can ignore it in the raycasts.
We’ll also untick Use Gravity, as we will be handling gravity ourselves.
So that’s pretty much all that’s needed for a basic vehicle setup (in the finished project I have added a buggy model which looks a bit nicer than a plain cube).
Part 2 – The code
So now let’s take a look at the code that will turn this into something a bit more interesting. First off we’ll add the various properties that we’ll use to control the behaviour of the buggy as so.
Most of this should be pretty self explanatory, but I’ll explain what some of them do.
The deadZonevalue is just a way to make the controller not so sensitive to small movements. Basically any input below the deadZone threshold is ignored.
The groundedDragvalue is used to change the buggy RigidBody drag factor depending on whether the buggy is grounded or in the air.
The dustTrailsarray will hold references to the particle systems that play when the wheels are grounded.
The layerMaskproperty is used to prevent the hover point raycasts from registering hits on the buggy.
Next we have the Startfunction, which stores a reference to the buggy Rigidbody and stores a reference to the inverse of its LayerMask, for use in the Raycast later.
It also sets the Rigidbody.centerOfMass to be one unit below the buggy, this helps to keep it a bit more stable when it’s in the air.
In the Updatefunction we read the current input and assign a value to the acceleration and rotation from it.
Most of the work is done in FixedUpdate, so let’s take a look at this one bit at a time:-
This block of code above handles the hover/bounce behaviour.
To start with it clears the grounded flag.
Then, for each of the hover points, it fires a raycast of hoverHeight length downwards, and if it detects a hit it applies a force in the opposite direction and scales it depending on the distance the hover point is away from the hit point. So the closer the hover point is to the point which the ray cast hits, the greater the force that is applied to push it back. Kind of like what happens when you compress a spring. Grounded is also set to true if any of the raycasts detect a hit.
If, however the hover point raycast doesn’t detect a hit, then that means this wheel/corner of the vehicle is off the ground, so we need to handle this differently as follows.
It compares the y position of each hover point with the y position of the vehicle, and pushes it up if it’s below it, or down if it’s above it. This serves two purposes, firstly it makes the vehicle automatically level out when it’s in the air, and secondly it applies a fake gravity effect. This is why the hover points need to be positioned above the centre of the vehicle transform, so that when the vehicle is in the air it will be pushed back down by the gravityForce amount. If we positioned the hover points below the y position of the vehicle transform, once it left the ground it would fly up into the air and never come down.
The next section of code handles other behaviour differences between when the vehicle is grounded and when it is airborne.
So basically, if the vehicle is on the ground, we set the Rigidbody.drag value to the amount we set in the inspector, and we give the dust trail particles a suitable emission rate.
But if the vehicle is in the air we set the Rigidbody.drag to a very low value, and we also drastically reduce the thrust and turn values, as we don’t want to have full control whilst we aren’t on the ground.
Lastly for this section, we iterate through the dustTrails array and set the particle emissionRate to the appropriate value (10 if grounded, zero if in the air).
Last of all we apply the thrust and turn forces to the vehicle and then limit it’s velocity to the maxVelocity value we set in the inspector.
So that’s the entire vehicle controller script, it produces quite a nice arcade style drive and with a bit more work could form the basis of a fun driving game, you can test out the complete project which can be downloaded from here. Once you have loaded it into Unity you will need to open Assets\Scene 1.
The behaviour of the vehicle can be modified to make it feel like it’s driving on different surfaces by changing the various properties exposed in the inspector, for example to make it feel like it’s on ice change the following properties:-
Grounded Drag = 0.5
Max Velocity = 30
Forward Acceleration = 1500
Reverse Acceleration = 750
Turn Strength = 500
It uses the standard WASD and Arrow keys to control acceleration, braking and turning.