
Parallax
팀원분들이 Parallax를 알려주셨고 처음 사용해보았다.
유튜브를 보고 따라했고 이 기능은 배경들이

이런 식으로 앞, 중간, 뒤 배경이 각자 다른 속도로 움직이게 하는 것이다.
테스트 용이여서 오브젝트들은 다 지우고 스크립트만 따로 머지 시켰다.
하이어라키 창에 스크립트를 넣을 빈 오브젝트를 만들고
배경이미지를 넣을 자식 오브젝트들을 만들어준다.
자식 오브젝트는 3D오브젝트인 Plane으로 만들고

Mesh Collider는 지우고 Materials에 배경을 하나 씩 집어넣으면 된다.
나는 3개의 배경을 사용하기 때문에 Plane을 3개를 만들어 각각 이미지를
넣어줬다.

이미지들은 계속 반복되게 해야하기 때문에 Repeat으로 설정해야한다.
그리고 배경 오브젝트들은 Z축을 다르게 설정해줘야한다.
기본적으로 이 코드는 이미지들의 Z축 위치에 따라 속도가 달라진다는게
핵심이다.
Z축이 작을수록 속도가 빨라지고 Z축이 클수록 속도가 느려진다.
Z축이 작다는 것은 가장 앞에 있는 배경이라는 것이고
크다는 것은 가장 뒤에 있는 배경이라는 것이다.
using UnityEngine;
public class ParallaxController : MonoBehaviour
{
private Transform cam; // 메인 카메라
private Vector3 camStartPos; // 게임 시작 시 카메라 초기 위치
private float distance; // 카메라가 시작된 지점과 현재 카메라가 있는 지점 사이의 거리
private GameObject[] backgrounds; // 자식 오브젝트로 있는 모든 배경을 담을 배열
private Material[] mat; // 각 배경의 오브젝트의 Material을 담을 배열
private float[] backSpeed; // 각 배경이 움직이는 속도를 담을 배열
private float farthestBack; // 카메라로부터 가장 멀리 떨어진 배경의 z축 거리
int mainTexId = Shader.PropertyToID("_MainTex");
[Range(0.01f, 0.05f)] public float parallaxSpeed; // 0.01 ~ 0.05 사이의 시차 속도
void Start()
{
cam = Camera.main.transform; // 게임 시작 시 메인 카메라의 Transform을 가져옴
camStartPos = cam.position; // 메인 카메라의 현재 위치를 시작 위치로 저장
int backCount = transform.childCount; // 이 오브젝트의 자식(배경) 개수
mat = new Material[backCount]; // 배경 개수만큼 Material 배열을 초기화
backSpeed = new float[backCount]; // 배경 개수만큼 속도 배열을 초기화
backgrounds = new GameObject[backCount]; // 배경 개수만큼 게임 오브젝트 배열 초기화
for (int i = 0; i < backCount; i++) // i < 3
{
// i번째 자식 오브젝트를 배경 배열에 저장
backgrounds[i] = transform.GetChild(i).gameObject;
// i번째 배경의 Renderer에서 material을 Material 배열에 저장
mat[i] = backgrounds[i].GetComponent<Renderer>().material;
}
BackSpeedCalculate(backCount); // 각 배경의 상대적인 스크롤 속도를 계산
}
void BackSpeedCalculate(int backCount) // 카메라의 거리에 따라 각 배경의 속도를 설정
{
for (int i = 0; i < backCount; i++) // 카메라로부터 가장 멀리 떨어진 배경 요소를 찾아라
{
// i번째 배경의 z축 - 카메라의 현재 z축이 가장 먼 배경의 z축보다 클 때
if((backgrounds[i].transform.position.z - cam.position.z) > farthestBack)
{
// z축 기준 가장 멀리 떨어진 배경 = i번째 배경 z축 - 현재 카메라 z축
farthestBack = backgrounds[i].transform.position.z - cam.position.z;
}
}
for (int i = 0; i < backCount; i++) // 여기서 배경들 속도를 설정
{
// i번째 배경 속도 = 1 - ((i번째 배경의 z축 - 카메라의 현재 z축) / 가장 먼 배경의 z축)
backSpeed[i] = 1 - (backgrounds[i].transform.position.z - cam.position.z) / farthestBack;
}
}
private void LateUpdate()
{
// 카메라의 시작 지점으로부터 카메라의 현재 x축이 얼마나 이동했는지 계산
distance = cam.position.x - camStartPos.x;
// 오브젝트의 자체 위치를 카메라의 x축 위치화 동기화시킴
transform.position = new Vector3(cam.position.x, cam.position.y, 0);
for (int i = 0; i < backgrounds.Length; i++) // 각 배경에 시차 스크롤링 효과를 적용
{
// 최종 속도 = i번째 배경 속도 * 시차 속도를
float speed = backSpeed[i] * parallaxSpeed;
// Vector2(_distance, 0) * speed는 카메라 이동 거리에 비례하여 텍스처를 이동시킴
// Material의 _MainTex (메인 텍스처)의 오프셋을 설정하여 텍스처를 스크롤함.
mat[i].SetTextureOffset(mainTexId, new Vector2(distance, 0) * speed);
}
}
}