2D depth simulation in a sidescroller

I am developing a 2D sidescroller. One of the basic mechanics of the game is that the player can choose between being on the foreground of the level or on the background of the level (deviating from the obstacles accordingly).

Since I´m developing it in pure 2D form, I´m having to “simulate” the depth of the level.

For that, I created four scripts:

  • One of them turns OFF the FOREGROUND objects collider (TurnOffCollisionForeground)

  • The other turns OFF the BACKGROUND objects collider (TurnOffCollisionBackground)

  • The other turns ON the BACKGROUND objects collider (TurnOnCollisionForeground)

  • And the other turns ON the BACKGROUND objects collider (TurnOnCollisionBackground)

TurnOffCollisionForeground

using UnityEngine;
using System.Collections;

public class TurnOffCollisionForeground : MonoBehaviour
{
    private BoxCollider2D boxCollider;  

    // Use this for initialization
    void Start()
    {
        boxCollider = GetComponent<BoxCollider2D>();      
    }

    public void OnCollisionEnter2D()
    {
        boxCollider.enabled = false;
    }

    // Update is called once per frame
    void Update()
    {
        OnCollisionEnter2D();
    }
}

TurnOffCollisionBackground

using UnityEngine;
using System.Collections;

public class TurnOffCollisionBackground : MonoBehaviour
{

    private BoxCollider2D boxCollider;

    // Use this for initialization
    void Start()
    {
        boxCollider = GetComponent<BoxCollider2D>();      
    }

    public void OnCollisionEnter2D()
    {
        boxCollider.enabled = false;
    }


    // Update is called once per frame
    void Update()
    {
        OnCollisionEnter2D();
    }
}

TurnOnCollisionForeground

using UnityEngine;
using System.Collections;

public class TurnOnCollisionForeground : MonoBehaviour {

    private BoxCollider2D boxCollider;

    // Use this for initialization
    void Start()
    {
        boxCollider = GetComponent<BoxCollider2D>();
    }

    public void OnCollisionEnter2D()
    {
        boxCollider.enabled = true;
    }


    // Update is called once per frame
    void Update()
    {
        OnCollisionEnter2D();
    }
}

TurnOnCollisionBackground

using UnityEngine;
using System.Collections;

public class TurnOnCollisionBackground : MonoBehaviour {

    private BoxCollider2D boxCollider;

    // Use this for initialization
    void Start()
    {
        boxCollider = GetComponent<BoxCollider2D>();
    }

    public void OnCollisionEnter2D()
    {
        boxCollider.enabled = true;
    }


    // Update is called once per frame
    void Update()
    {
        OnCollisionEnter2D();
    }
}

To check in what layer of depth the player is, I wrote the SendStatus script (which is attached to the player). In this script, inside the CurrentStatus() function (which is repeatedly called in Update() ) I check for player answer regarding the choice of layer - which he transits between by pressing the space bar.

The main thing here is that I want to use the SendStatus script to activate other scripts (TurnOffCollisionBackground, TurnOffCollisionForeground…) which are in OTHER game objects (prefab objects that contain said scripts).

Observation : on Start(), I initialize the player in the foreground layer (which is where he is supposed to start the game on)

To do that, I tried referencing those scripts in the SendStatus script and enabling/disabling them accordingly, as you can check below:

using UnityEngine;
using System.Collections;

public class SendStatus : MonoBehaviour {

    //This script in on the player

    public bool isOnForeground;
    public bool isOnBackground;

    private TurnOffCollisionBackground offBack;
    private TurnOnCollisionBackground onBack;
    private TurnOffCollisionForeground offFore;
    private TurnOnCollisionForeground onFore;

	// Use this for initialization
	void Start ()
    {
        isOnForeground = true;
        isOnBackground = false;

        offBack = GetComponent<TurnOffCollisionBackground>();
        onBack = GetComponent<TurnOnCollisionBackground>();
        offFore = GetComponent<TurnOffCollisionForeground>();
        onFore = GetComponent<TurnOnCollisionForeground>();

        offBack.enabled = true;
        onBack.enabled = false;
        offFore.enabled = false;
        onFore.enabled = true;

    }

    public void CurrentStatus()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            if (isOnForeground == true && isOnBackground == false) 
            {
                isOnForeground = false;
                isOnBackground = true;

                offBack.enabled = false;
                onBack.enabled = true;
                offFore.enabled = true;
                onFore.enabled = false;

            }
            if (isOnForeground == false && isOnBackground == true) 
            {
                isOnForeground = true;
                isOnBackground = false;

                offBack.enabled = true;
                onBack.enabled = false;
                offFore.enabled = false;
                onFore.enabled = true;
            }
        }
    }
	
	// Update is called once per frame
	void Update ()
    {
        CurrentStatus();
	}
}

However, this solution is not working properly. When I run the game and I check the scripts in the obstacles, they don´t alternate accordingly (activating or deactivating).

-------------------------------------------------------------------------------------------------------------------------------------

To sum up - my main problem is finding a way to activate and deactivate scripts on other game objects (the obstacles) from another script (SendStatus) in a different game object (the player)

In all of your scripts Update() function, you are always enabling the collider regardless of what your SendStatus script is doing. To be honest you don’t need a 4 scripts to manage this, you could get away with just one.

  1. Separate all the objects into empty game objects (one for foreground, one for background)
  2. In the SendStatus script (or a new one since it doesn’t send any status anymore), have two public GameObject variables (or a GameObject array if you are ok with that style) that you assign in the inspector for the two empty objects acting as parents.
  3. In the Start() function, loop through the two GameObjects and either add the colliders from the children to respective Lists (recommended) or add them to respective Collider2D arrays for caching and easier access.
  4. Write one function that will loop through a given List/Array that will invert the current value (example invert using your code, isOnForeground = !isOnForeground)
  5. Call that function only when you are intending to switch from the foreground and the background so that you don’t even need an Update() function.

That should solve most of the issues you may have with placed prefabs but if you are trying to have enemies that dynamically spawn and move, you cannot use this method on them. For that you would need to add the enemy to the list of objects for it’s respective depth as soon as it spawns (which is why I recommend you use a List). If you need more help or have questions feel free to ask.

C# List Info

Finding Components In Children