Shooting (Single Player)

Checked with version: 5.3

-

Difficulty: Intermediate

A common feature in multiplayer games is to have the player be able to shoot bullets and have these bullets work across all Clients in the game.

This section will add shooting, but in a single-player, non-networked manner. How to make shooting “network aware” will be covered in the next section of this lesson.

  • Create a new Sphere primitive GameObject.
  • Rename the Sphere GameObject “Bullet”.
  • With the Bullet GameObject selected,
  • ... change the scale of the GameObject’s Transform to (0.2, 0.2, 0.2).
  • ... find and add the component: Physics > Rigidbody.
  • On the Rigidbody component, set the Use Gravity checkbox to false.
  • Drag the Bullet GameObject into the Project Window to make a prefab asset.
  • Delete the Bullet GameObject from the scene.
  • Save the scene.

The PlayerController script will now need to be updated for shooting. The script will need to have a reference to the Bullet prefab and have code to do the actual shooting logic.

  • Open the PlayerController script for editing.
  • Add a public field for the Bullet prefab.
public GameObject bulletPrefab;

Add a public field for the location of the Bullet Spawn.

public Transform bulletSpawn;

Add Input handling in the Update function.

if (Input.GetKeyDown(KeyCode.Space))
{
    Fire();
}

Add a “Fire” function to fire a Bullet.

void Fire()
{
    // Create the Bullet from the Bullet Prefab
    var bullet = (GameObject)Instantiate (
        bulletPrefab,
        bulletSpawn.position,
        bulletSpawn.rotation);

    // Add velocity to the bullet
    bullet.GetComponent<Rigidbody>().velocity = bullet.transform.forward * 6;

    // Destroy the bullet after 2 seconds
    Destroy(bullet, 2.0f);
}

The final script will look like this:

PlayerController

Code snippet

using UnityEngine;
using UnityEngine.Networking;

public class PlayerController : NetworkBehaviour
{
    public GameObject bulletPrefab;
    public Transform bulletSpawn;

    void Update()
    {
        if (!isLocalPlayer)
        {
            return;
        }

        var x = Input.GetAxis("Horizontal") * Time.deltaTime * 150.0f;
        var z = Input.GetAxis("Vertical") * Time.deltaTime * 3.0f;

        transform.Rotate(0, x, 0);
        transform.Translate(0, 0, z);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            Fire();
        }
    }


    void Fire()
    {
        // Create the Bullet from the Bullet Prefab
        var bullet = (GameObject)Instantiate(
            bulletPrefab,
            bulletSpawn.position,
            bulletSpawn.rotation);

        // Add velocity to the bullet
        bullet.GetComponent().velocity = bullet.transform.forward * 6;

        // Destroy the bullet after 2 seconds
        Destroy(bullet, 2.0f);        
    }

    public override void OnStartLocalPlayer ()
    {
        GetComponent().material.color = Color.blue;
    }
}
  • Save the script.
  • Return to Unity.

In the next step, we need to set up the Player GameObject to reflect changes in the PlayerController script.

  • Drag the Player prefab into the Hierarchy View to be able to edit the Player GameObject.
  • With the Player GameObject selected,
  • ... create a new Cylinder primitive as a child.
  • Rename the Cylinder GameObject to “Gun”.
  • With the Gun GameObject selected,
  • ... remove the Capsule Collider Component.
  • ... set the Transform's Position to: (0.5, 0.0, 0.5).
  • ... set the Transform's Rotation to: (90.0, 0.0, 0.0).
  • ... set the Transform's Scale to (0.25, 0.5, 0.25).
  • ... set the Material to the Black Material.

The Player GameObject should look like this:

description

  • With the Player GameObject selected,
  • ... create a new empty GameObject as a child.
  • Rename this empty GameObject “Bullet Spawn”.
  • Set the Bullet Spawn’s Position to (0.5, 0.0, 1.0).

This should place the Bullet Spawn’s Transform Position to the end of the Gun GameObject.

description

  • With the Player GameObject selected,
  • ... apply the changes to the Prefab asset.
  • Delete the Player GameObject from the scene.
  • Save the scene.

The next step is to set up the PlayerController component on the Player prefab.

  • Select the Player prefab.
  • With the Player prefab selected:
  • ... add the Bullet prefab to the Bullet Prefab field in the PlayerController component.
  • ... add the Bullet Spawn child to the BulletSpawn field in the PlayerMovement component.
  • Save the project.

Test the current state of the project.

  • Build and Run this scene as a standalone application.
  • Click the Host button from the in-game UI to start this game as a Host.
  • Move the Player GameObject.
  • Return to Unity.
  • Enter Play Mode.
  • Click the LAN Client button from the in-game UI to connect to the Host as a Client.

Pressing the spacebar should create a new Bullet GameObject at the Bullet Spawn position for the local Player GameObject. The bullet is not created on other Clients, as the bullets and shooting code are not network aware.

  • Close the standalone player.
  • Return to Unity.
  • Exit Play Mode.