- 投稿日:2021-03-02T23:19:55+09:00
[Unity3D] シーンの切り替え・フェードイン/アウト
1, ヒエラルキーにPotalを作成し、RigidbodyとBoxColliderを作成する。各チェックとサイズを調整し、Prefabにする。
2, PotalPrefabのLayer→IgnoreRaycastにする
3, SceneManagementフォルダを作成しPotal.csを作成し、下記スクリプトを書く
Portalusing 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,下記コードを追加する
Potalusing 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, 下記コードを追加する
Portalusing 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, 下記コメント部のコードを追加
Portalusing 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を作成し、下記スクリプトを書く
Faderusing 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, 各スクリプトにコードを書く
PersistentObjectSpawnerusing 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); } } }Faderusing 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; } } } }Portalusing 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; } } }
- 投稿日:2021-03-02T14:21:48+09:00
Wallpaper Engineみたいに壁紙をUnityで作る
はじめに
今回は動く壁紙として有名なWallpapaer Engineのように、Unityで作ったプロジェクトを壁紙として表示する方法を書きます。
仕組み
壁紙のウィンドウハンドルを取得し、Unityのプロジェクトをそのウィンドウの子ウィンドウとして表示するだけです。
壁紙のウィンドウハンドル
c++で取得します。この記事ではc++でdllを作り、c#で呼び出します。
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { HWND p = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", NULL); HWND* ret = (HWND*)lParam; if (p) { *ret = FindWindowEx(NULL, hwnd, L"WorkerW", NULL); } return true; } HWND get_wallpaper_window() { HWND progman = FindWindow(L"ProgMan", NULL); SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr); HWND wallpaper_hwnd = nullptr; EnumWindows(EnumWindowsProc, (LPARAM)&wallpaper_hwnd); return wallpaper_hwnd; }Unityを表示する
[DllImport("WallpaperDLL.dll")] //c++で作ったdllを呼び出す static extern IntPtr GetWallpaperHWND(); /*------------------------------------------*/ var path = ユニティーのexeのパス; var cmdline = $"-parentHWND {GetWallpaperHWND()}";//子ウィンドウとして起動 Process exe = Process.Start(path, cmdline);完成
二つ作ってみました。結構いい感じにできてよかったです。
ソース
DLL
最後に
結構簡単なのでぜひ試してみてください
参考
https://yotiky.hatenablog.com/entry/unity_uaal-wpf
https://stackoverflow.com/questions/56132584/draw-on-windows-10-wallpaper-in-c
- 投稿日:2021-03-02T14:21:48+09:00
Wallpaper Engineみたいな壁紙をUnityで作る
はじめに
今回は動く壁紙として有名なWallpapaer Engineのように、Unityで作ったプロジェクトを壁紙として表示する方法を書きます。
仕組み
壁紙のウィンドウハンドルを取得し、Unityのプロジェクトをそのウィンドウの子ウィンドウとして表示するだけです。
壁紙のウィンドウハンドル
c++で取得します。この記事ではc++でdllを作り、c#で呼び出します。
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { HWND p = FindWindowEx(hwnd, NULL, L"SHELLDLL_DefView", NULL); HWND* ret = (HWND*)lParam; if (p) { *ret = FindWindowEx(NULL, hwnd, L"WorkerW", NULL); } return true; } HWND get_wallpaper_window() { HWND progman = FindWindow(L"ProgMan", NULL); SendMessageTimeout(progman, 0x052C, 0, 0, SMTO_NORMAL, 1000, nullptr); HWND wallpaper_hwnd = nullptr; EnumWindows(EnumWindowsProc, (LPARAM)&wallpaper_hwnd); return wallpaper_hwnd; }Unityを表示する
[DllImport("WallpaperDLL.dll")] //c++で作ったdllを呼び出す static extern IntPtr GetWallpaperHWND(); /*------------------------------------------*/ var path = ユニティーのexeのパス; var cmdline = $"-parentHWND {GetWallpaperHWND()}";//子ウィンドウとして起動 Process exe = Process.Start(path, cmdline);完成
二つ作ってみました。結構いい感じにできてよかったです。
ソース
DLL
最後に
結構簡単なのでぜひ試してみてください
参考
https://yotiky.hatenablog.com/entry/unity_uaal-wpf
https://stackoverflow.com/questions/56132584/draw-on-windows-10-wallpaper-in-c
- 投稿日:2021-03-02T12:17:03+09:00
UnityでiOSのUIColorPickerViewControllerを使うPlugin
はじめに
iOS14から導入されたUIColorPickerViewControllerをUnityから使いたかったのでPluginを書きました。
レポジトリ
Unitypackage
UIColorPickerManager.unitypackage
Sample
public void Show(){ Color currentColor = Color.white; UIColorPickerManager.Show(currentColor, OnSelectColor, OnFinish); } // call when color selected. void OnSelectColor(Color selectedColor){ // ... } // call UIColorPickerViewController finished. void OnFinish(){ }UIColorPickerManager.Show
UIColorPickerManager.Show
にはいくつかのオーバーライドがあります。選択された色をColorオブジェクトで受け取る
void Show ( Color currentColor, OnColorSelectedCallback onColorSelectedCallback, // Colorオブジェクトを受け取るコールバック関数 OnFinishCallback onFinishCallback)選択された色をRGBAで受け取る場合
void Show ( Color currentColor, OnRGBColorSelectedCallback onRGBColorSelectedCallback, // RGBAを受け取るコールバック関数 OnFinishCallback onFinishCallback)選択された色をColorオブジェクトで受け取り、iOS14未満の時の処理を必要とする場合
void Show ( Color currentColor, OnColorSelectedCallback onColorSelectedCallback, OnFinishCallback onFinishCallback, OnEarlierIOSVersionsCallback onEarlierIOSVersionsCallback)選択された色をRGBAで受け取り、iOS14未満の時の処理を必要とする場合
void Show ( Color currentColor, OnRGBColorSelectedCallback onRGBColorSelectedCallback, OnFinishCallback onFinishCallback, OnEarlierIOSVersionsCallback onEarlierIOSVersionsCallback)参考:上記のコードで使われているdelegateの定義
// - colorPickerViewControllerDidSelectColor: 用コールバック public delegate void OnColorSelectedCallback(Color color); public delegate void OnRGBColorSelectedCallback (float r, float g, float b, float a); // - colorPickerViewControllerDidFinish: 用コールバック public delegate void OnFinishCallback(); // @available(iOS 14.0, *) がfalseの時用コールバック public delegate void OnEarlierIOSVersionsCallback();ライセンス
ライセンスはMITです。
補足
いないかもしれませんが、ソースコードを読みたいという方がいれば、
先に、 [Unity]ネイティブプラグインからコールバック関数を呼ぶ[iOS]
という記事を読むことをお勧めします。このプラグインは、その記事の応用になっています。