偶発ゲーム開発

主にUnityでゲームを作ります。

UnityのMVPパターン、VisualScriptingとUnityEventの併用でメンドクササなくなる説

徒然なるままに無職のハツグウです。

タイトル通り、presenter一々定義すんのめんどくさいやんって

気持ちで試してみたもの。

 


public class Test : MonoBehaviour
{
   
    [SerializeField]
    private UnityEvent<string> _OnDisplay;
    [SerializeField]
    private int _HP = 0;

    public int HP { get => _HP; }



    // Start is called before the first frame update
    void Start()
    {
       
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown("a"))
           _OnDisplay.Invoke(_HP.ToString());
    }
}
こんな感じのモデルがあったとしまして、

public class CustomEventer<T> : MonoBehaviour
{
    [SerializeField]
    private string eventName;

    [SerializeField]
    private GameObject target;

    [SerializeField]
    private Graph graph;


    public void InvokeEvent(T arguments){
         CustomEvent.Trigger(target,eventName,arguments);
    }
}
こういうカスタムイベント起動用のスクリプトを用意します。

あとはインスペクタ―で登録して、VisualScripting側でごにょごにょViewにつないでやれば完成です。これだとほぼ(ジェネリッククラスの継承以外)コード書かずに対応できそうですね。可長変引数は設定できないので、複数の場合はジェネリックのパラメータを配列で宣言する必要があります。
 
ただこの場合、毎回VisualScriptを通過するので考えものですね…。VisualScriptingでもラムダ式みたいなことができればいいんだけど。
なまぐさプログラマなのでどのくらいの負荷がかかるとかはわかんないです……。以上。

ScriptableObjectのシリアライズしてない変数はビルド実行時に保持されない??

タイトルまんまですが、
UnityはDictionaryのシリアライズがデフォではできない…(Godotならできるのに!)

よって下記みたいにクラスを作ってからDictionaryに流し込んだりしなくてはいけない。

 [SerializeField]
    private List<Clip> clipList = new List<Clip>();
//インスペクタで設定

    private Dictionary<string, AudioClip> clipDic = new Dictionary<string, AudioClip>();


    [System.Serializable]
    public class Clip{

        [SerializeField]
        private string title;
        
        [SerializeField]
        private AudioClip audioClip;

        public string Title => title;
        public AudioClip AudioClip => audioClip;
    }//Dictionaryに流し込むクラスを定義

    private void OnValidate()
    {
        DictionaryUpdate();
    }//変数が変更されたらDictionaryを更新

    public Dictionary<string, AudioClip> GetDictionary() {
        
        return clipDic;
    }//Dictionaryを返す


    public void DictionaryUpdate() {
        clipDic = new Dictionary<string, AudioClip>();
        foreach (Clip clip in clipList) {
            clipDic.Add(clip.Title, clip.AudioClip);
        }//Dictionaryの更新
    }


しかしこのコード、エディタ上では動作するがビルド時だとDictionaryが空になってしまっている!

    public Dictionary<string, AudioClip> GetDictionary() {
        DictionaryUpdate();
        return clipDic;
    }//Dictionaryを返す

のようにランタイムで生成を行ってから返すことで動作するようになった。
ScriptableObjectはビルド時にインスペクタの値以外を保持してくれるわけではないっぽい。

でもランタイムでDictionary生成するってあんまりやりたくないよなぁ…。

なにか良い方法あればコメントでおしえてください。

2ちゃんネタのゲーム作って思った事。

unityroom.com

2ちゃんネタでゲーム作りました。開発期間1日。作業時間10時間程度。

下記開発して思ったこと学んだことなど。

 

・ゲデザで意識したこと

ただの連打ゲーなので特筆すべきことはないだけど、

今回はとにかく

何ができるのかを意識した。

連打をすると→ロケット飛ばせる

連打をはやくすると→ロケットを遠くまで飛ばせる

みたいなできる構文で作りはじめた。

これ先にやっとくと、ゲームの中身をつくるとき指針として役立ちかもしれない。

肝心のゲーム部分は練れなかったので、次回以降はそこも気を配りたい。

 

 

・UI要素のアルファ値の扱いや、フェードインアニメーションの重要

結局のところ、UIっていうゲーム世界とは分離された要素に如何に違和感を持たせないのにいいのかも!

アルファで透かすようにするのは視認の問題もあるけど、それ以上に画面内の絵となじんでる(違和感感じづらい)ように見えるのかなーとか。

あとフェードインアニメーションはアルファじゃなくても、横から流れてくるアニメーションとか、つながりを描くことで違和感を軽減できるんだなーと。

 

 

・段階やバリエーションの強力さ

各要素の品質が低めでも、バリエーションの多さや段階的な変化は効果を発揮しそうだ。マイクラとかもそうですね。

 

 

・内輪ネタのやりやすさ

元のネタがあるからその分らくかも。

 

 

・指数関数的なコストの増え方

多分仮に背景全部アニメーションでやったら倍の時間はかかっていた。

バリエーションはモロハの刃でもあるのかな…。

 

 

 

・プログラムの設計てきな

作ってる段階では(期間が短いのもあって)参照関係とかがぐちゃぐちゃになったり、一つのイベントに放り込みまくったり。

ただ、最初から気張って設計設計で作り始めると今までゲームが完成した記憶なし…。

イテレーションがまわせるなら、

短いゲーム(あるいはモック)を雑に作って遊ぶ→

その中でこれあると便利だな、組むの早いな、と思った機能をモジュール化していくと

回りやすいかな、と思った。

 

 

以上です。よかったら遊んでみてください。