1, ヒエラルキーにPotalを作成し、RigidbodyとBoxColliderを作成する。各チェックとサイズを調整し、Prefabにする。
2, PotalPrefabのLayer→IgnoreRaycastにする
3, SceneManagementフォルダを作成しPotal.csを作成し、下記スクリプトを書く
Portal
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RPG.SceneManagement
{
public class Potal : MonoBehaviour
{
[SerializeField] int sceneToLoad = -1;
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
SceneManager.LoadScene(sceneToLoad);
}
}
}
}
4, PortalにPortal.csをアタッチし、SceneToLoadを1に設定する
別シーンから戻る
1,下記コードを追加する
Potal
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
namespace RPG.SceneManagement
{
public class Potal : MonoBehaviour
{
[SerializeField] int sceneToLoad = -1;
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
StartCoroutine(Transition());
}
}
private IEnumerator Transition()
{
DontDestroyOnLoad(gameObject);
yield return SceneManager.LoadSceneAsync(sceneToLoad);
Debug.Log("Scene Loaded");
Destroy(gameObject);
}
}
}
SpawnPointの作成
1, Potalオブジェクト内にSpawnPointを作成する
3, 下記コードを追加する
Portal
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.AI; // 追加
namespace RPG.SceneManagement
{
public class Portal : MonoBehaviour
{
[SerializeField] int sceneToLoad = -1;
[SerializeField] Transform spawnPoint; //追加
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
StartCoroutine(Transition());
}
}
private IEnumerator Transition()
{
DontDestroyOnLoad(gameObject);
yield return SceneManager.LoadSceneAsync(sceneToLoad);
Portal otherPortal = GetOtherPortal(); //追加
UpdatePlayer(otherPortal); //追加
Destroy(gameObject);
}
//追加
private void UpdatePlayer(Portal otherPortal)
{
GameObject player = GameObject.FindWithTag("Player");
player.GetComponent<NavMeshAgent>().Warp(otherPortal.spawnPoint.position);
player.transform.rotation = otherPortal.spawnPoint.rotation;
}
//追加
private Portal GetOtherPortal()
{
foreach (Portal portal in FindObjectsOfType<Portal>())
{
if (portal == this) continue;
return portal;
}
return null;
}
}
}
4, PotalのPotalスクリプトにSpawnPointを設定する
5, SpawnPotalを回転させてplayerの向きを決める
複数のSpawnpointの切り替え
1, 下記コメント部のコードを追加
Portal
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.AI;
namespace RPG.SceneManagement
{
public class Portal : MonoBehaviour
{
//追加
enum DestinationIdentifier
{
A, B, C, D, E
}
[SerializeField] int sceneToLoad = -1;
[SerializeField] Transform spawnPoint;
[SerializeField] DestinationIdentifier destination; //追加
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
StartCoroutine(Transition());
}
}
private IEnumerator Transition()
{
//追加
if (sceneToLoad < 0)
{
Debug.LogError("Scene to load not set.");
yield break;
}
DontDestroyOnLoad(gameObject);
yield return SceneManager.LoadSceneAsync(sceneToLoad);
Portal otherPortal = GetOtherPortal();
UpdatePlayer(otherPortal);
Destroy(gameObject);
}
private void UpdatePlayer(Portal otherPortal)
{
GameObject player = GameObject.FindWithTag("Player");
player.GetComponent<NavMeshAgent>().Warp(otherPortal.spawnPoint.position);
player.transform.rotation = otherPortal.spawnPoint.rotation;
//player.transform.position = otherPortal.spawnPoint.position;
}
private Portal GetOtherPortal()
{
foreach (Portal portal in FindObjectsOfType<Portal>())
{
if (portal == this) continue;
if (portal.destination != destination) continue;
return portal;
}
return null;
}
}
}
2, Portalを作成し、Destinationのアルファベットを合わせる
フェードアウトの作成
2, Faderに名前を変更し、CanvasGroupコンポーネントをつける
4, Fader.csを作成し、下記スクリプトを書く
Fader
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace RPG.SceneManagement
{
public class Fader : MonoBehaviour
{
CanvasGroup canvasGroup;
private void Start()
{
canvasGroup = GetComponent<CanvasGroup>();
StartCoroutine(FadeOutIn());
}
IEnumerator FadeOutIn()
{
yield return FadeOut(3f);
Debug.Log("Fade out");
yield return FadeIn(1f);
Debug.Log("Fade in");
}
public IEnumerator FadeOut(float time)
{
while (canvasGroup.alpha < 1)
{
canvasGroup.alpha += Time.deltaTime / time;
yield return null;
}
}
public IEnumerator FadeIn(float time)
{
while (canvasGroup.alpha > 0)
{
canvasGroup.alpha -= Time.deltaTime / time;
yield return null;
}
}
}
}
8, PersistentObjectを作成し、Faderを子オブジェクトにしてからPrefabにする
9,PersistentObjectSpawner.csを作成し、Coreにアタッチする
10, 各スクリプトにコードを書く
PersistentObjectSpawner
using System;
using UnityEngine;
namespace RPG.Core
{
public class PersistentObjectSpawner : MonoBehaviour
{
[SerializeField] GameObject persistentObjectPrefab;
static bool hasSpawned = false;
private void Awake()
{
if (hasSpawned) return;
SpawnPersistentObjects();
hasSpawned = true;
}
private void SpawnPersistentObjects()
{
GameObject persistentObject = Instantiate(persistentObjectPrefab);
DontDestroyOnLoad(persistentObject);
}
}
}
Fader
using System.Collections;
using UnityEngine;
namespace RPG.SceneManagement
{
public class Fader : MonoBehaviour
{
CanvasGroup canvasGroup;
private void Start()
{
canvasGroup = GetComponent<CanvasGroup>();
}
public IEnumerator FadeOut(float time)
{
while (canvasGroup.alpha < 1)
{
canvasGroup.alpha += Time.deltaTime / time;
yield return null;
}
}
public IEnumerator FadeIn(float time)
{
while (canvasGroup.alpha > 0)
{
canvasGroup.alpha -= Time.deltaTime / time;
yield return null;
}
}
}
}
Portal
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.SceneManagement;
namespace RPG.SceneManagement
{
public class Portal : MonoBehaviour
{
enum DestinationIdentifier
{
A, B, C, D, E
}
[SerializeField] int sceneToLoad = -1;
[SerializeField] Transform spawnPoint;
[SerializeField] DestinationIdentifier destination;
[SerializeField] float fadeOutTime = 1f;
[SerializeField] float fadeInTime = 2f;
[SerializeField] float fadeWaitTime = 0.5f;
//private void Start()
//{
// transform.parent = null;
// DontDestroyOnLoad(gameObject);
//}
private void OnTriggerEnter(Collider other)
{
if (other.tag == "Player")
{
StartCoroutine(Transition());
}
}
private IEnumerator Transition()
{
if (sceneToLoad < 0)
{
Debug.LogError("Scene to load not set.");
yield break;
}
transform.parent = null;
DontDestroyOnLoad(gameObject);
Fader fader = FindObjectOfType<Fader>();
yield return fader.FadeOut(fadeOutTime);
yield return SceneManager.LoadSceneAsync(sceneToLoad);
Portal otherPortal = GetOtherPortal();
UpdatePlayer(otherPortal);
yield return new WaitForSeconds(fadeWaitTime);
yield return fader.FadeIn(fadeInTime);
Destroy(gameObject);
}
private void UpdatePlayer(Portal otherPortal)
{
GameObject player = GameObject.FindWithTag("Player");
player.GetComponent<NavMeshAgent>().Warp(otherPortal.spawnPoint.position);
player.transform.rotation = otherPortal.spawnPoint.rotation;
}
private Portal GetOtherPortal()
{
foreach (Portal portal in FindObjectsOfType<Portal>())
{
if (portal == this) continue;
if (portal.destination != destination) continue;
return portal;
}
return null;
}
}
}