Simulating depth on a 2D 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
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
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
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
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:
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)
Answer by anilhdas · Jan 12, 2017 at 04:23 PM
As I read the problem statement (correct me if I'm wrong), you have 2 layers of obstacles. Both of the layer objects has box collider and you will need to enable any one of them at a given time (obvious to disable the other).
And I can see that you have 4 scripts enabling and disabling the collider in update (which is not the recommended way to do things).
For this, you will only need one script holding the both the array of foreground objects and background objects. You have a boolean (preferably enum) to store the layer in which player is currently in (something like 'isPlayerInForeground').
When you receive Input.getKey(), you can check the boolean and enable the respected array of colliders and disable the other. Don't forget to flip the boolean as well.
Hope it helps. Let me know if I'm missing anything. (O_o)
I think that this might work.
But I´m kind new to Unity (haven´t worked with arrays on it yet), so if it isn´t too much to ask, could you help me with more or less how the script would shape up to be with the solution you suggested?
Answer by BarleyWarb · Jan 10, 2017 at 06:40 AM
It looks like every time you press space bar, you're creating a new boxCollider and then either enabling it or disabling it (and doing so every frame, which is unnecessary). So if you press space bar 10 times, your object would now have 10 boxColliders on it, only five of which are enabled. I could be wrong as it's late and I haven't tried this, but I would think each foreground/background object should have a single script that creates a boxCollider for the object on Start(), and then four (or even just one) functions that toggle whether the boxCollider is enabled or disabled, and nothing in the Update() function. Then whenever you wanna make the switch, you would iterate through an array of foreground and background objects, calling their switch functions. Obviously with a way to differentiate between foreground and background objects (a const would do, I'd think).
Does this make sense?
$$anonymous$$inda does. But as far as I know, the script is not creating a new collider everytime the space bar is pressed, the collider is only being activated/deactivated (object.enabled).
But can you give some help with the solution you´re suggesting with a script? That would be extremely helpful!
Your answer
Follow this Question
Related Questions
Simulating 2D depth in a sidescroller 0 Answers
2D depth in a sidescroller 0 Answers
2D depth simulation in a sidescroller 1 Answer
How to stop an object from following its parent? 3 Answers
Unity Sprite renderer bug?? 0 Answers