It has not taken me long to come across one of the minor shortcomings of Unity, the InputManager.
It is very simplistic and apparently it cannot be changed at runtime or at least not after the initial Unity provided options screen!
http://docs.unity3d.com/Documentation/Manual/Input.html
I think players of computer games should have some flexibility to customise their controls for a game and it should be easy to do even on the PC not just on Consoles. Not all games need this but first person shooters and similar, do, in my opinion.
Yes, Unity provides some customisation but it is not very user friendly.
I've started to write my own screens and am researching alternate input methods so that I can change this in my own, more user friendly, menus.
This is a list of some of the information, samples and assets I have found:
This is the sort of thing I want but I don't need everything: http://cinput2.weebly.com/index.html
The demo for CInput is useful for finding the Axes used by gamepads: http://cinput2.weebly.com/demo.html
This free project supports Ouya and others at the level I need: https://github.com/pbhogan/InControl
Edit 16 Dec 2014: A project with the same name is now on the Asset Store: https://www.assetstore.unity3d.com/en/#!/content/14695
Saturday, 21 December 2013
Monday, 16 December 2013
Unity Gotcha - What's in a name?
I like my folder structure in any project to be tidy and understandable.
Cosmetically I find it odd to have folders in folders with the same name. For example a Materials folder inside another folder called Materials.
I tidied up my folders and used the name 'Resources' to put all my assets in, within that I have Materials, Textures etc. I thought it sounded like a good name to use.
Bad idea! Folders called 'Resources' have a special meaning in Unity!
Anything in a folder with that name anywhere in the project folder tree will get compiled in to the game build even if the assets within it are never used in the game!
Everything in any other folder name only gets included in the build if it is used somewhere.
Luckily I spotted this before I had gone too far and can move everything to a folder with another name, like 'Content'.
Now I know that some folders have special meanings, I will be more carefull in the future.
Cosmetically I find it odd to have folders in folders with the same name. For example a Materials folder inside another folder called Materials.
I tidied up my folders and used the name 'Resources' to put all my assets in, within that I have Materials, Textures etc. I thought it sounded like a good name to use.
Bad idea! Folders called 'Resources' have a special meaning in Unity!
Anything in a folder with that name anywhere in the project folder tree will get compiled in to the game build even if the assets within it are never used in the game!
Everything in any other folder name only gets included in the build if it is used somewhere.
Luckily I spotted this before I had gone too far and can move everything to a folder with another name, like 'Content'.
Now I know that some folders have special meanings, I will be more carefull in the future.
Sunday, 15 December 2013
Unity Code Naming Conventions
I did a quick bit of searching to find out what naming conventions were used. It turns out that there isn't really one.
http://forum.unity3d.com/threads/135617-C-naming-conventions-for-Unity
http://answers.unity3d.com/questions/10571/where-are-the-rules-of-capitalization-documented.html
Unity supports three programming languages. I'll ignore Boo because I know nothing about it and there are few samples. Most of Unity's older code base is in UnityScript. That has a very similar syntax to JavaScript. In the UnityScript code base the only convention is that class and function names are in PascalCase and variables are in camelCase starting with a lowercase letter.
C# appears to becoming very popular with Unity developers, if not the dominant language but as the syntax is similar most people can mix and match if needed.
As C# is a Microsoft language many people have adopted the Microsoft guidelines for the use of case when working in Unity. I also prefer those naming conventions for case, they are:
PascalCase for public and protected properties and fields and camelCase for private properties and fields with PascalCase for all methods independent of if they are private, public or static etc.
The case is only significant for public or protected elements so that non-case sensitive languages can always reliably access them:
public Method(parameter)
protected Method(parameter)
private Method(parameter)
public Property
protected Property
private property
public Field
protected Field
private field
Some people like to use an underscore in front of _camelCase for private fields but that is their personal preference and appears to go against the recommendations in some of Microsoft's guidelines. Again, that is only significant for public fields, what you use privately is just for readability of the code.
http://forum.unity3d.com/threads/135617-C-naming-conventions-for-Unity
http://answers.unity3d.com/questions/10571/where-are-the-rules-of-capitalization-documented.html
Unity supports three programming languages. I'll ignore Boo because I know nothing about it and there are few samples. Most of Unity's older code base is in UnityScript. That has a very similar syntax to JavaScript. In the UnityScript code base the only convention is that class and function names are in PascalCase and variables are in camelCase starting with a lowercase letter.
C# appears to becoming very popular with Unity developers, if not the dominant language but as the syntax is similar most people can mix and match if needed.
As C# is a Microsoft language many people have adopted the Microsoft guidelines for the use of case when working in Unity. I also prefer those naming conventions for case, they are:
PascalCase for public and protected properties and fields and camelCase for private properties and fields with PascalCase for all methods independent of if they are private, public or static etc.
The case is only significant for public or protected elements so that non-case sensitive languages can always reliably access them:
public Method(parameter)
protected Method(parameter)
private Method(parameter)
public Property
protected Property
private property
public Field
protected Field
private field
Some people like to use an underscore in front of _camelCase for private fields but that is their personal preference and appears to go against the recommendations in some of Microsoft's guidelines. Again, that is only significant for public fields, what you use privately is just for readability of the code.
Saturday, 14 December 2013
Texture Quality
My first hurdle with Unity was understanding texture importing and displaying them in 2D.
Unity is very scene based. Many games and most tutorials put all the options within the player controller of the scene. I find this very odd.
I wanted to start with a menu, the sort of thing virtually all commercial games have and using that menu select the game options and launch the desired level.
That was not too difficult. What has delayed me for the best part of an hour is texture quality. I wanted a good quality logo.
I kept getting a horrid artefact ridden blur!
Every setting I tried with the texture type set to 'Texture' resulted in the same reduced image. It turns out that I need to use the 'GUI' texture type with a format of 'Truecolor' to avoid the texture being compressed and resized when it is imported.
You drag the texture in to any folder, as you do with most assets and then change the settings. Remember to press 'Apply' to see your changes.
Those settings conveniently led me to the 'GUI Texture' and 'GUI Text' objects that are probably better for me to use to create my menus.
Unity is very scene based. Many games and most tutorials put all the options within the player controller of the scene. I find this very odd.
I wanted to start with a menu, the sort of thing virtually all commercial games have and using that menu select the game options and launch the desired level.
That was not too difficult. What has delayed me for the best part of an hour is texture quality. I wanted a good quality logo.
Every setting I tried with the texture type set to 'Texture' resulted in the same reduced image. It turns out that I need to use the 'GUI' texture type with a format of 'Truecolor' to avoid the texture being compressed and resized when it is imported.
You drag the texture in to any folder, as you do with most assets and then change the settings. Remember to press 'Apply' to see your changes.
Those settings conveniently led me to the 'GUI Texture' and 'GUI Text' objects that are probably better for me to use to create my menus.
Monday, 9 December 2013
Unity Startup
As I am new to Unity I thought it was worth noting down any observations I have as I go. Once you become familiar with any development environment you, or at least I, tend to forget how difficult it was to find my way round when I first started.
By default Unity starts with the last project opened.
While experimenting I have found myself swapping between projects to look at different features. It is therefore more convenient for me to select the project I want to open when I start Unity.
I want the Project Wizard to be the first screen I see. It is easy to change in the Edit->Preferences form.
Enable 'Always Show Project Wizard.'
From then on Unity will start by asking you which project to open.
By default Unity starts with the last project opened.
While experimenting I have found myself swapping between projects to look at different features. It is therefore more convenient for me to select the project I want to open when I start Unity.
I want the Project Wizard to be the first screen I see. It is easy to change in the Edit->Preferences form.
Enable 'Always Show Project Wizard.'
From then on Unity will start by asking you which project to open.
Friday, 6 December 2013
Unity 3D SVN Setup and Usage
I have just started to create projects for Unity 3D to try things out.
I use Subversion (SVN) for my code storage and wanted to do the same with my Unity projects. Luckily I had been doing lots of reading so had already come across the fact that unlike code based projects Unity needs a few changes to support using SVN.
The changes are very minor but important. These include some useful reminders detailing what to do:
http://docs.unity3d.com/Documentation/Manual/ExternalVersionControlSystemSupport.html
http://blog.teamthinklabs.com/index.php/2012/04/11/unity-3-5-and-svn-now-easy-and-free-for-all/
Most of the guides mention using Meta-files. Version 4 of Unity has two settings, hidden meta files or visible meta files. I took them to mean use 'Visible' Meta Files' for SVN.
Edit -> Project Settings -> Editor... Mode = Visible Meta Files
There are also Unity add-ins for helping with this but having everything in one intergated development environment (IDE) is not something I have ever worried about so I did not look in to any of those add-ins.
I use TortoiseSVN, and to make things easier I use the Ignore list to stop the Library folder showing up as missing. That folder does not need to be stored with the source code because it is a local cache and will be rebuilt as needed.
Do not select the 'Library(recursive)' option because you may want to use the name 'Library' elsewhere in your repository.
I use the 'Check for Modifications' feature to make sure I commit any changes I make within the project:
When using SVN with Unity do NOT rename folders either in Unity nor with SVN. Renaming in either case messes up the other.
The simple solution is to always create a new folder in Unity and move the assets from the old folder to the new folder within Unity. You can then delete the empty folder in Unity. Add the new folder from your SVN client and commit the project.
You can delete or move assets within Unity it is just renaming folders that has a problem because the meta-data for either SVN or Unity is not updated by the other.
Although it it not tidy, missing folders and files can be marked as deleted when you commit your changes to the SVN repository.
Any missing items must be marked to be included in the commit before you do an Update. If you do an SVN update before marking the missing items then those items will be restored from the repository.
Tortoise SVN has a convenient link to mark all missing items as deleted.
There are other ways to do the same things and here is another article on the same subject.
I use Subversion (SVN) for my code storage and wanted to do the same with my Unity projects. Luckily I had been doing lots of reading so had already come across the fact that unlike code based projects Unity needs a few changes to support using SVN.
The changes are very minor but important. These include some useful reminders detailing what to do:
http://docs.unity3d.com/Documentation/Manual/ExternalVersionControlSystemSupport.html
http://blog.teamthinklabs.com/index.php/2012/04/11/unity-3-5-and-svn-now-easy-and-free-for-all/
Most of the guides mention using Meta-files. Version 4 of Unity has two settings, hidden meta files or visible meta files. I took them to mean use 'Visible' Meta Files' for SVN.
Edit -> Project Settings -> Editor... Mode = Visible Meta Files
There are also Unity add-ins for helping with this but having everything in one intergated development environment (IDE) is not something I have ever worried about so I did not look in to any of those add-ins.
I use TortoiseSVN, and to make things easier I use the Ignore list to stop the Library folder showing up as missing. That folder does not need to be stored with the source code because it is a local cache and will be rebuilt as needed.
Do not select the 'Library(recursive)' option because you may want to use the name 'Library' elsewhere in your repository.
I use the 'Check for Modifications' feature to make sure I commit any changes I make within the project:
When using SVN with Unity do NOT rename folders either in Unity nor with SVN. Renaming in either case messes up the other.
The simple solution is to always create a new folder in Unity and move the assets from the old folder to the new folder within Unity. You can then delete the empty folder in Unity. Add the new folder from your SVN client and commit the project.
You can delete or move assets within Unity it is just renaming folders that has a problem because the meta-data for either SVN or Unity is not updated by the other.
Although it it not tidy, missing folders and files can be marked as deleted when you commit your changes to the SVN repository.
Any missing items must be marked to be included in the commit before you do an Update. If you do an SVN update before marking the missing items then those items will be restored from the repository.
Tortoise SVN has a convenient link to mark all missing items as deleted.
There are other ways to do the same things and here is another article on the same subject.
Wednesday, 27 November 2013
Unity 3D FPS Prefabs Summary
When I started work on Diabolical: The Shooter I made a joke that it might take me ten years. I'm not there yet but I have been going for many years and learnt a huge amount on the way.
I chose XNA because at the time it was the only way for independent developers (indie) to publish to a console. With the advent of the Xbox One it was announced that Unity will be supported and provided to the initial crop of registered indie developers. It is hoped that eventually everyone will be able to developer for the Xbox One but as yet no details or dates have emerged.
I have decided to do some experimentation with Unity to decide if moving development of my game over to Unity is the most likely to get the game finished to the standard I would like within my lifetime!
I will post my progress with a Unity version and take a view at some point which version I will complete.
The first step is to see what prefabs and templates are available to get me started as quickly as possible.
Although I want a Third Person view eventually I want the controls and features to behave more like a First Person Shooter so I intend to start by looking at those. I also need multiplay, online with AI, so they are also prefabs to look for.
Any views I express about the quality or suitablity are my own opinion for my own use and may not be applicable to anyone else's use of that same asset.
Realistic FPS Prefab
+ Movement, Multi-Weapons, Pickups, Melee, Health, AI(simple)
- No Multiplayer, No Online
Full level sample and ran nicely.
Very Good Reviews.
FPS Kit | Version 2.0
+ Multiplayer(Photon), Online(Photon), Movement, Multi-Weapons, Pickups
- Bugs(claimed), No AI
Limited samples but what was there worked well. See the forum thread for more details.
Good Reviews.
Unity Shooter Engine
+ AI, Third and First Person
- No Multiplayer, No Online
Sample did not finish loading!
Good Reviews.
Free Unity FPS Starter Template
+Online
Need to e-mail to get sample code.
Looked very limited and slow in the video.
Free FPS Kit by OneManArmy
+ Vehicles, Multi-Weapons, Pickups, Melee, Health.
- No Muliplayer, No online, No AI
I tried this out and it has everything I need as a starter and more.
Good Reviews.
The web site has other useful stuff on it.
Ultimate FPS
+ Movement, Pickups, Melee
- Just a camera
To maintain a 5 star rating with so many reviews is very good.
Very Good Reviews.
Update: So much more has been added to this since I first looked.
Other things I found that I have not folowed up on:
http://www.youtube.com/watch?v=qdnWby6zx3s
http://www.youtube.com/watch?v=5I5GJbKj1Cg
Don't forget all the excellent complete sample projects provided by Unity themselves:
https://www.assetstore.unity3d.com/#/category/97
I chose XNA because at the time it was the only way for independent developers (indie) to publish to a console. With the advent of the Xbox One it was announced that Unity will be supported and provided to the initial crop of registered indie developers. It is hoped that eventually everyone will be able to developer for the Xbox One but as yet no details or dates have emerged.
I have decided to do some experimentation with Unity to decide if moving development of my game over to Unity is the most likely to get the game finished to the standard I would like within my lifetime!
I will post my progress with a Unity version and take a view at some point which version I will complete.
The first step is to see what prefabs and templates are available to get me started as quickly as possible.
Although I want a Third Person view eventually I want the controls and features to behave more like a First Person Shooter so I intend to start by looking at those. I also need multiplay, online with AI, so they are also prefabs to look for.
Any views I express about the quality or suitablity are my own opinion for my own use and may not be applicable to anyone else's use of that same asset.
Realistic FPS Prefab
+ Movement, Multi-Weapons, Pickups, Melee, Health, AI(simple)
- No Multiplayer, No Online
Full level sample and ran nicely.
Very Good Reviews.
FPS Kit | Version 2.0
+ Multiplayer(Photon), Online(Photon), Movement, Multi-Weapons, Pickups
- Bugs(claimed), No AI
Limited samples but what was there worked well. See the forum thread for more details.
Good Reviews.
Unity Shooter Engine
+ AI, Third and First Person
- No Multiplayer, No Online
Sample did not finish loading!
Good Reviews.
Free Unity FPS Starter Template
+Online
Need to e-mail to get sample code.
Looked very limited and slow in the video.
Free FPS Kit by OneManArmy
+ Vehicles, Multi-Weapons, Pickups, Melee, Health.
- No Muliplayer, No online, No AI
I tried this out and it has everything I need as a starter and more.
Good Reviews.
The web site has other useful stuff on it.
Ultimate FPS
+ Movement, Pickups, Melee
- Just a camera
To maintain a 5 star rating with so many reviews is very good.
Very Good Reviews.
Update: So much more has been added to this since I first looked.
Other things I found that I have not folowed up on:
http://www.youtube.com/watch?v=qdnWby6zx3s
http://www.youtube.com/watch?v=5I5GJbKj1Cg
Don't forget all the excellent complete sample projects provided by Unity themselves:
https://www.assetstore.unity3d.com/#/category/97
Saturday, 21 September 2013
Muzzle Flash
I've just been asked a question by way of a comment to this blog. It's easier to reply by way of a new post. I also haven't had anything to update on the blog for a while so this does two jobs in one.
State of Play
I haven't had anything to say for a while because at the moment my code is broken. By that I mean I'm in the middle of changing something fundamental and it won't compile, let alone run.
I don't like it when the code is in this state. I prefer to make small changes and at the end of every day the code compiles and I can test it. For the last few weeks it has been a mess.
I am in the process of separating the client processes from the server processes and adding all the messages to communicate between the two.
I am concentrating on just the messages to get to a state where I can compile and run the game again but just to spawn a character in to the world, the state of every part of the world needs to be sent from the server to the client and the message to say what and where to spawn.
There's been a fair bit of design and redesign but now it's mainly a lot of typing. I'm nearly there but not quite.
The Question
As mentioned, this post is to specifically answer a question.
"I've been working on a project in which you've helped me out a lot and now I'm at point at which I'm experimenting with particles. I've seen the muzzle flash screenshots on your blog and wanted to ask how did you go about positioning the exact spot to your weapon for the muzzle flash effect."
It was asked by 49ers94 from the Xbox Live developer forums.
It refers not only to the muzzle flash shown in a previous post, but to the start of the projectile particle effects shown in several of the screen shots.
The answer is simple. I store the relative position of the muzzle in relation to the origin of the weapon. That position is transformed by the direction the weapon is aimed in to calculate the position of the muzzle at any point in time.
The above code is within the weapon model wrapper class that I use. The weapon is already moved by whichever bone the weapon is attached to.
If you calculate that relative muzzle offset position manually for each weapon, that is all you should need to do.
One note on the particle effect. The muzzle moves quickly as the character does but to make a nice effect the flash is not instantaneous. I found that if the particle effect stayed still for its duration it looked odd when the weapon moved away from the still visible flash.
The solution I used was to have very short duration particles and create new particles at the new position of the muzzle each frame. This is not how a real flash would happen but this is what I found looked best.
Coding my own Tools
I've taken it a bit further to make it easier to create and edit more weapons. I included a visual method to adjust the muzzle position in to the model viewer that I use for my game.
To make my life even easier I create all my weapons facing the same way and at the same scale. I have not created all my own models but I take the model in to Blender, change its position and scale and output the model to FBX for use in my model viewer and in my game.
I save the relative muzzle position in to a text file for each weapon which is loaded in the content pipeline.
I think that covers everything on that topic. Back to coding my client server architecture... After an all day breakfast that is.
State of Play
I haven't had anything to say for a while because at the moment my code is broken. By that I mean I'm in the middle of changing something fundamental and it won't compile, let alone run.
I don't like it when the code is in this state. I prefer to make small changes and at the end of every day the code compiles and I can test it. For the last few weeks it has been a mess.
I am in the process of separating the client processes from the server processes and adding all the messages to communicate between the two.
I am concentrating on just the messages to get to a state where I can compile and run the game again but just to spawn a character in to the world, the state of every part of the world needs to be sent from the server to the client and the message to say what and where to spawn.
There's been a fair bit of design and redesign but now it's mainly a lot of typing. I'm nearly there but not quite.
The Question
As mentioned, this post is to specifically answer a question.
"I've been working on a project in which you've helped me out a lot and now I'm at point at which I'm experimenting with particles. I've seen the muzzle flash screenshots on your blog and wanted to ask how did you go about positioning the exact spot to your weapon for the muzzle flash effect."
It was asked by 49ers94 from the Xbox Live developer forums.
It refers not only to the muzzle flash shown in a previous post, but to the start of the projectile particle effects shown in several of the screen shots.
The answer is simple. I store the relative position of the muzzle in relation to the origin of the weapon. That position is transformed by the direction the weapon is aimed in to calculate the position of the muzzle at any point in time.
///
/// Get the muzzle location in world space.
/// Grenades will return the hand position because the offset is zero.
///
public Vector3 MuzzleLocation()
{
// Vector3 MuzzleOffset - relative to the weapon origin
// Matrix WorldPosition - position and rotation of the weapon model
return Vector3.Transform(MuzzleOffset, WorldPosition);
}
The above code is within the weapon model wrapper class that I use. The weapon is already moved by whichever bone the weapon is attached to.
If you calculate that relative muzzle offset position manually for each weapon, that is all you should need to do.
One note on the particle effect. The muzzle moves quickly as the character does but to make a nice effect the flash is not instantaneous. I found that if the particle effect stayed still for its duration it looked odd when the weapon moved away from the still visible flash.
The solution I used was to have very short duration particles and create new particles at the new position of the muzzle each frame. This is not how a real flash would happen but this is what I found looked best.
Coding my own Tools
I've taken it a bit further to make it easier to create and edit more weapons. I included a visual method to adjust the muzzle position in to the model viewer that I use for my game.
To make my life even easier I create all my weapons facing the same way and at the same scale. I have not created all my own models but I take the model in to Blender, change its position and scale and output the model to FBX for use in my model viewer and in my game.
I save the relative muzzle position in to a text file for each weapon which is loaded in the content pipeline.
I think that covers everything on that topic. Back to coding my client server architecture... After an all day breakfast that is.
Labels:
3D Modelling,
C#,
Code Sample,
Effect,
Particles,
XNA
Sunday, 28 July 2013
Multi-Threaded Code Is Hard
I know that title is probably stating the obvious to anyone who has tried it but it bears repeating. I have other articles that refer to the same in different ways.
Nearly a month ago I thought I was nearly finished with the change to the physics to get it ready for networking, just a few peculiarities to sort out. Little did I know how long some of those 'peculiarities' would take to find.
Today I have finally confirmed that one of the hardest problems to find was, yet again, caused by multi-threading. When the player shot towards another character sometimes but not always the shot would fire, the muzzle flash would display but no projectile trail was shown and the enemy was not damaged.
Lots of debug code and head scratching later I narrowed it down to the line of sight intersect code with the enemy bounding spheres was returning a distance of zero from the muzzle of the shooting weapon.
In my head and all the maths I did and all the debug code said this was an impossible situation but there it was on my output window, length zero to target and the shot in reverse! Aaaaah!
I got so frustrated I started looking at Unity3D and the possibility of re-writing from scratch and targeting the Xbox One instead of the Xbox 360. After installing Unity3D and taking a quick look at that I decided all I would be doing was moving from one frustrating problem to a different set of frustrating problems.
The break from XNA gave me some time to think and I eventually noticed that the spheres I use to intersect with are updated in a different thread to where I calculate collision. I am not sure how I prove this next statement but all the elements of the position of the spheres update atomically (in one operation) and therefore cannot be out of sync on an individual level but my guess is that as each vector contains three floating point numbers any one could be out of sync with the other two.
Anyway, I've changed the code to lock the changes to the spheres and I can no longer reproduce the problem. At last :-)
Just when you thought this article was over, sorry... moments before writing this up I have come across another error. This time with particles. At least this time I can see immediately it is also caused by multi-threading.
My last word on this today... That particle code has been unchanged for a very long time but threading problems can hit you at any time and may not be easily repeatable!
Nearly a month ago I thought I was nearly finished with the change to the physics to get it ready for networking, just a few peculiarities to sort out. Little did I know how long some of those 'peculiarities' would take to find.
Today I have finally confirmed that one of the hardest problems to find was, yet again, caused by multi-threading. When the player shot towards another character sometimes but not always the shot would fire, the muzzle flash would display but no projectile trail was shown and the enemy was not damaged.
Lots of debug code and head scratching later I narrowed it down to the line of sight intersect code with the enemy bounding spheres was returning a distance of zero from the muzzle of the shooting weapon.
In my head and all the maths I did and all the debug code said this was an impossible situation but there it was on my output window, length zero to target and the shot in reverse! Aaaaah!
I got so frustrated I started looking at Unity3D and the possibility of re-writing from scratch and targeting the Xbox One instead of the Xbox 360. After installing Unity3D and taking a quick look at that I decided all I would be doing was moving from one frustrating problem to a different set of frustrating problems.
The break from XNA gave me some time to think and I eventually noticed that the spheres I use to intersect with are updated in a different thread to where I calculate collision. I am not sure how I prove this next statement but all the elements of the position of the spheres update atomically (in one operation) and therefore cannot be out of sync on an individual level but my guess is that as each vector contains three floating point numbers any one could be out of sync with the other two.
Anyway, I've changed the code to lock the changes to the spheres and I can no longer reproduce the problem. At last :-)
Just when you thought this article was over, sorry... moments before writing this up I have come across another error. This time with particles. At least this time I can see immediately it is also caused by multi-threading.
My last word on this today... That particle code has been unchanged for a very long time but threading problems can hit you at any time and may not be easily repeatable!
Sunday, 30 June 2013
Quaternion Axes
It's been a while since I last posted so before I get in to the topic of this post I'll mention what I've been up to as it has some relevance.
I have been working on adding network game play. It did not take me long to realise that the way I originally did the physics in the game, that works for single player and split screen, does not work for a network client server based game!
My mistakes were that I used variable time step with a lot of relatively simple maths to ensure all movement was smooth and I used a single state for working out what the character was doing. I have now learnt that I need to keep a history of the movement and states of the entities and use the state at a point in time to best approximate where all the characters are in relation to each other and what they were doing at that same point in the past.
I have nearly finished making those changes so at least the single player game works with a history of states. In the process I changed the way the movement physics was calculated. Probably not essential but I came across better ways of doing things while I was looking in to networked physics.
I ended up using more quaternions than I had previously. I still convert to matrices in several places to get some results but where possible I have tried to leave the quaternions as quaternions and use quaternion maths to get the results. Just in case it was not obvious, I am not very familiar with quaternion maths. I think I now get it but basically I look up formulae on the Internet and convert them to C# code to get the results I need.
The XNA Matrix structure has methods to get the Forward, Right and Up axes vectors from the matrix. The Quaternion structure does not! With a bit of research I found some C++ code that nearly got the axes directly from a quaternion and with a minor change and some testing I ended up with:
I am sure any professional developers will understand the importance of testing. I may not be a professional but from experience I know I cannot trust my own typing or other people's sample code or maths. To ensure the results are as intended I have validated the code above using versions of the following method, one for each axis. I am not sure if this is 'Unit Testing' but it is my interpretation.
There is significantly more code to check the results so the above just shows validating the forward vector but it should be obvious where to change that to do the Up and Right axes vectors.
I have many bits of maths and other methods that I need to ensure produce the results I expect, so I have similar debug code that I can run as stand alone methods to test the result of sections of code.
I hope the above is useful to some of you.
I have a little bit more to do to get the AI to use the newly added history of states and then I can get on with creating the server side code.
I have been working on adding network game play. It did not take me long to realise that the way I originally did the physics in the game, that works for single player and split screen, does not work for a network client server based game!
My mistakes were that I used variable time step with a lot of relatively simple maths to ensure all movement was smooth and I used a single state for working out what the character was doing. I have now learnt that I need to keep a history of the movement and states of the entities and use the state at a point in time to best approximate where all the characters are in relation to each other and what they were doing at that same point in the past.
I have nearly finished making those changes so at least the single player game works with a history of states. In the process I changed the way the movement physics was calculated. Probably not essential but I came across better ways of doing things while I was looking in to networked physics.
I ended up using more quaternions than I had previously. I still convert to matrices in several places to get some results but where possible I have tried to leave the quaternions as quaternions and use quaternion maths to get the results. Just in case it was not obvious, I am not very familiar with quaternion maths. I think I now get it but basically I look up formulae on the Internet and convert them to C# code to get the results I need.
The XNA Matrix structure has methods to get the Forward, Right and Up axes vectors from the matrix. The Quaternion structure does not! With a bit of research I found some C++ code that nearly got the axes directly from a quaternion and with a minor change and some testing I ended up with:
///
/// Returns the forward vector from a quaternion orientation.
///
public static Vector3 Forward(Quaternion q)
{
return new Vector3(
-2 * (q.X * q.Z + q.W * q.Y),
-2 * (q.Y * q.Z - q.W * q.X),
-1 + 2 * (q.X * q.X + q.Y * q.Y));
}
///
/// Returns the up vector from a quaternion orientation.
///
public static Vector3 Up(Quaternion q)
{
return new Vector3(
2 * (q.X * q.Y - q.W * q.Z),
1 - 2 * (q.X * q.X + q.Z * q.Z),
2 * (q.Y * q.Z + q.W * q.X));
}
///
/// Returns the right vector from a quaternion orientation.
///
public static Vector3 Right(Quaternion q)
{
return new Vector3(
1 - 2 * (q.Y * q.Y + q.Z * q.Z),
2 * (q.X * q.Y + q.W * q.Z),
2 * (q.X * q.Z - q.W * q.Y));
}
I am sure any professional developers will understand the importance of testing. I may not be a professional but from experience I know I cannot trust my own typing or other people's sample code or maths. To ensure the results are as intended I have validated the code above using versions of the following method, one for each axis. I am not sure if this is 'Unit Testing' but it is my interpretation.
///
/// Check that the result of the quaternion elements is facing where expected.
/// The class containing the methods is called MoreMaths
///
public static void ValidateQuarternionForward()
{
const float acceptable = 0.0009f;
System.Diagnostics.Debug.WriteLine(
"\n== Start Test ===============================================");
System.Diagnostics.Debug.WriteLine(
"== MoreMaths.ValidateQuaternionForward() =====================");
// List of values to test
Vector3[] positions = new Vector3[]
{
new Vector3(10, 20, 15),
new Vector3(15, -5, 12),
new Vector3(10, 20, -12),
new Vector3(-10, 20, 15),
new Vector3(2, 1, 0),
};
Vector3[] facing = new Vector3[]
{
new Vector3(10, 9, 20),
new Vector3(25, -5, 12),
new Vector3(10, 17, -19),
new Vector3(-12, 20, 15),
new Vector3(2, 1, 10),
};
int countTotal = 0;
int countFails = 0;
foreach (Vector3 location in positions)
{
foreach (Vector3 target in facing)
{
countTotal++;
Matrix orient =
Matrix.CreateLookAt(location, target, Vector3.Up);
Quaternion face =
Quaternion.CreateFromRotationMatrix(orient);
face.Normalize();
orient = Matrix.CreateFromQuaternion(face);
Vector3 item = MoreMaths.Forward(face);
Vector3 net = Vector3.Subtract(orient.Forward, item);
string result = "Pass | ";
float length = net.Length();
if (length > acceptable ||
float.IsNaN(length))
{
result = "FAIL | ";
countFails++;
}
System.Diagnostics.Debug.WriteLine(
result + "Forward" +
" Result M: " + orient.Forward.ToString() +
" Result Q: " + item.ToString() +
" Difference M-Q: " + net.ToString()
);
}
}
System.Diagnostics.Debug.WriteLine(
"Total Count: " + countTotal +
" | Failed Count: " +
countFails.ToString());
if (countFails < 1)
{
System.Diagnostics.Debug.WriteLine("PASS");
}
else
{
System.Diagnostics.Debug.WriteLine("FAIL");
}
System.Diagnostics.Debug.WriteLine(
"== End ======================================================\n");
}
There is significantly more code to check the results so the above just shows validating the forward vector but it should be obvious where to change that to do the Up and Right axes vectors.
Matrix orient =
Matrix.CreateLookAt(location, Vector3.Forward, target);
Quaternion face =
Quaternion.CreateFromRotationMatrix(orient);
face.Normalize();
orient = Matrix.CreateFromQuaternion(face);
Vector3 item = MoreMaths.Up(face);
I have many bits of maths and other methods that I need to ensure produce the results I expect, so I have similar debug code that I can run as stand alone methods to test the result of sections of code.
I hope the above is useful to some of you.
I have a little bit more to do to get the AI to use the newly added history of states and then I can get on with creating the server side code.
Labels:
C#,
Code Sample,
Maths,
Network,
Physics,
Unit Testing,
XNA
Monday, 15 April 2013
Wooshy Transitions
'Wooshy' is how my wife described the latest menu transitions that I've added to the game.
For those not familiar with the use of the term in games, a transition is the way one screen changes to another. A sudden jump from one page to another looks wrong or unfinished. Fading between screens or some other effect makes the change look better and more polished. Transitions are used in film and video production, DVD menus and computer games to name just a few.
It still surprises me how much of the game is connected together in unexpected ways. I started working on the networking code but have spent the last few weeks doing screen transitions. How does that happen?
It happened because I needed a background for a screen to display the list of available servers to select from.
I created a sci-fi looking frame with a blank background which I liked so much I decided I could also replace some of the placeholder artwork I had been using elsewhere...
While I was creating graphics I might as well do something about some of the other placeholder art on the menus...
With the new art assets the menu transitions looked a little inconsistent...
So on and so forth until I had changed nearly all the backgrounds to the menus and designed a set of matching slide on and off (wooshy) transitions that worked for all the menus.
It's never quite as easy as it sounds. Several of my menu screens have moving 3D models on them and getting them to nicely 'woosh' off and on was going to be somewhat troublesome so I opted for a different but matching transition for those screens.
On those difficult screens a panel slides over the entire screen and the menu changes at the point the panel obscures the whole screen and then it continues to slide off revealing the new screen.
Hopefully when you get to see the thing in action you'll like the effect.
For those not familiar with the use of the term in games, a transition is the way one screen changes to another. A sudden jump from one page to another looks wrong or unfinished. Fading between screens or some other effect makes the change look better and more polished. Transitions are used in film and video production, DVD menus and computer games to name just a few.
It still surprises me how much of the game is connected together in unexpected ways. I started working on the networking code but have spent the last few weeks doing screen transitions. How does that happen?
It happened because I needed a background for a screen to display the list of available servers to select from.
I created a sci-fi looking frame with a blank background which I liked so much I decided I could also replace some of the placeholder artwork I had been using elsewhere...
While I was creating graphics I might as well do something about some of the other placeholder art on the menus...
With the new art assets the menu transitions looked a little inconsistent...
So on and so forth until I had changed nearly all the backgrounds to the menus and designed a set of matching slide on and off (wooshy) transitions that worked for all the menus.
It's never quite as easy as it sounds. Several of my menu screens have moving 3D models on them and getting them to nicely 'woosh' off and on was going to be somewhat troublesome so I opted for a different but matching transition for those screens.
On those difficult screens a panel slides over the entire screen and the menu changes at the point the panel obscures the whole screen and then it continues to slide off revealing the new screen.
Hopefully when you get to see the thing in action you'll like the effect.
Thursday, 7 March 2013
View Occlusion
Since the play testing a few weeks ago I have been busy but I have not got a great deal to show for it yet.
My main task is trying to improve the draw performance so I can add a bit more detail to the levels and counter some of the additions I made based on the suggestions from the play testing.
I already do the typical view frustum culling and restrict the far plane range so I am only left with the more complex things to try. Pretty much that is some form of pre-calculation of what is in view.
From the reading I have done Binary Space Partitioning (BSP) is not appropriate to the type of exterior vistas I would like to have in the game. Therefore I have been concentrating on Occlusion Volumes (View or Visibility Cells). My understanding being that these are areas of the map that if you are inside that area the models and meshes in view have been pre-calculated and therefore exclude meshes that are hidden by other meshes. Both Unity and the Unreal Engine have variations of this that can be enabled depending on if it is appropriate for the map.
My map already uses a grid for storing, triangles and other information so adding additional heights to set the boundaries of the Occlusion Volume is trivial. The tricky task has been calculating the mesh occlusion information.
I tried to calculate the view using the GPU. I wrote a shader that stored an index for each model and returned that in the render target. By drawing the view in sufficient directions from various points in each Occlusion Volume I would get a fairly accurate chance of knowing what was not in view and could therefore be ignored and not drawn in game.
I wrote all the code to do the calculations using the GPU but now for the problem. Based on my initial trials it would take 72 hours to calculate the information for the entire usable area of the map! I decided that was too long to run every time I made a tiny change to any game level!
I was also not confident that the result from the render target was completely accurate because my tests showed that if I put a float value in, the float I got out was close but not identical when rendered!
For my next trick I am attempting to use the grid and simply ray cast between cells. I have not finished coding this but in the process I have used the Bresenham Line Algorithm.
The algorithm was originally intended to plot a line on early printers in the '60's. I have come across it before but as it does not include every possible cell that a line could pass through it was no good for my impact calculations. However for view occlusion I need something that is fast and where a few false positives for grid squares in view will not be harmful to the overall result.
It's only a tiny bit of code but I decided to put my C# XNA versions on CodePlex. The important bit is that one of the variations I've included gives the result in order from the start to the finish point. If it is of interest you can view and download it from there.
My main task is trying to improve the draw performance so I can add a bit more detail to the levels and counter some of the additions I made based on the suggestions from the play testing.
I already do the typical view frustum culling and restrict the far plane range so I am only left with the more complex things to try. Pretty much that is some form of pre-calculation of what is in view.
From the reading I have done Binary Space Partitioning (BSP) is not appropriate to the type of exterior vistas I would like to have in the game. Therefore I have been concentrating on Occlusion Volumes (View or Visibility Cells). My understanding being that these are areas of the map that if you are inside that area the models and meshes in view have been pre-calculated and therefore exclude meshes that are hidden by other meshes. Both Unity and the Unreal Engine have variations of this that can be enabled depending on if it is appropriate for the map.
My map already uses a grid for storing, triangles and other information so adding additional heights to set the boundaries of the Occlusion Volume is trivial. The tricky task has been calculating the mesh occlusion information.
I tried to calculate the view using the GPU. I wrote a shader that stored an index for each model and returned that in the render target. By drawing the view in sufficient directions from various points in each Occlusion Volume I would get a fairly accurate chance of knowing what was not in view and could therefore be ignored and not drawn in game.
I wrote all the code to do the calculations using the GPU but now for the problem. Based on my initial trials it would take 72 hours to calculate the information for the entire usable area of the map! I decided that was too long to run every time I made a tiny change to any game level!
I was also not confident that the result from the render target was completely accurate because my tests showed that if I put a float value in, the float I got out was close but not identical when rendered!
For my next trick I am attempting to use the grid and simply ray cast between cells. I have not finished coding this but in the process I have used the Bresenham Line Algorithm.
The algorithm was originally intended to plot a line on early printers in the '60's. I have come across it before but as it does not include every possible cell that a line could pass through it was no good for my impact calculations. However for view occlusion I need something that is fast and where a few false positives for grid squares in view will not be harmful to the overall result.
It's only a tiny bit of code but I decided to put my C# XNA versions on CodePlex. The important bit is that one of the variations I've included gives the result in order from the start to the finish point. If it is of interest you can view and download it from there.
Labels:
Bresenham,
C#,
Code Sample,
Graphics,
View Occlusion,
XNA
Monday, 11 February 2013
Play Testing Is Very Useful
I put the game in to Xbox Live play testing with little expectations especially as it is such an early version.
What I got back was incredible. I knew the way others look at the game would be different to how I see it, with the 'rose tinted glasses' of the developer on but I was not expecting such useful feedback.
http://xboxforums.create.msdn.com/forums/t/110018.aspx
After the initial essential bug fix, many of the comments are about balancing the combat. I got feedback on AI behaviour, the relative strengths of the weapons and even some suggestions for the bullet effect via Twitter. I also got some useful comments, with screen shots, on projectile behaviour which I knew about but did not expect others to notice. I know now that if I know about it chances are others will also find it distracting.
I have already fixed or changed many of the things based on the suggestions and just have the more time consuming ones to go. Some changes have hit performance so I am in the process of moving things about to get a few more milliseconds out of the CPU... I hope!
Thanks again to all.
What I got back was incredible. I knew the way others look at the game would be different to how I see it, with the 'rose tinted glasses' of the developer on but I was not expecting such useful feedback.
http://xboxforums.create.msdn.com/forums/t/110018.aspx
After the initial essential bug fix, many of the comments are about balancing the combat. I got feedback on AI behaviour, the relative strengths of the weapons and even some suggestions for the bullet effect via Twitter. I also got some useful comments, with screen shots, on projectile behaviour which I knew about but did not expect others to notice. I know now that if I know about it chances are others will also find it distracting.
I have already fixed or changed many of the things based on the suggestions and just have the more time consuming ones to go. Some changes have hit performance so I am in the process of moving things about to get a few more milliseconds out of the CPU... I hope!
Thanks again to all.
Sunday, 3 February 2013
Alpha Playtest Version
UPDATE: This playtest has now expired. The forum remains for anyone interested and there will be future versions when I have made sufficient changes for more testing to be worthwhile.
I'd like to thank everyone who tested the game. I received some excellent feedback and and am working through it all to make changes.
==
I have just uploaded the first version that other developers can play.
For those who may be interested please be aware that this is only available to Xbox Live Independent Game (XBLIG) developers who have a premium subscription with Microsoft. That's the way Microsoft set up the publishing mechanism for the Xbox. That's a long way of saying only other Xbox developers can get this download:
http://xboxforums.create.msdn.com/forums/t/110018.aspx
I am a bit nervous and excited because this will be the first time that anyone other than me has played it. I've demo'd older versions to a few friends before but these only had partial test levels. No one else has played a version where a level can be played through from start to finish.
The game is still a long way from completion. Lots of the graphics need improving both in game and on the menus. I need more player characters, more types of aliens, better animations and most importantly I need to write the network code so it can be played on line.
That's what's not there but what is there...
- Character selection.
- Single player
- Two player split screen
- Playable level with an end objective (a bit simplistic at the moment I admit)
- Selection of weapons including different types of grenades
- AI controlled Bots. Despite their limited skill set they still make difficult opponents
- Ammo counters, weapon sights, grenades, the usual stuff...
- Weapon and ammo pickups
- Lots of enemies to shoot at
- End of game scores
and more...
If you are an XBLIG developer I hope you try it out and enjoy it.
http://xboxforums.create.msdn.com/forums/t/110018.aspx
==
For anyone else at this stage it took about 3 hours between uploading the file and it being available to download.
I'd like to thank everyone who tested the game. I received some excellent feedback and and am working through it all to make changes.
==
I have just uploaded the first version that other developers can play.
For those who may be interested please be aware that this is only available to Xbox Live Independent Game (XBLIG) developers who have a premium subscription with Microsoft. That's the way Microsoft set up the publishing mechanism for the Xbox. That's a long way of saying only other Xbox developers can get this download:
http://xboxforums.create.msdn.com/forums/t/110018.aspx
I am a bit nervous and excited because this will be the first time that anyone other than me has played it. I've demo'd older versions to a few friends before but these only had partial test levels. No one else has played a version where a level can be played through from start to finish.
The game is still a long way from completion. Lots of the graphics need improving both in game and on the menus. I need more player characters, more types of aliens, better animations and most importantly I need to write the network code so it can be played on line.
That's what's not there but what is there...
- Character selection.
- Single player
- Two player split screen
- Playable level with an end objective (a bit simplistic at the moment I admit)
- Selection of weapons including different types of grenades
- AI controlled Bots. Despite their limited skill set they still make difficult opponents
- Ammo counters, weapon sights, grenades, the usual stuff...
- Weapon and ammo pickups
- Lots of enemies to shoot at
- End of game scores
and more...
If you are an XBLIG developer I hope you try it out and enjoy it.
http://xboxforums.create.msdn.com/forums/t/110018.aspx
==
For anyone else at this stage it took about 3 hours between uploading the file and it being available to download.
Thursday, 24 January 2013
Wednesday, 16 January 2013
Assumptions...
You know all the
sayings about assumptions. They all boil down to don't take things for
granted but how do you know when you are making an assumption?
I have been chasing a problem with my grenade throwing code. They would disappear unexpectedly or explode at the wrong time or place.
I have lots of visualisation to confirm that the calculations are being performed and that the positions were correct and in view!
It turns out that the confusion was because I had unconsciously assumed that my update thread was always in advance of my draw thread.
Nearly everywhere else in the code the update does not matter if it runs out of sync with the draw thread but for grenades that have to bounce, the difference was noticeable. The collision is calculated in one thread but the grenade is drawn in another thread in real time.
Overall the update thread does less work and so has plenty of spare performance therefore it seamed logical in the back of my mind that it would process the collision faster than needed. What I had not allowed for is that it might have started after the draw thread.
I had varying results that I could not explain. Sometimes working and sometimes not which I now know is because it is multi-threaded. The launching of the grenade could sometimes be picked up instantly by the draw thread because that is where it was in its cycle but the update thread could be a few milliseconds or even a frame behind that draw.
Problem solved and another lesson learnt :-)
I have been chasing a problem with my grenade throwing code. They would disappear unexpectedly or explode at the wrong time or place.
I have lots of visualisation to confirm that the calculations are being performed and that the positions were correct and in view!
It turns out that the confusion was because I had unconsciously assumed that my update thread was always in advance of my draw thread.
Nearly everywhere else in the code the update does not matter if it runs out of sync with the draw thread but for grenades that have to bounce, the difference was noticeable. The collision is calculated in one thread but the grenade is drawn in another thread in real time.
Overall the update thread does less work and so has plenty of spare performance therefore it seamed logical in the back of my mind that it would process the collision faster than needed. What I had not allowed for is that it might have started after the draw thread.
I had varying results that I could not explain. Sometimes working and sometimes not which I now know is because it is multi-threaded. The launching of the grenade could sometimes be picked up instantly by the draw thread because that is where it was in its cycle but the update thread could be a few milliseconds or even a frame behind that draw.
Problem solved and another lesson learnt :-)
Monday, 7 January 2013
Video Update
I've spent the last day of my extended Christmas break creating a video to show off the progress I've made.
There are new weapons, new effects, more aliens and it is all comfortably playable on the Xbox.
It's taken me a couple of hours including waiting time to capture the video and edit it using the following tools:
Microsoft Expression Encoder 4 to capture 10 minutes of video.
Windows Live Movie Maker to edit the video down to about 3 minutes, add the transitions and the background music.
Thanks to Purple Planet for the music included in the video.
There are new weapons, new effects, more aliens and it is all comfortably playable on the Xbox.
It's taken me a couple of hours including waiting time to capture the video and edit it using the following tools:
Microsoft Expression Encoder 4 to capture 10 minutes of video.
Windows Live Movie Maker to edit the video down to about 3 minutes, add the transitions and the background music.
Thanks to Purple Planet for the music included in the video.
Friday, 4 January 2013
Shotgun Pellets
Just added the code so that some ammunition types shoot more than one projectile with each shot.
The code worked first time and is easy to change the behaviour for different weapons.
Another small step closer.
The code worked first time and is easy to change the behaviour for different weapons.
Another small step closer.
Thursday, 3 January 2013
Weapon Line Up
I'm working through everything needed for the finished weapons in the game.
I have nearly all the models and cross hairs completed and most of the sounds and visual effects.
There is a good selection each with slightly different characteristics.
They have a futuristic style but retain recognisable features and handling.
Like the alien weapons these are from models purchased from Garage Games. I've changed most of the names.
I have nearly all the models and cross hairs completed and most of the sounds and visual effects.
There is a good selection each with slightly different characteristics.
Like the alien weapons these are from models purchased from Garage Games. I've changed most of the names.
Subscribe to:
Posts (Atom)