0
votes

I am trying to create a simple Infinite Runner game on Unity and ran into a problem. The task is to make a ball spawn on the floor and immediately begin to roll to the left towards the Player. I have tried a number of ways to implement it, but it does not seem to work. Here is my most recent attempt:

public class ObstaclePool : MonoBehaviour {

public GameObject columnPrefab;
public GameObject ballPrefab;
public int obstaclePoolSize = 5;
public float spawnRate = 3f;

private GameObject[] obstacles;
private int currentObstacle = 0;

private Vector2 objectPoolPosition = new Vector2(-15, -25);
private float timeSinceLastSpawned;

private float spawnXPosition;
private bool hasCalled = false;

private int dice;
bool beforeBall = false;
// Use this for initialization
void Start () {
    timeSinceLastSpawned = 0f;
    SetupObstacles();
}

private void SetupObstacles()
{
    obstacles = new GameObject[obstaclePoolSize];

    for (int i = 0; i < obstaclePoolSize; i++)
    {
        dice = Random.Range(1, 3);
        if (dice == 1)
        {
            obstacles[i] = (GameObject)Instantiate(columnPrefab, objectPoolPosition, Quaternion.identity);
        }
        else if (dice == 2)
        {
            obstacles[i] = (GameObject)Instantiate(ballPrefab, objectPoolPosition, Quaternion.identity);
        }
    }
}
// Update is called once per frame
void Update () {
    timeSinceLastSpawned += Time.deltaTime;

    if (GameControl.instance.gameOver == false && timeSinceLastSpawned >= spawnRate)
    {
        timeSinceLastSpawned = 0f;
        if (hasCalled == false)
        {
            spawnXPosition = 10f;
            hasCalled = true;
        }
        else
        {
            spawnXPosition = Random.Range(6f, 10f);
        }

        if (obstacles[currentObstacle].transform.tag == "Ball")
        {
            spawnXPosition = Random.Range(9f, 10f);
            obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -1.84f);
            ballPrefab.GetComponent<Rigidbody2D>().AddForce(new Vector2(-100f, 0) * 5);
            beforeBall = true;
        }


        else {
            if (beforeBall == true)
            {
                spawnXPosition = Random.Range(9f, 10f);
                beforeBall = false;
            }

            obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -7.08f);
            Debug.Log(spawnXPosition);
        }


        currentObstacle++;

        if (currentObstacle >= obstaclePoolSize)
        {
            currentObstacle = 0;
            SetupObstacles();
            hasCalled = false;
        }
    }
}

}

For a quick explanation of my code: I have an array of size 5. It holds the obstacles that I have created. When deciding what to put inside the array, I generated a random number (1 or 2). If it's a 1, I put in a column. If it's a 2, I put in a ball. These obstacles are spawned off-screen. Then, I move them in the actual scene after using random number to determine the X position.

This part in particular is where I try to implement it:

        if (obstacles[currentObstacle].transform.tag == "Ball")
        {
            spawnXPosition = Random.Range(9f, 10f);
            obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -1.84f);
            ballPrefab.GetComponent<Rigidbody2D>().AddForce(new Vector2(-100f, 0) * 5);
            beforeBall = true;
        }

I may have some remnants of stuff that I have been testing out, so some of the code may seem redundant and messy.

I also tried using Translate and Velocity with no success. I also have a ScrollingObject code and a RepeatingBackground code. I placed the ScrollingObject code in the Ball prefab too. (Also, tried taking it out -> ball rolls to the right). These codes come from the Unity tutorial.

RepeatingBackground:

public class RepeatingBackground : MonoBehaviour {

private BoxCollider2D groundCollider;
private float groundHorizontalLength;
// Use this for initialization
private void Awake () {
    groundCollider = GetComponent<BoxCollider2D>();
    groundHorizontalLength = groundCollider.size.x;
}

// Update is called once per frame
private void Update () {
    if (transform.position.x < -groundHorizontalLength)
    {
        RepositionBackground();
    }
}

private void RepositionBackground()
{
    Vector2 groundOffSet = new Vector2(groundHorizontalLength * 2f, 0);
    transform.position = (Vector2)transform.position + groundOffSet;
}

}

ScrollingObjects:

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;
    }
}

}

2

2 Answers

1
votes

It looks like you simply named the wrong object in your first example.

        if (obstacles[currentObstacle].transform.tag == "Ball")
    {
        spawnXPosition = Random.Range(9f, 10f);
        obstacles[currentObstacle].transform.position = new Vector2(spawnXPosition, -1.84f);
        ballPrefab.GetComponent<Rigidbody2D>().AddForce(new Vector2(-100f, 0) * 5);
        beforeBall = true;
    }

Notice how here you added the force to the prefab, not an instantiated version of the prefab.

0
votes

I played around a bit more and got it to work. I just wrote another script that added force to the object. I still do not understand why my original way did not work though.