見出し画像

ダンスゲーを作りたい#41 【試作】プレイシステムの基盤その3(タイマーとスコアとプレイフロー変更)

前回までで「わー踊ってるー」まではいけましたが、重大な問題に気づきました。

ダンスバトルで一曲丸々踊れるのはジャッジムーブくらいでダンスバトルには制限時間があります。

そして開始したらいきなり踊り出すわけではありません。

先攻後攻は自由に取り合って、曲の好きなタイミングでスタートし、好きなタイミングで終了して終了したらそれを合図に次が踊るのです。

よって、ただ曲を流しても踊れないわけです。

そこで、タイマー作っておかないといけないですね。関連して、スコア算出までの大枠も作っておきましょう。

タイマー

単に時間を図るならストップウォッチ(以下sw)でいいと思われます。

せっかくなのでUIと連携するコンポーネントを作成します。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System.Diagnostics;
using DG.Tweening;

public class GameTimer : MonoBehaviour{
   public GameObject Object;
   Text Text;
   Stopwatch sw;
   public int LastTime{
       get{
           if(isCounting){ 
               return MaxTime-(int)(PastTime/1000);
           }else{
               return -1;
           }
       }
   } //残り何秒か[秒] 主に表示用
   public float PastTime{
       get{
           if(isCounting){
               return sw.ElapsedMilliseconds;
           }else{
               return 0;
           }
       }
   } //経過時間[ミリ秒]

   int MaxTime ; //最大何秒計測するか
   int CountDown; //カウントダウンはどこからするか
   int _CDADP;//カウントダウン判定用のAdapter変数
   bool isCounting;
   string EndText="Fin";

   /*タイマーをスタート*/
   public void TimerStart(int MaxTime,int CountDown,string EndText){
       sw = new Stopwatch();
       Text = Object.GetComponent<Text>();
       Text.fontSize = Tool.SetFontSize(Object.GetComponent<RectTransform>().sizeDelta.y);
       this.MaxTime=MaxTime;
       this.CountDown=CountDown;
       this._CDADP=CountDown;
       this.EndText=EndText;
       sw.Start();
       isCounting=true;
   }
   /*タイマーを終了*/
   public void TimerEnd(){
       Text.text = EndText;
       isCounting=false;
       sw.Stop();
   }
   void CountDownAnimation(){
       Text.DOFade(0,0f);
       Text.DOFade(1,0.4f);
   }
   void Update(){
       if(LastTime==0){
           TimerEnd();
       }
       if(isCounting){
           Text.text = LastTime.ToString();
       }
       if(LastTime<=CountDown&&_CDADP==LastTime){
           _CDADP-=1;
           CountDownAnimation();
       }
       
   }
}

時間を表示できればいいのでクソ雑ですがまぁいいでしょう。

GetComponent<GameTimer>().TimerStart(5,3,"計測終了");

これで上記みたいにして残り時間と計測時間を入力すると勝手テキスト表示してカウントダウンエフェクトも出してくれる子ができました。

画像2

よくあるスクリプト本来の使い方感あってなんかいいですね。

ローディング画面が止まってないのでUIスレッドは生きてる状態で動いてることも確認できました。当たり前ではありますが。

スコアマネージャ

そもそもですが、プレイ中にスコア算出するのはお門違いで、実際のダンスバトルでもムーブ中のダンサーへのフィードバックは観客の沸きとか程度で、それは"Scoreに絡む"ことはあれどScoreそのものではないです。

そのためプレイ中は入力を記録して、終了後にスコア算出する流れが正解です。

以前仮で作った際もそうしてましたが、いったん離れてる間に記憶から消えてました。備忘録の大事さが身に沁みますね。

以前のものを参考に単純な入力情報の型枠を作成しましょう。

1プレイ情報として以下のような形状を考えます。

画像2

入力情報はタイミングデータと入力ボタンデータがあればOKです。

これらの情報を取得し、プレイデータとしてまとめるマネージャを暫定的にスコアマネージャと命名しておくことにし、Score自体の算出、記録はサーバで行います。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class InputData{
   public InputData(int BTNo,float MusicTime){
       this.BTNumber=BTNo;
       this.Timing=MusicTime;
   }
   public int BTNumber;
   public float Timing;
}
public class ScoreManager : MonoBehaviour{
   /*
   Score算出にあたって欲しい情報はStart時に受け取る
   */
   List<InputData> InputData;
   public void StartScoreManager(){
       InputData=new List<InputData>();
   }
   public void SetInput(InputData inputData){
       InputData.Add(inputData);
   }
   public void EndScoreManager(){
       //データをサーバ経由で照合し保存
   }
}

こんな感じ?

インプットは受け取れてるので、後はサーバに送って認証するだけって感じでしょうね。

最終形態

以前作った画面に若干の変更を加えて、Play開始時のカメラ位置を変更し、キャラモデルを2体にして、ボタン領域にムーブ開始ボタンを設置し、ムーブ開始したらカメラが移動してタイマーがスタート、タイマーが終了したら元に戻るという流れを作りました。

画像3

あんまり長いとgifが入りきらないのでプレイ時間短くしてますがこんな感じのイメージです。

この裏では入力したボタンが記録されてる状態なので、終了時にサーバ経由でscoreにしてもらう処理が入ります。

直近やるべきこととしてはCPUをつくる必要がありそうです。

CPUはユーザと同じ操作手順をいい感じにやってくれるようになればそれでOKですが、果たしてCPUのAIってどうやって作るもんなのか。という問題があります。AIって言うけどたぶんAIではないんじゃないんですか?知らんけど。

そこまでいけば、サーバ経由でスコアを取得して表示させればリザルト画面に遷移できる見込みです。

いよいよダンスゲーになってきました。

次回はとりあえず調整できるCPUを検討していくことにしましょうか。

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