見出し画像

【Unity】汎用スクリプト

Unityでよく使用しているスクリプトを紹介します。

1.PauseScript

ポーズ(一時停止)に使用できる。
コード中盤の「※最重要※ポーズ画面になる条件」の下のコードを変えれば、マウス、キーボードの入力からでもポーズできる。ポーズ中に消したい、映したいオブジェクトも指定できる。

using UnityEngine;
using UnityEngine.UI;

//一時停止ボタン、参考 https://www.youtube.com/watch?v=w10_AXiGYuY

public class PauseScript : MonoBehaviour{
    [System.NonSerialized] public bool IsOnPause;
    [Header("ポーズ中に表示するパネル等")]public GameObject [] pauseEffects;
    [Header("ポーズ中隠したいオブジェクト")] public GameObject [] HideObjects;
    [Header("ポーズ画面に入る効果音")]public AudioClip pauseOnSE;
    [Header("ポーズ画面から抜ける効果音")] public AudioClip pauseOffSE;
    SoundManager soundManager;
    //public GameContoroller gameContoroller;//ステージクリア後かどうか判定するためにgamecontorollerを登録。ゲーム内容によっては不要。

    private void Start() {
        GameObject gameObject = GameObject.FindGameObjectWithTag("SoundManager");
        soundManager = gameObject.GetComponent<SoundManager>();
    }

    //画面上に設定しているボタンをクリックした場合
    public void OnClick() {
        pauseTheGame();
    }

    //マウス、キーボード、コントローラー等のボタンを押した場合
    public void Update() {
        //////////////////※最重要※ポーズ画面になる条件///////////////////
       if (Input.GetMouseButtonDown(1)/* &&!gameContoroller.isEnd*/) {         
            pauseTheGame();
        }
    }

    public void pauseTheGame(){
        if (IsOnPause) { 
            Time.timeScale = 1;
            IsOnPause = false;
            soundManager.PlaySe(pauseOffSE);
            for (int i = 0; i < pauseEffects.Length; i++) {
                pauseEffects[i].SetActive(false);
            }
            for (int i = 0; i < HideObjects.Length; i++) {
                HideObjects[i].SetActive(true);
            }
        } else {
            soundManager.PlaySe(pauseOnSE);
            Time.timeScale = 0;
            IsOnPause = true;
            for (int i = 0; i < pauseEffects.Length; i++) {
                pauseEffects[i].SetActive(true);
            }
            for (int i = 0; i < HideObjects.Length; i++) {
                HideObjects[i].SetActive(false);
            }
        }
    }
}

2.ConviniButton

ボタンにつけることを想定しているスクリプト。
シーン遷移、Webページ表示、SEを鳴らす、オブジェクトの表示・非表示等。
連打防止機能あり。
SoundManagerとの組み合わせ必須。
FadeControllerとの組み合わせ推奨。

using UnityEngine;
using UnityEngine.SceneManagement;
using System;

public class ConveniButton : MonoBehaviour {
    [Header("表示したいWebページ")] public String url;
    [Header("移動したいシーン")] public String scene;
    [Header("ActiveSelfを切り替えたいゲームオブジェクト")] public GameObject [] openAndcloseObject;
    [Header("表示させたいゲームオブジェクト")] public GameObject[] showObject;
    [Header("消したいゲームオブジェクト")] public GameObject[] hideObject;
    [Header("Delayで遅らせたい時間")] public float delayTime;
    [Header("ウィンドウオープン時またはシーン遷移時になるSE")]public AudioClip OpenSE;
    [Header("ウィンドウクローズ時またはゲーム終了時になるSE")]public AudioClip CloseSE;
    [Header("フェードコントローラー")] public FadeController fadeController;
    bool dontSeBarrage;//DelayGoT0Scene,DelayQuitScene,DelayRetryのSEの連射防止
    SoundManager soundManager;

    public void Start() {
        GameObject gameObject = GameObject.FindGameObjectWithTag("SoundManager");
        soundManager = gameObject.GetComponent<SoundManager>();
        dontSeBarrage = false;
    }

    /// <summary>
    /// シーン遷移
    /// </summary>
    public void GoToScene() {
        Time.timeScale = 1;
        SceneManager.LoadScene(scene);
    }

    /// <summary>
    /// delayTime分遅れて、シーン遷移
    /// </summary>
    public void DelayGoToScene() {
        if (OpenSE&&!dontSeBarrage) {
            soundManager.PlaySe(OpenSE); 
        }
        if(fadeController != null) {
            fadeController.isFadeOut = true;
        }
        dontSeBarrage = true;
        Invoke("GoToScene", delayTime);
    }

    /// <summary>
    /// 現在のシーンと同じシーンに遷移
    /// </summary>
    public void Retry() {
        Time.timeScale = 1;
        SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    }

    /// <summary>
    /// delayTime分遅れて、現在のシーンと同じシーンに遷移
    /// </summary>
    public void DelayRetry() {
        if (OpenSE && !dontSeBarrage) {
            soundManager.PlaySe(OpenSE);
        }
        if (fadeController != null) {
            fadeController.isFadeOut = true;
        }
        dontSeBarrage = true;
        Invoke("Retry", delayTime);
    }

    /// <summary>
    /// ゲーム終了
    /// </summary>
    public void QuitGame() {
        Application.Quit();
    }

    /// <summary>
    /// delayTime分遅れて、ゲーム終了
    /// </summary>
    public void DelayQuitGame() {
        if (CloseSE&&!dontSeBarrage) {
            soundManager.PlaySe(CloseSE);
            dontSeBarrage = true;
        }
        Invoke("QuitGame", delayTime);
    }

    /// <summary>
    /// Webページを開く
    /// </summary>
    public void GoToWeb() {
        if (OpenSE) {
            soundManager.PlaySe(OpenSE);
        }
        Application.OpenURL(url);
    }

    /// <summary>
    /// openAndcloseObjectのActiveSelfを切り替える。delaytimeに入力があると、delayTime分感覚を開けないと、再度押せない
    /// </summary>
    public void OpenOrClose() {
        for (int i = 0; i < openAndcloseObject.Length; i++) {
            if (openAndcloseObject[i].activeSelf) {
                if (CloseSE) {
                    soundManager.PlaySe(CloseSE);
                }
                openAndcloseObject[i].SetActive(false);
            } else {
                if (OpenSE) {
                    soundManager.PlaySe(OpenSE);
                }
                openAndcloseObject[i].SetActive(true);
            }
        }
        if (delayTime > 0) {
            dontSeBarrage = true;
            Invoke("BarrageOK", delayTime);
        }
    }

    /// <summary>
    /// showObjectを表示させ、hideObjectを隠す。delaytimeに入力があると、delayTime分感覚を開けないと、再度押せない
    /// </summary> 
    public void ShowAndHide() {
        Show();
        Hide();
        if (delayTime > 0) {
            dontSeBarrage = true;
            Invoke("BarrageOK", delayTime);
        }
    }

    /// <summary>
    /// showObjectを表示させる
    /// </summary>    
    public void Show() {
        for (int i = 0; i < showObject.Length; i++) {
            showObject[i].SetActive(true);
        }
    }

    /// <summary>
    /// hideObjectを隠す
    /// </summary>
    public void Hide() {
        for (int i = 0; i < hideObject.Length; i++) {
            hideObject[i].SetActive(false);
        }
    }

    /// <summary>
    /// OpenSEを鳴らすだけ、delayTime分感覚を開けないと、再度押せない
    /// </summary>
    public void PlaySE() {
        if (!dontSeBarrage) {
            soundManager.PlaySe(OpenSE);
        }

        if (delayTime > 0) {
            dontSeBarrage = true;
            Invoke("BarrageOK", delayTime);
        }
    }

    //連射を可能にする
    private void BarrageOK() {
        dontSeBarrage = false;
    }
}

3.StartManager

ゲームスタート時のタイトル表示→SE再生→ボタン表示&BGM再生という流れに使用できる。
変数とコルーチンの項目を増やせば、凝った演出も可能。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class StartManager : MonoBehaviour {
    SoundManager soundManager;
    public AudioClip bgm;
    public AudioClip titleSE;
    public GameObject titleText;
    public GameObject buttons;

    private void Start () {
        GameObject gameObject = GameObject.FindGameObjectWithTag("SoundManager");
        soundManager = gameObject.GetComponent<SoundManager>();
        soundManager.StopBgm();
        StartCoroutine("TitleStart");
    }

    IEnumerator TitleStart() {
        //0.3秒停止
        yield return new WaitForSeconds(0.3f);
        //タイトルテキスト
        titleText.SetActive(true);
        yield return new WaitForSeconds(0.5f);
        //タイトルSE
        soundManager.PlaySe(titleSE);
        yield return new WaitForSeconds(0.8f);
        //ボタン表示
        //BGMスタート
        soundManager.PlayBgm(bgm);
        buttons.SetActive(true);
        yield return null;
    }
}

4.SoundManager

サウンドマネージャー。各シーンに一つ置く。
audioMixerの使用必須。

using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.SceneManagement;

public class SoundManager : MonoBehaviour
{
    [SerializeField] AudioMixer audioMixer;
    [SerializeField] AudioSource bgmAudioSource;
    [SerializeField] AudioSource seAudioSource;

    public static SoundManager instance;
    void Awake() {
        CheckInstance();
    }
    void CheckInstance() {
        if (instance == null) {
            instance = this;
        } else {
            Destroy(gameObject);
        }
    }

    void Start() {
        DontDestroyOnLoad(gameObject);//シーン遷移しても破棄されない
    }

    /// <summary>
    /// BGMを再生
    /// </summary>
    /// <param name="clip"></param>
    public void PlayBgm(AudioClip clip) {
        bgmAudioSource.clip = clip;
        bgmAudioSource.Play();
    }

    /// <summary>
    /// BGMを停止
    /// </summary>
    public void StopBgm() {
        bgmAudioSource.Stop();
    }

    /// <summary>
    /// 効果音を再生
    /// </summary>
    /// <param name="clip"></param>
    public void PlaySe(AudioClip clip) {
        seAudioSource.PlayOneShot(clip);
    }

    /// <summary>
    /// 引数のAudioClipの中からランダムに再生
    /// </summary>
    /// <param name="clips"></param>

    public void RandomizeSfx(params AudioClip[] clips) {
        var randomIndex = UnityEngine.Random.Range(0, clips.Length);
        seAudioSource.PlayOneShot(clips[randomIndex]);
    }
}

5.AudioVolume

AudioMIxerのボリュームを記録する。
BGMスライダーとSEスライダーが必須。
スライダーがないシーンには置かない。
EasySaveを使用しているので、EasySaveがない人はPlayerPrefsに置き換えることで使用可能。

using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.UI;

public class AudioVolume : MonoBehaviour {
    public AudioMixer audioMixer;//オーディオミキサーを登録
    public Slider bGMSlider;//BGMのスライダーを登録
    public Slider sESlider;//SEのスライダーを登録

    public static AudioVolume instance;

    void Awake() {
        CheckInstance();
    }
    void CheckInstance() {
        if (instance == null) {
            instance = this;
        } else {
            Destroy(gameObject);
        }
    }

    private void Start() {
        //BGMとSEのスライダーの位置をロード。データがなければ最大値を入れる。
        float bgmSliderPosition = ES3.Load<float>("BGM_SLIDER", 5.0f);
        float seSliderPosition = ES3.Load<float>("SE_SLIDER", 5.0f);
        //BGMとSEのセットメソッドを呼び出す
        SetBGM(bgmSliderPosition);
        SetSE(seSliderPosition);
    }

    public void SetBGM(float bgmSliderPosition) {
        //スライダーの位置から相対量をdBに変換してvolumeに入れる
        var volume = Mathf.Clamp(Mathf.Log10(bgmSliderPosition/5) * 20f, -80f, 0f);
        //スライダーの位置のデータとビジュアルを合わせる
        bGMSlider.value = bgmSliderPosition;
        //オーディオミキサーにvolumeの値をセットする。
        audioMixer.SetFloat("BGM", volume);
        //スライダーの位置をセーブする。
        ES3.Save<float>("BGM_SLIDER", bGMSlider.value);
    }

    public void SetSE(float seSliderPosition) {
        var volume = Mathf.Clamp(Mathf.Log10(seSliderPosition/ 5) * 20f, -80f, 0f);
        sESlider.value = seSliderPosition;
        audioMixer.SetFloat("SE", volume);
        ES3.Save<float>("SE_SLIDER", sESlider.value);
    }
}

6.FadeController

Panelにアタッチし、他のScriptからisFadeOut、isFadeInをtrueにすると、Panelの透明度が変わり、フェードイン、フェードアウトが実行される。
Panelの大きさはギリギリではなく、余裕をもって大きくしたほうが良い。

using UnityEngine;
using UnityEngine.UI; //パネルのイメージを操作するのに必要

public class FadeController : MonoBehaviour {

	public float fadeInSpeed = 0.02f;        //フェードイン時に透明度が変わるスピードを管理
	public float fadeOutSpeed = 0.02f;       //フェードアウト時に透明度が変わるスピードを管理
    float red, green, blue, alfa;   //パネルの色、不透明度を管理

	public bool isFadeOut = false;  //フェードアウト処理の開始、完了を管理するフラグ
	public bool isFadeIn = false;   //フェードイン処理の開始、完了を管理するフラグ

	Image fadeImage;                //透明度を変更するパネルのイメージ

	void Start() {
		fadeImage = GetComponent<Image>();
		red = fadeImage.color.r;
		green = fadeImage.color.g;
		blue = fadeImage.color.b;
		alfa = fadeImage.color.a;
	}

	void Update() {
		if (isFadeIn) {
			StartFadeIn();
		}

		if (isFadeOut) {
			StartFadeOut();
		}
	}

	void StartFadeIn() {
		alfa -= fadeInSpeed;                //a)不透明度を徐々に下げる
		SetAlpha();                      //b)変更した不透明度パネルに反映する
		if (alfa <= 0) {                    //c)完全に透明になったら処理を抜ける
			isFadeIn = false;
			fadeImage.enabled = false;    //d)パネルの表示をオフにする
		}
	}

	void StartFadeOut() {
		fadeImage.enabled = true;  // a)パネルの表示をオンにする
		alfa += fadeOutSpeed;         // b)不透明度を徐々にあげる
		SetAlpha();               // c)変更した透明度をパネルに反映する
		if (alfa >= 1) {             // d)完全に不透明になったら処理を抜ける
			isFadeOut = false;
		}
	}

	void SetAlpha() {
		fadeImage.color = new Color(red, green, blue, alfa);
	}
}

7.C♯スクリプトテンプレート

81-C# Script-NewBehaviourScript.cs.txtを編集することで、C♯スクリプトテンプレートを編集できるので便利。
以下は自分が使用している自作テンプレート。#regionと#endregionで挟むと、折りたためるので、確認することが多いメモや滅多に弄らないusinigなどは省略している。

#region
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.InputSystem;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
//using Sirenix.OdinInspector;//SerializedMonoBehaviourを使うのに必要
//using DG.Tweening;//DoTween使用時に必要
#endregion

#region
/* odinInspector用
Dictionaryもシリアライズ出来るように
[SerializeField]private Dictionary<string, int> _dict = new Dictionary<string, int>(){{"Key1", 1},{"Key2", 2}

編集できないように、プロパティまで表示
[ReadOnly,ShowInInspector]public Vector3 ShowInInspectorVector3{get;set;}

[LabelText("自由な名前に")]public string LabelTextTest = "LabelTextTest";

Indent (インデントの設定)[Indent(1)]public bool Indent1 = false; [Indent(2)]public bool Indent2 = false;

メソッドを実行するボタン[Button("押して!")]private void OnClick() {Debug.Log("押した!");}

BoxGroup(ボックスグループ化)[BoxGroup("グループ1")]public int A, B, C;
FoldoutGroup(フォルダーグループ化)[FoldoutGroup("グループ1")]public int A, B, C;
TabGroup(タブグループ化) [TabGroup("グループ1")]public int A, B, C;
*/
#endregion

#region
/*確認、コピペ用
private int a; //このスクリプトでしか使えない。インスペクタにも表示されない。
public int b; //他のスクリプトからもアクセスできる。インスペクタにも表示される。

[SerializeField]
private int c;//このスクリプトでしか使えないが、インスペクタには表示される。

[System.NonSerialized]
public int d; //他のスクリプトからもアクセスできるが、インスペクタには表示されない。

同じ型の変数であれば、カンマ区切りで連続で宣言できる
private float moveSpeed, waitTime, walkTime;
*/
#endregion

    #ROOTNAMESPACEBEGIN#
public class #SCRIPTNAME# : MonoBehaviour
{
    void Start()
    {
        #NOTRIM#
    }

    void Update()
    {
        #NOTRIM#
    }
}
#ROOTNAMESPACEEND#

いいなと思ったら応援しよう!