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.