【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#