“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

preface

It’s like the title says liver for several nights. Originally, I wanted to write the tutorial directly from my previous project. Write write found a lot of do not good place, and rearrange modification. It was a complete reworking of the project. This article starts with a new project and takes you step by step to complete the pixelated bird game that can be made on a zero basis. Restore the classic gameplay, try it together ~

As usual, take a look at the final implementation:

How’s that? Are you interested? Want to feel the sense of accomplishment you feel when you’re done? Let’s start the process


One, create a directory

1.1 After creating a project, create a directory as shown in the figure below:The directories to be created correspond to the following resources:

  • -Vanessa: Audios, Materials, Prefabs, Scenees, Scripts, Texture

1.2 Import sound and picture resources prepared in advance and put them in the corresponding directory: [Provided at the end of the article]1.3 After import, change the image resource format used by UI to Sprite(2D and UI), hold down Ctrl and select GameOver, Score and Start to modify the number of images, as shown below:Then go to the “Apply” button below:After the modification, the effect is as follows:


Two, make the material

2.1 Making material balls (background, pipes and pixel birds)

Right-click on the Materials file and select Create –> Material to Create a new Material ball:Then change its name to bg and change its Shader to Unlit/Transparent:Finally, assign it as the background image –> Click the Select button –> Double-click the BG image in the popover:Then select the BG shader ball and use the shortcut Ctrl+D to copy three shader balls:Change the name and repeat the steps above to back, brid, and tipe (don’t forget to respecify the texture of the material ball). The result is as follows:


Third, scene construction

3.1 Modifying main Camera Properties:

  • Change its coordinates to (0,0,-2), rotate to (0,0,0), scale to (1,1,1)
  • Alter it to be Projection –> Orthographic

Click the resolution selection panel in the Game view, and click “+” at the bottom to create a new resolution. The property values are set as follows:

Then click on the Resolution Selection panel again and select the properties you just created:


Create a map

4.1 Creating a Background Right-click in Hierarchy space and select 3D Object. Then select Quad created as background.

If it doesn’t show up in the Game view, change its Position to (0,0,0), change its Scale to (10,12,1), and finally assign the bg material ball we made to Quad. The result is as follows:

4.2 Creating a Bottom

Select the background “Quad” created above, right-click on 3D Object -> Select Quad to create one, and assign the material ball to the back to get the following result:

Rename the background “Quad” to BG and rename its child objects to Back. Then change BG’s Position to (-4,-1,0) so that it appears at the leftmost end. The effect is as follows:4.4 Removing colliders

In the Inspector, right-click on the “Mesh Collider” Component and select “Remove Component” to Remove the Collider Component:

Similarly select Quad and remove the Mesh Collider component.


Five, make pipes

5.1 Copy the background to cover the screen

Select Hierarchy –> BG and use the shortcut key Ctrl+D to copy it, and adjust its coordinate to (6,-1,0). The effect is as follows:

5.2 Make a pipe

Under the newly copied BG (1) create an empty object named Pipe1 to be the parent of the top and bottom tubes, set the coordinates, rotate to (0,0,0), scale to (1,1,1):

Then select Pipe1 and create the Quad named Up and the material ball named Tipe. Set its coordinates (0,0.7,0), rotation (0,0,0), and scale (0.07,1,1);

Then select Up, Ctrl+D and make a copy of it. Change its coordinates to (0,-0.5,0) and leave all other properties unchanged.

5.3 Adjusting positions

Now you can see that the tube below is exposed to the outside of the map. Adjust the z-axis of the lower background Back to -1 to get the following effect:


Create a protagonist

6.1 Creating a Bird

Repeat the steps above to create a Quad named Brid, set Position to (0,0,-1), and assign the material ball to Brid. The effect is as follows:

6.2 Setting the Brid Tag to Player:

6.3 Modifying material Ball properties

Change Tiling(0.3333,1), Offset(0.3333,1).

6.4 Let the birds fly

Create the script BridHandler and mount it to the Brid. Edit the content as follows:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BridHandler : MonoBehaviour {

    / / the singleton
    public static BridHandler intance;
    private void Awake()
    {
        intance = this; 
    }
    
    private Renderer _renderer;      / / material
    
    private float timer;        // Timer,
    private int frameNum =10;   // Display several frames per second
    private int frameCount;     // Frame counter

	void Start () {
        _renderer = this.GetComponent<Renderer>();
    }
	
	// Update is called once per frame
	void Update () {
        timer += Time.deltaTime;  // Add a frame of time
        if (timer >= 1.0 f / frameNum)  // The time taken for more than 1 frame
        {
            frameCount++;   // The number of frames increased
            timer -= 1.0 f / frameNum;

            // three frames (0,1,2 show each frame)
            int frameIndex = frameCount % 3;

            // Update the offset x attribute
            _renderer.material.SetTextureOffset("_MainTex".new Vector2(0.33333 f * frameIndex, 0)); }}}Copy the code

After running, you can see the bird in the fly, the effect is as follows:


Seven, the bird moves

7.1 Add the Rigidbody component to the main Brid:

Check the XZY Constraint –> Freeze Rotation to avoid Rotation:

7.2 Adding the following script to the BridHandler script:


private Rigidbody _rigidbody;    // Rigid body components
private float x = 3;             // Bird running speed

void Start () {
    _rigidbody = this.GetComponent<Rigidbody>();
    _rigidbody.useGravity = false;
}

void Update()
{
    if (Input.GetMouseButtonDown(0)) { StartGame(); }}public void StartGame()
{
     _rigidbody.useGravity = true;
     _rigidbody.velocity = new Vector3(x, 0.0);
}

Copy the code

7.3 Then run click on the margin, you can see the bird moving:

7.4 Processing error If your project operation error (no error can be ignored)

Select the Convex property of Brid’s Mesh Collider:

Add the Sphere Collider component

Adjust the radius of the collider to 0.28, and look at the Scene to keep consistent with the outline of the bird:


Eight, game state control

8.1 Creating a GameManager Script and Mounting it to a Scenario Add the script as follows:

using UnityEngine;

public enum GAME_STATUS
{
    // Start the game
    GAME_START = 0./ / in the game
    GAME_PLAYING = 1.// Game over
    GAME_END = 2 
}

public class GameManager : MonoBehaviour {
    / / the singleton
    public static GameManager intance;
    private void Awake()
    {
        intance = this; 
    } 
    /// <summary>
    ///Current Game State
    /// </summary>
    public GAME_STATUS GameState = GAME_STATUS.GAME_START;    
    // The background to be moved
    public Transform moveBgTrans;

    void Start(){}void Update () {

        switch (GameState)
        {
            case GAME_STATUS.GAME_START: 
                // Click the screen to start the game
                if (Input.GetMouseButtonDown(0))
                {
                    GameState = GAME_STATUS.GAME_PLAYING;
                    BridHandler.intance.StartGame();
                }
                break;
            case GAME_STATUS.GAME_PLAYING:
                break;
            case GAME_STATUS.GAME_END:
            
                break;
            default: break; }}}Copy the code

8.2 Right-click on Hierarchy, create an empty GameObject, and change its name to GameManager.

8.3 Modify the Update method of bridhandler. cs script to add the logic of game state control and bird jump. The specific code is as follows:

void Update()
{
    if (GameManager.intance.GameState == GAME_STATUS.GAME_PLAYING) // Can jump
    {
        Vector3 vel = _rigidbody.velocity;
        / / jump
        if (Input.GetMouseButtonDown(0))
        {
            vel.x += 0.05 f; // Increase the speed by one point per jump
            _rigidbody.velocity = new Vector3(vel.x, 5, vel.z);
            Debug.Log(vel);
        }
        
        // Whether to play the animation is controlled by the game state
        timer += Time.deltaTime; // Add a frame of time
        if (timer >= 1.0 f / frameNum) // The time taken for more than 1 frame
        {
            frameCount++; // The number of frames increased
            timer -= 1.0 f / frameNum;
            // three frames (0,1,2 show each frame)
            int frameIndex = frameCount % 3;
            // Update the offset x attribute
            _renderer.material.SetTextureOffset("_MainTex".new Vector2(0.33333 f * frameIndex, 0)); }}}Copy the code

8.4 Change the original position of the bird to the upper left corner by a point (-2,1.8,-1):8.5 Run again at this time, click the screen and the bird can jump:


Nine, the camera follows

9.1 Create script FollowBrid and attach it to the camera:

using UnityEngine;

// The camera follows
public class FollowBrid : MonoBehaviour {

    private Transform bridTrans;

	// Use this for initialization
	void Start () {
        bridTrans = GameObject.FindGameObjectWithTag("Player").transform;
    }
	
	// Update is called once per frame
	void Update () {
        Vector3 bridPos = bridTrans.position;        
        float y = bridPos.y - 4.4 f;
        // Limit the maximum and minimum camera positions
        if (y > 1.5 f)
        {
            y = 1.5 f;
        }
        if (y < 0 )
        {
            y = 0f;        
        }
        this.transform.position = new Vector3(bridPos.x + 3.63223 f,y, - 10); }}Copy the code

9.2 Running effect is as follows:


Add collision detection

10.1 add a “Box Collider” to the bottom: select the Back and add a “Box Collider” to the bottom. After adding the Collider, set the offset and size to (0,-0.36,0) and (1,0.28,2), as shown below:

10.2 for tube colliders: first select Up to remove your “Mesh Collider” component, then add “Box Collider” and change the size to (1,1,2); Do the same for Up (1), so that both the upper and lower tubes have colliders. The effect is as follows:

10.3 Add game contact detection, create the script PipUporDown, and mount several game objects on which the collision body is added, so that the bird touches the pole and the bottom can trigger the end of the game. The script is as follows:

public class PipUporDown : MonoBehaviour {

    private void OnCollisionEnter(Collision collision)
    {
        if(collision.gameObject.tag == "Player")
        {
            // Game overGameManager.intance.GameState = GAME_STATUS.GAME_END; }}}Copy the code

10.4 Add a Box Collider to the parent tube object and set its center to (0,0.1,0), size to (0.1,0.2,2) and position between the two tubes. Check Is Trigger to Trigger the pass score:

PS: Note that the collider size is (0.1,0.2,2).

Create a PipeHandler script and mount BG(1) –> Pipe1 to random pipe height.

using UnityEngine;

public class PipeHandler : MonoBehaviour {

    private void Start()
    {
        RandomPos();
    }

    /// <summary>
    ///Generating random numbers
    /// </summary>
    public void RandomPos()
    {
        float pos_y = Random.Range(0.1 f.0.1 f);
        this.transform.localPosition = new Vector3(this.transform.localPosition.x, pos_y, this.transform.localPosition.z);
    }

    // Pass trigger score:
    private void OnTriggerExit(Collider other)
    {
        if(other.tag == "Player")
        {
            Debug.Log("todo... Points"); }}}Copy the code

10.6 make a copy of Pipe1, and adjust its position to (0.5,0,0), so that there are two pipes in one map, the spacing is more suitable for the difficulty of the game, the effect is as follows:


11. Perfect the background

1: Right-click BG (1) and create an empty object. Rename it “MoveTrrgger”, change the position to (1.3,0,-1), and add a Box Collider to it. Change the size to (0.1,1,1).

2: Create script MoveTrigger and mount it to the “MoveTrrgger” object created in 10.4. The code is as follows:

using UnityEngine;

public class MoveTrigger : MonoBehaviour
{
    public Transform currentBg;

    public PipeHandler pipe1;
    public PipeHandler pipe2;

    private void OnTriggerExit(Collider other)
    {
        // debug.log (" trigger to background move ");
        if (other.tag == "Player")
        {
            // Move the front background to the back
            // Get the first background position
            Transform firstbg = GameManager.intance.moveBgTrans;
            / / move
            currentBg.position = new Vector3(firstbg.position.x + 10, currentBg.position.y, currentBg.position.z);
            / / updateGameManager.intance.moveBgTrans = currentBg; pipe1.RandomPos(); pipe2.RandomPos(); }}}Copy the code

11.3 Assign a value to the code, and the assignment situation is as follows:

11.4 duplicate two copies of BG(1) to get BG(2) and BG(3) with positions set to (16,0,0) and (26,0,0) respectively. The effect is as follows:

11.5 toGameManagerTo assign the value of the moveBgTrans attribute

11.6 At this point, the infinite connection of the background can be realized:

So far, most of the main logic of the game has been completed, but there are still two parts to complete: UI and sound.


12. UI

Right-click on Hierarchy space, create UI –> Text, adjust its anchor point to the upper left corner, change the Text size to (300,100), and font size to 42. The effect is as follows:

12.2 End of Game Create an Image under Canvas as the end of game background board, spread it all over the screen, adjust its transparency to 100, and rename it “UIBG”:

Create an Image under “UIBG” as the score background board and assign the score to it:

Under “UIBG” create two text as the bureau Score and highest Score display named “Score” and “Best” respectively, adjust the position text as follows:

Create a Button under “UIBG” as the restart Button, hide the child object “Text”, assign the value “Image” to “start”, and adjust the position as shown below:

12.4 Logical Processing

GameManager class, the complete code is as follows:

public class GameManager : MonoBehaviour {
    / / the singleton
    public static GameManager intance;
    private void Awake()
    {
        intance = this; 
    }
 
    /// <summary>
    ///Current Game State
    /// </summary>
    public GAME_STATUS GameState = GAME_STATUS.GAME_START;

    // The background to be moved
    public Transform moveBgTrans;
    
    / / score
    public Text ScoreText;
    
    // End the game UI
    public GameObject GameOverUI;
    // End of game score
    public Text GameOverScore;
    // The game ends with the highest score
    public Text GameOverBest;
    // Restart button after game
    public Button GameOverButton;
    
    // Score of this game
    int score = 0;

    void Start()
    {
        GameOverButton.onClick.AddListener(()=>{
            SceneManager.LoadScene(0);
        });
    }

    void Update () {

        switch (GameState)
        {
            case GAME_STATUS.GAME_START: 
                GameOverUI.SetActive(false);
                // Click the screen to start the game
                if (Input.GetMouseButtonDown(0))
                {
                    GameState = GAME_STATUS.GAME_PLAYING;
                    BridHandler.intance.StartGame();
                }
                break;
            case GAME_STATUS.GAME_PLAYING:
                break;
            case GAME_STATUS.GAME_END:
                // Game over, display panel, maintain score
                GameOverUI.SetActive(true);
                GameOverScore.text = score.ToString();
                GameOverBest.text = PlayerPrefs.GetInt("Best").ToString();
                break;
            default: break; }}// Update the score
    public void UpdateScore()
    {
        // The score is increased
        score++;
        ScoreText.text = "Score." + score;
        // Maintain the highest score
        if (score > PlayerPrefs.GetInt("Best"))
        {
            PlayerPrefs.SetInt("Best", score); }}}Copy the code

Delay assignment to a GameManager public variable:

Modify the PipeHandler script’s OnTriggerExit() method to say:

private void OnTriggerExit(Collider other)
{
    if(other.tag == "Player") { GameManager.intance.UpdateScore(); }}Copy the code

12.5 Adding a Scenario

File –> Build Settings –> Add Open Scenes Add Scenes to prepare for packaging and replaying logic:

At this point, the main logic of the game is complete. The final step is to add the sound effects.


Thirteen, add sound effects

13.1 Adding Background Music

Add an “Audio Source” component to the Main Camera

Assign the BGM sound to the AudioClip property and check the Loop property to play it through:

13.2 Adding jump Sound effects

Add the “Audio Source” component to the Brid, assign the SFX_Jump sound to the AudioClip property, and uncheck the Play On Awake property to avoid autoplay:

Edit the BridHandler script and add the following three lines of code to the location shown below

// Declare the jump sound
private AudioSource Jumpaudio; 
/ / assignment
Jumpaudio = this.GetComponent<AudioSource>();
/ / play
Jumpaudio.Play();
Copy the code

Add the “Audio Source” component to the Brid, assign the SFX_Point sound to the AudioClip property, and uncheck the Play On Awake property to avoid autoplay:

Edit the GameManager script and add the following three lines of code to the location shown below:

private AudioSource getSecoreAudio;
getSecoreAudio = GetComponent<AudioSource>();
getSecoreAudio.Play();
Copy the code

At this point all the game logic is complete and ready to play


Fourteen, at the end

Development environment Unity2019.4.19 (support all versions of 5.x-2021. x)

Tested packaging platforms –> Window, Mac, Android,IOS, WebGL.


Finally, the production is completed, although the article is not much text, but combined with the picture has been explained in detail. The article is very long, I suggest collecting. Original is not easy, three even support to go again ~