タワーディフェンス型?ゲームを作ってみる【Unity,DoozyUI,Odin】

(2021/3/9 修正) こちらのオンライン版は作成しないことにしました. 記事のタイトルを変更しました

Demo

www.youtube.com

公開場所

t.co

開発環境

どんなゲームを作る?

何事も簡単なゲームからやっていきましょう
複雑にするとわからなくなっていきます.

(作成中なので,どんどん変わっていきます) ←ここ重要

以下のようなゲームを作っていきたいと思います.
(図の適当は気にしないでください) f:id:ayousanz:20201207222705j:plain

  • ひたすらボスを殴る
  • チャットができたらうれしい
  • アニメションもつけたい
  • HPだけオンラインで共有

簡易アニメションの実装

アタック,ダメージ

f:id:ayousanz:20201207224105g:plain

上のような動きを作成します.

  • アタック:前に移動後,元の位置に戻る
  • ダメージ:後ろに移動後,元の位置に戻る

アタックとダメージのアニメションの実装はほぼ同じです

public void Attack(int attack value)
    {
        transform.DOMoveX(-1f,0.5f).SetRelative(true)
            .OnComplete(() =>
            {
                transform.DOMoveX(1f, 0.5f).SetRelative(true);
            });
    }

スタート画面とゲーム画面の切り替えの実装

以下のような画面の切り替えを行っていきます.

使用アセットはOdinを主に使っています.

f:id:ayousanz:20201208021714g:plain

Odinの設定

まずは使用するViewを作成します. f:id:ayousanz:20201208022011p:plain

で,スタート画面からゲーム画面に移行するためのボタンも作成します f:id:ayousanz:20201208022059p:plain

次にgraphを作成します.

f:id:ayousanz:20201208022130p:plain

OdinのViewが Show,Hideされるときのアニメションはそれぞれ以下のように設定しています. f:id:ayousanz:20201208022237p:plain

プレイボタンのアニメション

こんな感じにスタートを強調?する感じのアニメションをつけています. f:id:ayousanz:20201208024155g:plain

しっかり使わなくなったタイミングでDOTweenをKillしてあげましょう

private void GameStartLogo()
    {
        playButton.transform.DOScale(0.05f, 1f)
            .SetRelative(true)
            .SetEase(Ease.OutQuad)
            .SetLoops(-1, LoopType.Yoyo);
    }

private void OnDisable()
    {
        _tweener.Kill();
    }

敵データの作成

ayousanz.hatenadiary.jp

参考サイト

unity-yuji.xyz

Fadeで出現・消滅するshieldの実装

Demo

f:id:ayousanz:20201213181152g:plain

実装内容

DOTween のSequenceを再利用するときは 以下を使います

Sequence生成時

.SetAutoKill(false)
.SetLink(gameObject);

Sequence実行時

tweener.Restart();

(注)参考サイトでは,.Pause() を入れていますが,私の場合DOTweenの初期化の時に DOTween.defaultAutoPlay = AutoPlay.None で自動スタートをoffにしているので,入れていません.

以下アニメーションの実装部分のスクリプトです

public void Guard(bool guard action)
    {
        if (guardAction)
        {
            var guardStartSequence = DOTween.Sequence()
                .OnStart(() =>
                {
                    _isGuard = true;
                    PlayerStatus.Mp -= PlayerStatus.GuardCost;
                })
                .Append(shieldSpriteRenderer.DOFade(1f, 0.5f))
                .SetAutoKill(false)
                .SetLink(gameObject);
            guardStartSequence.Restart();
        }
        else
        {
            var guardEndSequence = DOTween.Sequence()
                .Append(shieldSpriteRenderer.DOFade(0f, 0.5f))
                .OnComplete(() =>
                {
                    _isGuard = false;
                })
                .SetAutoKill(false)
                .SetLink(gameObject);
            guardEndSequence.Restart();
        }
    }

DOTweenのSequenceを使いまわすときの注意点(2020/12/15 追記)

あれこれ2,3時間悩んでいたのですが,多分あっているはずです

Sequenceを使いまわすときとは PrependCallback を使いましょう

参考サイト

qiita.com

特定の条件でメッセージを表示する

Demo

f:id:ayousanz:20210103234826g:plain

実装方法

BoolReactiveProperty を使用してTrueになったときにアニメーションが実行されるようにしています.

private readonly BoolReactiveProperty _isMessageInfoShow = new BoolReactiveProperty();

 public void Initialize()
    {
        _isMessageInfoShow.Value = false;

        _isMessageInfoShow.Where(x => x).Subscribe(_ =>
        {
            _messageInfoSequence.Restart();
        }).AddTo(this);
    }

敵の攻撃タイミングを可視化する (2021/1/9追記)

Demo

f:id:ayousanz:20210109155734g:plain

実装方法

UniRxの Observable.Interval を使うと数行できてます

時間をカウントするところは以下

Observable.Interval(TimeSpan.FromSeconds(0.1f))
            .Where(_=> !_playerController.IsMove.Value && !_enemyController.IsMove.Value)
            .Subscribe(_ =>
            {
                _enemyActionTime += 0.1f;
                _enemyController.SetEnemyAttackTimeSlider(_enemyActionTime);
                if (_enemyController.AtkInterval < _enemyActionTime)
                {
                    Damage();
                    _enemyActionTime = 0f;
                }
            }).AddTo(this);

スライドの値を変化しているのは以下

public void SetEnemyAttackTimeSlider(float time)
    {
        enemyAttackTime.value = AtkInterval - time;
    }

使用しているアセット

assetstore.unity.com

assetstore.unity.com

assetstore.unity.com

assetstore.unity.com

assetstore.unity.com

assetstore.unity.com

使用している素材

フォント

moji-waku.com

戦闘背景画像

pipoya.net