Whats wrong in my coding?

Hello all!

I am currently trying to tackle a flappy bird style* game I am making with throwing my own flare onto it. I have followed some unity tutorials and hit some bumps along the way. My current issue maybe some of your fresh eyes can see! In my code I have a C# script called CratesPool where it is responsible for generating the pillar obstacles that you have to jump through and avoid. I have tried to implement a CoinPool script to do the same thing but generating coins that you collect. I have done this and it works however I have it generator a pool with a max of 6 coins at one time. Once you have passed the coins or even collected all 6 it stops creating more. This is my main issue that I need help with. How do I make it so that it keeps on creating coins like the cratespool script keeps on creating pillars.

An additional issue is for some reason i can not get a sound effect for the coin to play on collection of that coin.

I will add most of my scripts that i think would be associated with this. Any help is welcome!

GameControl

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

public class GameControl : MonoBehaviour {

// UI and UI fields
private const int COIN_SCORE_AMOUNT = 5;

public static GameControl Instance;
public GameObject gameOverText;
public Text scoreText, coinText, modifierText, hiscoreText;
public bool gameOver = false;
public float scrollSpeed = -2.0f;

private int score = 0;
private float coinScore, modifierScore;
private int lastScore;

// Death menu
public Animator deathMenuAnim;
public Text deadScoreText, deadCoinText;

// Use this for initialization
void Awake()
{
    if (Instance == null)
    {
        Instance = this;
    }
    else if (Instance != this)
    {
        Destroy(gameObject);
    }
    hiscoreText.text = PlayerPrefs.GetInt("Hiscore").ToString();
}

// Update is called once per frame
void Update()
{
    //if (gameOver == true && Input.GetMouseButtonDown(0))
    //{
    // Change this line to load menu once made
    //SceneManager.LoadScene(SceneManager.GetActiveScene ().buildIndex);
   }

public void GetCoin()
{
    coinScore++;
    coinText.text = "Coins: " + coinScore.ToString("0");
    score += COIN_SCORE_AMOUNT;
    scoreText.text = scoreText.text = "Score: " + score.ToString("0");
}


public void PlayerScored()
{
    if (gameOver)
    {
        return;
    }
    score++;
    scoreText.text = "Score: " + score.ToString ();
    coinText.text = "Coins: " + coinScore.ToString("0");
    deadScoreText.text = score.ToString("0");
    deadCoinText.text = coinScore.ToString("0");
}

public void PlayerDied()
{
    gameOverText.SetActive(true);
    gameOver = true;
    deathMenuAnim.SetTrigger("PlayerDied");

    // Check if this is a highscore
    if (score > PlayerPrefs.GetInt("Hiscore"))
    {
        float s = score;
        if (s % 1 == 0)
            s += 1;
        PlayerPrefs.SetInt("Hiscore", (int)s);
    }
}

public void OnPlayButton()
{
    UnityEngine.SceneManagement.SceneManager.LoadScene("Level_01");
}

public void OnMenuButton()
{
    UnityEngine.SceneManagement.SceneManager.LoadScene("Start");
}

public void OnDeath()
{
    
    deathMenuAnim.SetTrigger("PlayerDied");
}  

}

Player

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

public class Player : MonoBehaviour {

public float upForce = 50f;
public AudioClip flap;
public float flapVolume = 1f; // can change access modifier Later
public AudioClip playerdeath;
public float playerdeathVolume = 1f; // can change access modifier Later
public AudioClip scored;
public float scoredVolume = 1f; // can change access modifier Later

private bool isDead = false;
private Rigidbody2D rb2d;
private Animator anim;

// Use this for initialization
void Start ()
{
    rb2d = GetComponent<Rigidbody2D>();
    anim = GetComponent<Animator>();
}

// Update is called once per frame
void Update () {
	if (isDead == false)
    {
        if (Input.GetMouseButtonDown(0)) {
            
            Flap();
        }
    }
}

private void Flap() {
    rb2d.velocity = Vector2.zero;
    rb2d.AddForce(new Vector2(0, upForce));
    anim.SetTrigger("Flap");

    AudioSource.PlayClipAtPoint(flap, gameObject.transform.position, flapVolume);
}

private void OnTriggerEnter2D (Collider2D other)
{
    if (other.tag == "Player")
    {
        GameControl.Instance.GetCoin();
        AudioSource.PlayClipAtPoint(scored, gameObject.transform.position, scoredVolume);
        Destroy(gameObject, 1f);
    }
}
private void OnCollisionEnter2D() {
    rb2d.velocity = Vector2.zero;
    isDead = true;
    anim.SetTrigger("Die");
    GameControl.Instance.PlayerDied();

    AudioSource.PlayClipAtPoint(playerdeath, gameObject.transform.position, playerdeathVolume);
}

}

Coin

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

public class Coin : MonoBehaviour {

private void Start()
{

}

private void OnTriggerEnter2D (Collider2D other)
{
    if(other.tag == "Player")
        {
        GameControl.Instance.GetCoin();
            Destroy(gameObject, 0.5f);
    }      
}

}

CratesPool

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

public class CratesPool : MonoBehaviour {

public int cratesPoolSize = 6;
public GameObject cratesPrefab;
public float spawnRate = 2f;
public float cratesMin = -4f;
public float cratesMax = 3.5f;

private GameObject[] crates;
private Vector2 objectPoolPosition = new Vector2 (-15f, -25f);
private float timeSinceLastSpawned;
private float spawnXPosition = 5f;
private int currentCrates = 0;

// Use this for initialization
void Start ()
{
    crates = new GameObject[cratesPoolSize];
    for (int i = 0; i < cratesPoolSize; i++)
    {
        crates[i] = (GameObject)Instantiate(cratesPrefab, objectPoolPosition, Quaternion.identity);
    }
}

// Update is called once per frame
void Update ()
{
    timeSinceLastSpawned += Time.deltaTime;

    if(GameControl.Instance.gameOver == false && timeSinceLastSpawned >= spawnRate)
    {
        timeSinceLastSpawned = 0;
        float spawnYPosition = Random.Range(cratesMin, cratesMax);
        crates[currentCrates].transform.position = new Vector2(spawnXPosition, spawnYPosition);
        currentCrates++;
        if (currentCrates >= cratesPoolSize)
        {
            currentCrates = 0;
        }
    }
}

}

CoinPool

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

public class CoinPool : MonoBehaviour {

public int coinPoolSize = 6;
public GameObject coinPrefab;
public float spawnRate = 2f;
public float coinMin = -4f;
public float coinMax = 3.5f;

private GameObject[] coin;
private Vector2 objectPoolPosition = new Vector2(-15f, -25f);
private float timeSinceLastSpawned;
public float spawnXPosition = 5f;
private int currentCoin = 0;

// Use this for initialization
void Start ()
{
    coin = new GameObject[coinPoolSize];
    for (int i = 0; i < coinPoolSize; i++)
    {
        coin[i] = (GameObject)Instantiate(coinPrefab, objectPoolPosition, Quaternion.identity);
    }
}

// Update is called once per frame
void Update ()
{
    timeSinceLastSpawned += Time.deltaTime;

    if (GameControl.Instance.gameOver == false && timeSinceLastSpawned >= spawnRate)
    {
        timeSinceLastSpawned = 0;
        float spawnYPosition = Random.Range(coinMin, coinMax);
        coin[currentCoin].transform.position = new Vector2(spawnXPosition, spawnYPosition);
        currentCoin++;
        if (currentCoin >= coinPoolSize)
        {
            currentCoin = 0;
        }
    }
}

}

Scrolling Object

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

public class ScrollingObject : MonoBehaviour {

private Rigidbody2D rb2d;

// Use this for initialization
void Start ()
{
    rb2d = GetComponent<Rigidbody2D> ();
    rb2d.velocity = new Vector2 (GameControl.Instance.scrollSpeed, 0);
}

// Update is called once per frame
void Update ()
{
	if (GameControl.Instance.gameOver == true)
    {
        rb2d.velocity = Vector2.zero;
    }

}

}

Crates

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

public class Crates : MonoBehaviour {

public AudioClip scored;
public float scoredVolume = 1f; // can change access modifier Later

private void OnTriggerEnter2D (Collider2D other)
{
    if (other.GetComponent<Player> () != null)
    {
        GameControl.Instance.PlayerScored();

        AudioSource.PlayClipAtPoint(scored, gameObject.transform.position, scoredVolume);
    }
}

}

Anyone? :grin:

I’m going to assume that the bird is moving to the right like what flappy bird was like. When a players bird comes in contact with the coin, you can use Transform.position to reposition the coin to the right offscreen so that there is another coin coming up for the player to collect.

The other thing is when the player passes a coin and the coin goes offscreen you want to reposition it to the right so it’s coming up again for the player to collect again.
Unity has a function called void OnBecameInvisible() which detects when something has moved off screen and then you can reposition it to the right offscreen again so there is another coin for the player to pickup.

Thank you for the help i didn’t know about that function OnBecameInvisible I will look into that. The game is going to the right and in the CoinPool script I do have under the Void update the coin[currentCoin].transform.position = new Vector2(spawnXPosition, spawnYPosition);
currentCoin++;
if (currentCoin >= coinPoolSize)
{
currentCoin = 0;
}

Could it be something with the line of code if(currentCoin >= coinPoolSize { currentCoin = 0;}

To me when I am looking at both my cratesPool script and the coinPool script I can’t see what is different. The only thing is that the player is not collecting the pillars (Ie cratesPool) but is collecting the coins which then destroys the coin object.

Oh it could be but I’d try making it simpler myself. I’d still use your CoinPool Script to instantiate the 6 coins in Start. You wouldn’t really need an update function in the CoinPool script to keep instantiating them.

For the Coin script, if the bird touches the coin, call GameControl.Instance.GetCoin(); and then change the Transform.position of the coin so it’s ready for the player to try collecting it again. If the coin passes by the screen so it gets called by OnBecameInvisible(), then change the Transform.position of the coin so it’s ready for the player to try collecting.

Privacy & Terms