Search code examples
c#unity-game-engineunity3d-2dtools

Obstacles and Background not scrolling at the same time


Me and a friend from college have a game idea where obstacles are pooled in an object pool and then scrolled across the screen (from right to left) at the same speed the background scrolls (from right to left) to give the illusion the player's character is running. This works so far.

However, we want to make it so that the background and obstacles gradually increase in speed as time goes on while remaining the same speed as each other to make the game harder for the user.

We've had loads of trouble implementing this. Originally we tried to add a speed modifier to both base speeds but this resulted in wildly different speeds. I believe it has something to do with the fact we're using a texture offset to move the background but for obstacles we're using velocity. If it helps, everything (apart from the background, the camera, EventSystem and GameController) is within a canvas because that was the only way we knew how to scale at the time.

So, what are we doing wrong here?

Background Scrolling Code:

using UnityEngine;

public class Background : MonoBehaviour
{

/*
 * 
 * A script that's sole purpose is to create a scrolling, infinite background.
 * Attached to: Brick
 * Scene: Level0
 *
 */

public float scrollSpeed;
private Vector2 savedOffset;
private Renderer rndrer;
private float conversionFactor = 0.1f;
public static Background instance;

private void Start()
{
    rndrer = GetComponent<Renderer>();
    savedOffset = rndrer.material.GetTextureOffset("_MainTex");
}

private void FixedUpdate()
{
    this.rndrer.material.SetTextureOffset("_MainTex", new Vector2((GameControl.speed * conversionFactor), 0));
}

private void OnDisable()
{
    rndrer.sharedMaterial.SetTextureOffset("_MainTex", savedOffset);
}
}

Obstacle Scrolling Code:

using UnityEngine;

public class ObstacleScrolling : MonoBehaviour
{

/*
 * 
 * A script which controls the movement of the Obstacles to make it look like the player is running towards them.
 * Attached to: [All Obstacles in the Prefabs folder]
 * Scene: Level0
 * 
 */

private Rigidbody2D rb2d;
public float scrollSpeed;
public float test;
GameObject canvasObj;
Canvas canvas;

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

    canvasObj = GameObject.Find("Canvas");
    canvas = canvasObj.GetComponent<Canvas>();

    test = -1280 * canvas.scaleFactor;

    scrollSpeed = scrollSpeed * canvas.scaleFactor; //+ -(Time.timeSinceLevelLoad / 100);
}

// Update is called once per frame
void FixedUpdate()
{
    this.transform.Translate(Vector3.right * GameControl.speed);

    if (GameControl.instance.gameOver == true)
    {
        rb2d.velocity = Vector2.zero;
    }
}
}

Solution

  • use this:

    public class GameControl : MonoBehaviour
    {
    private static float speedFactor = 1.0f; // you can set this to canvas scale
    private static float speed = 1.0f;
    
    public static float ScaledSpeed
    {
        get
        {
            return speed * speedFactor;
        }
    }
    
    void FixedUpdate()
    {
        speed += 0.01f * Time.deltaTime;
    }
    }
    

    and this:

    public class Background : MonoBehaviour
    {
    private Vector2 savedOffset;
    private Vector2 offset;
    private Renderer rndrer;
    private float conversionFactor = 0.1f;
    
    private void Start()
    {
        rndrer = GetComponent<Renderer>();
        savedOffset = rndrer.material.GetTextureOffset("_MainTex");
        offset = savedOffset;
    }
    
    private void FixedUpdate()
    {
        offset += new Vector2(GameControl.ScaledSpeed * conversionFactor, 0);
        this.rndrer.material.SetTextureOffset("_MainTex", offset);
    }
    }
    

    and this:

    public class ObstacleScrolling : MonoBehaviour
    {
    void FixedUpdate()
    {
        this.transform.Translate(Vector3.right * GameControl.ScaledSpeed);
    }
    }