見出し画像

Unityゲーム開発で絶対役立つ小ネタスクリプト集4


自作ミニゲーム(パリイと弾きを鍛えるトレーニング)の進捗
弾き+体幹ルールの操作や技を一通りこしらえた動画

タイトル画面+パリィ+スウェイを実装した動画。

その過程でできた、汎用的に使えるであろう自作スクリプトを紹介します。

UIValueLerpBar


普通のHPゲージ制御コードです。シンプルなHPバーのアセットが意外とストアにないので仕方なく自作しました。後追いで残像が減る演出付き。。

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

namespace FUNSET
{
	public class UIValueLerpBar : MonoBehaviour
    {
		[SerializeField]
		private int maxValue = 10000;
		[SerializeField]
		private int AfterValue;
		private int Value;
		// HPを一度減らしてからの経過時間
		private float countTime = 0f;
		// 次にHPを減らすまでの時間
		[SerializeField]
		private float nextCountTime = 0f;

        [SerializeField, Header("必須:lerpスライダー"), Tooltip("あとから減る演出用スライダー")]
        private Slider LerpSlider;
		[SerializeField]
		Color ColorLerpSlider;
		[SerializeField]
		Image Lerpbar;
        [SerializeField, Header("必須:スライダー"), Tooltip("実際の値を表示するスライダー")]
		private Slider bulkValueSlider;
		[SerializeField]
		Color ColorbulkValueSlider;
		[SerializeField]
		Image ValueBar;

        // 現在のダメージ量
        //private int damage = 0;
        [SerializeField]
		private int amountOfDamageAtOneTime = 100;

		private bool isReducing;
		// HP用表示スライダーを減らすまでの待機時間
		[SerializeField]
		private float delayTime = 1f;

		int preValue;
		int preAfterValue;


		public void Start()
        {
			Lerpbar.color = ColorLerpSlider;
			ValueBar.color = ColorbulkValueSlider;
			AfterValue = maxValue;
			Value = maxValue;
			LerpSlider.value = 1;
			bulkValueSlider.value = 1;
		}
        
		public void SetInitValue(int MaxValue,int Value)
        {
			maxValue = MaxValue;
			this.Value = Value;
			AfterValue = Value;
		}
        
        public void Update()
        {
			if (!isReducing){return;}

			if (countTime >= nextCountTime)
			{
				AfterValue = Value;
				LerpSlider.value = (float)AfterValue / maxValue;
				isReducing = false;
			}			
			countTime += Time.deltaTime;			
		}

        private void FixedUpdate()
        {
			if (preValue == Value) { preValue = Value;  return; }

			bulkValueSlider.value = (float)Value / maxValue;
		}

        // 外部からダメージを追加する
        public void TakeDamage(int damage)
		{
			Value = Mathf.Clamp(Value - damage, 0, maxValue);
			bulkValueSlider.value = (float)Value / maxValue;
			countTime = 0f;
			if (damage < 0)
			{
				AfterValue = Value;
				LerpSlider.value = (float)AfterValue / maxValue;
				isReducing = false;
			}
            else
            {
				Invoke("StartReduceHP", delayTime);
			}			
		}

		// 後からHPバーを減らすのをスタート
		public void StartReduceHP(){isReducing = true;}
	}
}


これを使うには、下の画像を参考に5つのUIパネルと2つのスライダーコンポーネントでHPバーのUIを作って、このスクリプトをRootにアタッチします。
※HPバーの枠の画像は、要る場合は別途用意してRootのImageに設定します

TakeDamage(int damage)のメソッドで、HPが増減します。(プラスでダメージ、マイナスで回復)後追いでlerpスライダーが減ります。

AnimetorParamController

アニメータに設定したパラメータを、(ある程度)GUIやイベントで直接操作できます。アニメータの操作の窓口を目立つ場所に置いて一本化することで、キャラ操作などのプログラムの流れが追跡しやすくなるかもしれません。

using UnityEngine;

namespace FUNSET
{
    /// <summary>
    /// アニメーターのパラメータを気軽に操作する。
    /// </summary>
    public class AnimetorParamController : MonoBehaviour
    {
        [SerializeField, Header(""), Tooltip("このコンポーネントはアニメーターと同じ場所にあるべき")]
        Animator animator;

        public enum ParamType { Bool, Int, Float, Trigger }

        [System.Serializable]
        public class ParamProperty
        {
            [SerializeField, Header("パラメータ名"), Tooltip("")]
            public string ParamName;
            public int ParamHash;
            public ParamType paramType;
            
        }

        [SerializeField, Header(""), Tooltip("")]
        ParamProperty[] Parametors;


        private void Start()
        {
            if (animator == null) { animator = gameObject.GetComponent<Animator>(); }

            for (int i = 0; i < Parametors.Length; i++)
            {
                Parametors[i].ParamHash = Animator.StringToHash(Parametors[i].ParamName);
            }
        }



        public void SetParamBoolOn(int ID)
        {
            if (Parametors[ID].paramType == ParamType.Bool) { animator.SetBool(Parametors[ID].ParamHash, true); }   
        }

        public void SetParamBoolOff(int ID)
        {
            if (Parametors[ID].paramType == ParamType.Bool) { animator.SetBool(Parametors[ID].ParamHash, false); }
        }  
        public void SetParamBool(int ID,bool a)
        {
            if (Parametors[ID].paramType == ParamType.Bool) { animator.SetBool(Parametors[ID].ParamHash, a); }           
        }

        public void SetParamInt(int ID,int a)
        {
            if (Parametors[ID].paramType == ParamType.Int) { animator.SetInteger(Parametors[ID].ParamHash, a); }
        }

        public void SetParamFloat(int ID,float a)
        {
            if (Parametors[ID].paramType == ParamType.Float) { animator.SetFloat(Parametors[ID].ParamHash, a); }
        }


        public void SetParamTrigger(int ID)
        {
            if (Parametors[ID].paramType == ParamType.Trigger) { animator.SetTrigger(Parametors[ID].ParamHash); }
        }
    }
}


アニメータにあるパラメータの名前と種類をParametorsに登録し、その要素数=IDを覚えておいて
SetParamBoolOn(int ID),、SetParamBoolOff(int ID)、SetParamTrigger(int ID)
をGUIボタンなどにセットすれば、手軽に操作できます。
SetParamInt(int ID,int a)とか引数が2つあるのはスクリプトでのみ呼び出せます。
※SetParamBoolOn(string ParamName)みたいにパラメータ名で呼び出せるほうが直感的と思ったのですが、文字入力の手間やタイプミスのリスクが発生したためメリット少ないのでは?となったのでやめました)

SEPut

実行時に連続した短い効果音を出すのに作りました。(名前適当すぎた)
連続ヒットする打撃音などの短時間で連発される効果音を一つのオーデイオソースにPlayoneshot()で出そうとしてもできないので、オーデイオソースごとプレハブにしてシーンに生成する必要があります。

using UnityEngine;

namespace FUNSET
{
    [RequireComponent(typeof(AudioSource))]

    public class SEPut : MonoBehaviour
    {
       
        AudioSource audioSource;
        AudioClip[] SE_Random;

        public float DestroyTimer = 4f;
        float Destroycount;
        
        public void Awake()
        {
            audioSource = gameObject.GetComponent<AudioSource>();
        }
        
        public void Start()
        {  
            if ((audioSource != null) && (SE_Random.Length > 0))
            {
                //audioSource.clip = SE_Random[Random.Range(0, SE_Random.Length)];audioSource.play;
                audioSource.PlayOneShot(SE_Random[Random.Range(0, SE_Random.Length)]);
            }
        }
        
        public void Update()
        {
            Destroycount += Time.deltaTime;
            if (Destroycount > DestroyTimer) Destroy(gameObject);
        }        
    }
}


このスクリプトを空オブジェクトにアタッチするとオーデイオソースコンポーネントを自動で取り付けます。SE_Randomに鳴らしたいオーデイオクリップを登録してプレハブ化します。
実行時にinstantiate()で生成するとSEのうちどれかをランダム再生し、一定時間で自身のオブジェクトを削除します。


この記事が気に入ったらサポートをしてみませんか?