- Home /
How to deal with 2D parallax in a building?
Please bear through the long description of my problem, there is a gif partway through that helps explain it.
In my game, the player is inside a building for the first part of the level. In the second part, a boss spawns in and the player starts running to the right, exiting the building in the process, as the boss chases him.
I would like both the background inside the building and the background of the cityscape outside to have parallax to them. For the infinite scrolling, the camera is static with the level elements scrolling to the left, but during the first portion of the level the camera itself is moving with the player. To handle the parallax, I give each element a relative speed factor that says how fast it will move in relation to the camera to control the parallax. For In the second portion of the level, I supply a fake value for the camera's movement to simulate that the camera is actually moving.
The parallax effect itself works great, but here's where the issue comes in. I need the background elements of the building to be constrained to the walls as if it is actually a building. When moving from side to side the building background elements will stick outside the wall.
Here is a gif that demonstrates the issue: https://gfycat.com/MilkyTeemingCassowary
So far I have a couple of ideas on how to resolve this, but none of them give a complete solution.
Write a shader that only shows the building backgrounds when they are within the bounds of the walls. The issue with this is that then it will simply look like the backgrounds are just disappearing into the walls.
Resize each background layer in accordance with how fast it moves with the parallax. This would work if it weren't for the infinite scrolling. Once the player ran outside the building, either the backgrounds would clip through the wall, or if I just disabled their parallax and had them move at the same speed as the foreground, the illusion of parallax would be destroyed.
I'm really sorry this is such a complicated and confusing problem, but I have been racking my brain for days trying to figure this out and can't think of a solution. Normally I would look to an existing game to see how they do it, but there isn't really a game out there that does this sort of thing.
If it helps, here is the script I wrote to handle the parallax:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class Parallax : MonoBehaviour
{
[Range(0f, 1f)]
public float relativeSpeed = 1f;
public bool scroll = false;
public bool loop = false;
public bool cameraParallax = false;
private List<Transform> layers = new List<Transform>();
void Awake()
{
for (int i = 0; i < transform.childCount; i++)
{
Transform child = transform.GetChild(i);
if (child.renderer != null)
{
layers.Add(child);
}
layers = layers.OrderBy(t => t.position.x).ToList();
}
}
void FixedUpdate()
{
if (scroll)
{
transform.Translate(new Vector2(-(relativeSpeed * LevelManager.instance.bossWave.cameraMoveSpeed), 0) * Time.deltaTime);
Transform firstChild = layers.FirstOrDefault();
if (firstChild != null)
{
if (firstChild.position.x < Camera.main.transform.position.x)
{
if (!firstChild.renderer.IsVisibleFrom(Camera.main))
{
if (loop)
{
Transform lastChild = layers.LastOrDefault();
Vector3 lastSize = lastChild.renderer.bounds.max - lastChild.renderer.bounds.min;
firstChild.position = new Vector3(lastChild.position.x + lastSize.x,
firstChild.position.y,
firstChild.position.z);
layers.Remove(firstChild);
layers.Add(firstChild);
}
else
{
layers.Remove(firstChild);
Destroy(firstChild.gameObject);
}
}
}
}
}
else if (cameraParallax)
{
transform.Translate((1 - relativeSpeed) * CameraFollow.instance.DeltaMovement);
}
}
}
ugh. an old question un answered.
So not the full answer but i would try two cameras. one smaller one only seeing the inside room and then on bigger camera to show the outside. and then make the draw order the small camera first then outside camera. $$anonymous$$ind of like masking it. $$anonymous$$aybe thats wrong. i think you want outside drawn first. but you get the idea.
Then you need to make all objects inside only viewable by the indoor camera and all outside objects viewable by the outside camera. and player and overlays seen by....hmm. i guess you could put them on both? not sure how that would look. if you would get a double effect on objects. should be okay since they are in exact same location. just make both cameras look at same point, should be fine.
This is just in case someone else comes along with similar problem. or maybe you already figured this out and can come back and post some code?
Your answer
Follow this Question
Related Questions
Vertical Parallax Scrolling 1 Answer
Multiple Cars not working 1 Answer
How do I do 2d parallax 1 Answer
Distribute terrain in zones 3 Answers