84 lines
2.2 KiB
C#
84 lines
2.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
|
|
public class WorldSwitcher : MonoBehaviour {
|
|
[Range(0, 5)]
|
|
[SerializeField] float transitionDuration;
|
|
[SerializeField] AnimationCurve transitionCurve;
|
|
[SerializeField] Camera[] cameras;
|
|
[SerializeField] Transform renderQuad;
|
|
[SerializeField] float quadOffset;
|
|
int lastWorldIndex;
|
|
int currentWorldIndex;
|
|
Coroutine transition;
|
|
RenderTexture renderTexture;
|
|
Material renderMaterial;
|
|
|
|
void Awake() {
|
|
if (cameras.Length <= 1)
|
|
Debug.LogWarning("WorldSwitcher should have multiple cameras");
|
|
|
|
currentWorldIndex = 0;
|
|
lastWorldIndex = 0;
|
|
|
|
renderMaterial = renderQuad.GetComponent<Renderer>().material;
|
|
GenerateRenderTexture();
|
|
}
|
|
|
|
public void SwitchWorld(int index) {
|
|
if (index == currentWorldIndex)
|
|
return;
|
|
|
|
if (index < 0 || index >= cameras.Length)
|
|
throw new IndexOutOfRangeException($"{index} is not an available world.");
|
|
|
|
lastWorldIndex = currentWorldIndex;
|
|
currentWorldIndex = index;
|
|
|
|
Camera currCam = cameras[currentWorldIndex];
|
|
currCam.enabled = true;
|
|
|
|
//TODO Block window resize during transition?
|
|
if (Screen.width != renderTexture.width || Screen.height != renderTexture.height)
|
|
GenerateRenderTexture();
|
|
|
|
currCam.targetTexture = renderTexture;
|
|
|
|
renderQuad.localScale = new Vector3(cameras[lastWorldIndex].aspect, 1f, 1f);
|
|
|
|
transition = StartCoroutine(TransitionCamera());
|
|
}
|
|
|
|
void OnGUI() {
|
|
for (int i = 0; i < cameras.Length; ++i) {
|
|
if (i == currentWorldIndex)
|
|
continue;
|
|
|
|
if (GUILayout.Button($"World {i}"))
|
|
SwitchWorld(i);
|
|
}
|
|
}
|
|
|
|
IEnumerator TransitionCamera() {
|
|
float startTime = Time.time;
|
|
Transform lastCam = cameras[lastWorldIndex].transform;
|
|
|
|
while (Time.time < startTime + transitionDuration) {
|
|
float t = transitionCurve.Evaluate((Time.time - startTime) / transitionDuration);
|
|
|
|
renderQuad.position = lastCam.position + Vector3.forward * quadOffset + Vector3.right * (2f * t - 2f);
|
|
|
|
yield return null;
|
|
}
|
|
|
|
cameras[currentWorldIndex].targetTexture = null;
|
|
cameras[lastWorldIndex].enabled = false;
|
|
transition = null;
|
|
}
|
|
|
|
void GenerateRenderTexture() {
|
|
renderTexture = new RenderTexture(Screen.width, Screen.height, 32);
|
|
renderMaterial.mainTexture = renderTexture;
|
|
}
|
|
} |