Tuesday, 18 March 2014

Shooting and few gadgets

4. Shooting bullets, Laser Scope and Aiming Icon

To shoot bullets I created bullet prefab which contains bullet script and bullet object. Bullet script encapsulates bullet speed. In function Update() single line of code represents movement transform.Translate"Vector2.up * bulletSpeed * Time.deltaTime" and after short amount of time bullet gets destroyed. I would like to add that it's not efficient to put any collision detection inside the bullet class (we might have hundreds of bullets and if each one will check for collisions it will consume lot of computer resources). In game object each bullet have Sprite Renderer and Bullet script attached. Each time when player shoots "Input.GetMouseButtonDown(0)" Player script will instantiate bullet prefab with player position and rotation creating clone of bullet "tempBullet = (Instantiate(bullet, transform.position, transform.rotation)) as GameObject".
To detect collision of bullet there are two ways. First which I used is suitable for fast moving objects (depends how fast do you want your bullets to move). For fast moving objects (speed > 50) function "OnCollisionEnter2D()" is unreliable so my enemies are using "RaycastHit2D". It is function to draw invisible line between two objects and return true if something is on its way, I also used layer mask so line will collide only with objects placed on that layer e.g. walls or other enemies. My collision detection is if mouse over object and left mouse button pressed and ammo greater than zero and no collisions on the way - enemy was hit (you can also add range condition).
Second way to detect collisions is to use "OnCollisionEnter2D()" function for slow moving objects. In that case our bullet object needs extra elements like Rigidbody 2D() and Circle Collider 2D so we can add some physics to our object. This function also returns many useful information about collision like object tag we collide with or position of collision. I'm going to use it for ammo or if enemy will touch you.
In my game player have useful gadget Laser Scope attached to his guns. To do that I used Line Renderer. Line Renderer has many options like color, number of points line consist of, and shader. Starting point is player rotation and position transformed by some offset (so laser coming out of gun instead of center of player). End point is a returned vector of Raycasting against layer mask. Layer mask consists of three layers (walls, furniture and enemies) or together in binary values and convert to decimal e.g. layers 12, 13 and 14 or together as binary numbers will give us decimal 14336. To get nice laser effect I used material "Default-Particle" for both points. To set end point I used "lineRenderer.SetPosition(1, endPoint)" syntax where 1 is second point (0 is start point) and endPoint is returned vector of Raycasting collision.    
To replace standard mouse cursor first I disabled it with "Screen.showCursor = false" and in FixedUpdate() function I transformed it position to mouse position with "Camera.main.ScreenToWorldPoint(Input.mousePosition)". In Unity we need new cursor object with desired sprite and cursor script attached.

Laser and cursor:
  

Monday, 3 March 2014

Animations and first coding

3. Player animations and movement

To apply simple animations e.g. for character in move I used tile sheets which contain player sprites captured frame by frame. At this stage I used three types of animations: Idle, Walk and Shoot but I'm going to include one more for Player hit. Each animation needs a condition which will trigger it. In Unity each PNG file containing tile sheet for animation needs to be prepared. I set: Sprite Mode - Multiple, Pixels To Units - 32 then in Sprite Editor I used grid to divide picture into frames, each frame needs to have the same size in pixels. Next I created new object for player called Animator, each animator needs Controller. In Animation Window for player I added: Idle with Sample Rate - 3, Walk with Sample Rate - 12 and Shoot with Sample Rate - 20. Sample Rates are set how fast animation will be displayed. In Animator Window I set transition between animations and conditions as follow: if speed of player is greater than 0.01 switch to Walk animation, if speed of player is less than 0.01 go back to default Idle animation. Reason why I used values 0.01 is if we use e.g. 1 switching animations will be delayed as player has to reach speed of 1 first. For shooting I created new variable called 'Trigger' and I set it to true in Update function in PlayerControl scrip using Input.GetMouseButtonDown(0). Animation will end after 1 second - Exit Time variable.
For movement I created new C# script called PlayerControl. I included two variables: maxSpeed for player speed set it to 3.0f and Animator type variable called anim to be able to access animations. In update function I included another variables for speedX and speedY assigning them values: "Input.GetAxis("Horizontal")" and "Input.GetAxis("Vertical")". I also created new object called rigidbody2D for my player as i I will need it to change velocity of it "Vector2(moveX * maxSpeed, moveY * maxSpeed)", detect any collisions or to apply any physics.

Example of "Animator" tab for my player:


Picture above clearly represents bunch of different animations. We have two different sets of animations, animations for player holding pistol and for player holding shoot gun.

Wednesday, 26 February 2014

Tiles, tiles, tiles

2. Graphics processing and collisions

Game graphic is mostly based on 32x32 pixels tiles. By default size of first two levels are 32x24 blocks (1024x768) with Pixels to Units set to 32. The last two levels are 64x48 blocks (2048x1536). To make the game "lighter" all huge static surfaces like walls and floors was exported by Tiled Map Editor to PNG files. Tiled Map Editor is a very useful free software to build whole levels out of tiles. Program has few really useful options like layers and export to PNG which I needed the most. Created PNG file are used in 2D Unity Project as sprites, instead of surfaces build out of hundreds of small objects. Each object is traced by our CPU and if game will get bigger we can easily overload processor. To prepare the tiles I mostly used Photoshop and another really good free feature called Sprite Splitter but Paint.NET or Gimp are sufficient enough.
For collisions I used Box Colliders 2D drawing them around walls and other objects that I want to collide with.
Really important is to center camera and all sprites, put them on numbered layers and set values to them in order from bottom up. That allowed me to manipulate what will be drawn on top of what in easy way.
I strongly recommend using tools like Tiled Map Editor. I saved a lot of time producing whole levels graphics using this small program.

Example of PNG graphic representing walls of of my ground level building; assembled out of 32x32 small blocks using "Tiled" program:

Another PNG graphic for floors:

When you join then together:

The only thing you have to keep in mind is layers (what is displayed on top of what) and to add "Polygon collider 2D" for walls.

Sunday, 16 February 2014

Basic ideas

1. Ideas and some technical details

For my assignment I would like to do 2D shooting game using Unity. I believe that most challenging part are the good sprites, so it is worth to spend some time and prepare really good graphics. Unity it self is a very powerful tool combining elements of Photoshop and Visual Studio. Currently I am going over number of Unity tutorials and preparing my player sprites which are going to be animated.

Game functionality:
- 2D game
- controls: keyboard + mouse (recommended)
- single player
- two types of weapons (pistol and shotgun) - can be extended
- laser scope attached to guns
- three different types of enemies (can be extended) - randomly spawned
- four levels (ascending difficulty) - can be extended
- ammo
- player interface (image of player, health, ammo for pistol, ammo for shotgun, score)
- lift (move from ground to basement level)