LoginSignup
0
0

More than 3 years have passed since last update.

[Unity3D] シーンの切り替え・フェードイン/アウト

Posted at

1, ヒエラルキーにPotalを作成し、RigidbodyとBoxColliderを作成する。各チェックとサイズを調整し、Prefabにする。
46878420-B6EA-4548-83C1-C87610FB0AD3.jpeg
43CA53AF-2A80-49AA-B7E7-3E129A45508A_4_5005_c.jpeg

2, PotalPrefabのLayer→IgnoreRaycastにする
D156A67B-844E-4C61-9F4B-0F6D13BD62EA_4_5005_c.jpeg

3, SceneManagementフォルダを作成しPotal.csを作成し、下記スクリプトを書く
3999E348-841C-422F-BC99-61D3F407ECEB_4_5005_c.jpeg

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に設定する
AA85A522-B2D6-444A-A3AB-6153C50F023B.jpeg

5, BuildSettingでSceneを設定する
6EAAD168-B7A4-48F1-95A4-CA277C93016C_4_5005_c.jpeg

別シーンから戻る

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を作成する
C9D5C136-16D7-42E2-8EA2-59E485977A8F_4_5005_c.jpeg

2, SpawnPointを動かし、位置を決める
B24D9B79-E0A7-40B1-81C7-BAF02846F7CE_4_5005_c.jpeg

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を設定する
A5A2C306-F5FA-42F6-9680-82AE3A60F508.jpeg

5, SpawnPotalを回転させてplayerの向きを決める
9F963B44-5D4F-426F-AA80-664EE1A24063_4_5005_c.jpeg

6, PlayerのNavMeshAgentを外す
757A1E33-F833-4205-946C-AECF0AA64908_4_5005_c.jpeg

複数の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のアルファベットを合わせる
8C722C7D-7FB2-4EDA-AC52-BC0E0089FE1F.jpeg

フェードアウトの作成

1, ヒエラルキーにUI→Canvasを作成する
63AA0FF7-5FDE-4F01-A41F-93E760DEC65E.jpeg

2, Faderに名前を変更し、CanvasGroupコンポーネントをつける
714B2CAB-1BAF-46B4-8C83-6F7C70462D63.jpeg

3, imageコンポーネントをつける
0A1C81EC-10CB-4635-982E-FC6EEFA5C143.jpeg

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;
            }
        }
    }
}

5, Faderスクリプトをアタッチする
9392841E-2600-41A9-A0B4-CB937C890FB9.jpeg

6,CoreとFaderをPrefabにする
A9D922B8-CB05-41CB-A4BB-29A4056043C0_4_5005_c.jpeg

7, Scene2にCorePrefabから新しく作成する
475CB893-EE17-452F-B7E0-EAC8FF6A0084_4_5005_c.jpeg

8, PersistentObjectを作成し、Faderを子オブジェクトにしてからPrefabにする
EA73B877-F3A6-47EA-8BA1-2A402727716D_4_5005_c.jpeg

9,PersistentObjectSpawner.csを作成し、Coreにアタッチする
8352ECDC-4B79-438A-834C-5D11EF644D64.jpeg

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;
        }
    }
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0