<repo_name>SelcreSS/MyStudyUnity<file_sep>/UnityStudy/Assets/Sources/System/InspectorComment.cs
﻿using UnityEngine;

/// <summary>
/// コメントの意味を持たせたいクラスです。
/// クラスやprefabの使い方の意味を教えるときなどに利用して下さい
/// 使い方
/// 1 AddComponentでこのクラスをアタッチする
/// 2 インスペクターからコメントを記載する
/// </summary>
[System.Serializable]
public class InspectorComment : MonoBehaviour
{
	[Header("==== Comment ====")]
	[TextArea(2, 5)] public string info;
}
<file_sep>/UnityStudy/Assets/Sources/UI/TestPrefab.cs
using System;
using UnityEngine.Events;

using UnityEngine;
using UnityEngine.UI;

public class TestPrefab : PopupSystem<TestPopupData>
{
    [SerializeField]
    private Text _text;
    public override void Open(TestPopupData setupData)
    {
        root.SetActive(true);
        Setup(setupData);
    }

    protected override void Setup(TestPopupData data)
    {
        _text.text = data.text;
        closeButton.onClick.AddListener(data.button1);
        okButton.onClick.AddListener(data.button2);
    }
}

public class TestPopupData
{
    public string text;
    public UnityAction button1;
    public UnityAction button2;

    public TestPopupData(string title, UnityAction button1, UnityAction button2)
    {
        text = title;
        this.button1 = button1;
        this.button2 = button2;
    }
}


<file_sep>/UnityStudy/Assets/Sources/System/PopupSystem.cs
public class PopupSystem<TData> : BasePopUp
{
    public virtual void Open(TData setupData) { }
    protected virtual void Setup(TData data) { }
}<file_sep>/UnityStudy/Assets/Sources/System/StackPopupOpener.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class StackPopupOpener : MonoBehaviour
{
    public static StackPopupOpener _Instance;

    private BasePopUp[] _stackPopups;
    private string _displayPopupName;

    // TODO
    // 簡易的に表示中ポップアップ名があるかでチェック
    public static bool IsOpened => !string.IsNullOrEmpty(_Instance._displayPopupName);

    void Awake()
    {
        _Instance = this;
        _stackPopups = GetComponentsInChildren<BasePopUp>();
    }

    public void Open<TData>(string popupName, TData setupData) where TData : class
    {
        Close(); // 二重popupブロック
        foreach(var prefab in _stackPopups)
        {
            if (prefab.name == popupName)
            {
                _displayPopupName = popupName;
                var openPrefab = (PopupSystem<TData>)prefab;
                openPrefab.Open((TData)(object)setupData);
            }
        }
    }

    public void Open(string popupName)
    {
        Close();
        foreach (var prefab in _stackPopups)
        {
            if (prefab.name == popupName)
            {
                _displayPopupName = popupName;
                prefab.Open();
            }
        }
    }

    public void Close()
    {
        foreach (var prefab in _stackPopups)
        {
            if (prefab.name == _displayPopupName)
            {
                _displayPopupName = string.Empty;
                prefab.Close();
            }
        }
    }

    private void OnDestroy()
    {
        foreach (var prefabName in _stackPopups)
        {
            prefabName.Close();
        }
        _Instance = null;
    }
}<file_sep>/UnityStudy/Assets/Sources/Main.cs
using UnityEngine;

public class Main : MonoBehaviour
{
    void Update()
    {
        if(StackPopupOpener.IsOpened)
        {
            return;
        }

        // 外部からデータを渡すPopup
        if( Input.GetMouseButtonDown(0))
        {
            var data = new TestPopupData("purchase?", () => StackPopupOpener._Instance.Close(), () => Debug.Log("OK"));
            StackPopupOpener._Instance.Open<TestPopupData>("A_SamplePopup", data);
        }
        // 内部で完結Popup
        else if(Input.GetMouseButtonDown(1))
        {
            StackPopupOpener._Instance.Open("B_SamplePopup");
        }
    }
}
<file_sep>/UnityStudy/Assets/Sources/System/BasePopUp.cs
﻿using System;
using UnityEngine;
using UnityEngine.UI;

public class BasePopUp : MonoBehaviour
{
	[SerializeField]
	protected GameObject root;

	[SerializeField]
	protected Button closeButton;
	[SerializeField]
	protected Button okButton;

	public virtual void Open() { }
	public void Close()
	{
		root.SetActive(false);
	}
}
<file_sep>/README.md
# PopupSystemの構築

個別のシーンで出る可能性のあるポップアップを一括管理で表示非表示するシステムです。
<br>※Instantiateでprefabからインスタンス化する手法ではない
<br>渡すデータの型が違っていても共通でPopupを開けます。

<使い方> カッコ内はこのサンプルの名称
 - 1、シーンにStackPopupsを配置する。多々シーンがある場合はVariant prefabでそのシーンごと作るのも〇
 - 2、StackPopups以下階層にPopupを付けます
 - 3、Popupごとのスクリプトを書きます（TestPrefab.cs/TestPrefab2.cs）
 - 4、どこかで呼び出しコードを記載します（Main.cs)

<注意点>
PopupのPrefabは必ずroot、SetActiveでON/OFFする階層を作成してくだい
<file_sep>/UnityStudy/Assets/Sources/UI/TestPrefab2.cs
using System;
using UnityEngine;
using UnityEngine.Events;

public class TestPrefab2 : BasePopUp
{
    private void Awake()
    {
        closeButton.onClick.AddListener(() =>StackPopupOpener._Instance.Close());
    }

    public override void Open()
    {
        root.SetActive(true);
    }

    public void OnClick(int index)
    {
        Debug.Log("ClickF" + index);
    }
}