前提・実現したいこと
「Updateと各ボタンのコールバック」しか実装していないコードで、
「一部処理をFixedUpdateに切り出す」等をせず、「早すぎない描画」と
「ある程度正確な入力受け取り」を実現する方法
発生している問題・エラーメッセージ
開発当初、Unityの「Updateの間隔」や「入力受け取り」について知らないままに
実装を始めてしまいました。
結果、現在の実装は各シーンごとに
・start()完了後に実行されるのは、updateと各ボタンのコールバック関数のみ
・updateでは「if(Input.GetMouseButtonDown(0))後に画面クリック時の処理」と
「毎フレームの計算処理(移動、カウンタ増加など)」を行っている
・コールバック関数では、各ボタンに対応した処理を書いている
と、updateに「入力受け取り」「定周期で行うべき計算」「描画」が混在してしまっています。
開発マシンでは不思議と「ちょうどいい速度」だったので、気にならなかったのですが
かなり形になってから別マシンで動かす機会があり、「Updateごとに移動などを行う」と
基本的に早すぎる、ということが(今更)判明しました。
「今からUpdateを修正し、入力以外の処理をFixedUpdateに切り出す」のも考えたのですが、
Update内は「入力受け取り」「定周期で行うべき計算」「描画」が相当強く相互に結びついてしまっており、下手に切り出すとバグの原因になりそうで、それは最終手段にしたいです。
下記のソースが、「とりあえずの現実解」として、今動かしている実装なのですが
何かアイデアや、逆に「〇〇××しないと、この実装は致命的な問題がある」など
ご意見があったら教えてください。
該当のソースコード
// 現在のコードであり、当初の実装ではありません
Unity
1 void Start () { 2 button[i].GetComponent<Button>().onClick.AddListener(() => OnButtonClick(index)); 3 } 4 5 void Update() { 6 if (Input.GetMouseButtonDown(0)) 7 { 8 // 今回「IsPassedInterval == false」になってUpdateを抜ける場合でも 9 // 「処理のインターバル中に画面はクリックした」という事実は保管しておかないと 10 // クリックが無かったことにされる可能性がある 11 isGamenClick = true;//isGamenClickはグローバル静的変数 12 } 13 if (!IsPassedInterval()) return; 14 if (cantSyoriCounter > 0) cantSyoriCounter--;//cantSyoriCounterはグローバル静的変数 15 if (isGamenClick)//当初はif(Input.GetMouseButtonDown(0)) 16 { 17 isGamenClick = false;//こうしないと次回Update時もコールされてしまう 18 ClickWindow();//画面クリック時の処理 19 } 20 // 以降、毎フレームごとの描画処理など 21 //(例)攻撃演出中 22 if (gameState == GAME_STATE_ATTACK) { 23 24 if (ensyutsuCounter <= 15) { 25 printDamage();//ダメージ量を表示 26 } 27 if (ensyutsuCounter == 10) { 28 targetHp -= damage;//ターゲットのHPを今回のダメージ分だけ減らす 29 } 30 ensyutsuCounter--; 31 if (ensyutsuCounter == 0) { 32 // 攻撃演出状態終了。初期状態に戻る 33 gameState == GAME_STATE_FIRST; 34 } 35 } 36 } 37 38 // 一定周期ごとにupdateの実質処理が行われるようにチェック 39 public static Boolean IsPassedInterval() 40 { 41 tempInterval += Time.deltaTime;//tempIntervalはグローバル静的変数 42 if (tempInterval > UPDATE_INTERVAL) 43 { 44 tempInterval = 0; 45 return true; 46 } 47 return false; 48 } 49 50 void OnButtonClick(int index){ 51 // ボタンを押された時の、カウンタの増加やゲーム内状態変数の変更など 52 if (cantSyoriCounter != 0) 53 { 54 return; 55 } 56 //ボタン押したときの処理(例) 57 if (gameState == GAME_STATE_ATTACKCHECK) {//攻撃決定するかの確認状態 58 gameState = GAME_STATE_ATTACK;//攻撃の演出に入る 59 ensyutsuCounter = 20;//20フレーム間、攻撃演出 60 cantSyoriCounter = 30;//連打で一気に進む防止のため 61 } 62 }
試したこと
まずは、上記のソースでの「IsPassedInterval」処理を追加しました。
が、それだけだと、「スキップされるupdate()」で拾った画面クリックが
いざ「スキップしないupdate()」が来た時に、無視されてしまうことに気づきました。
よってisGamenClickフラグを追加しました。
ボタンについては、cantSyoriCounterで「どんなに連打しても、
スキップしないupdateが30回呼ばれるまでは無視する」ようにしました。
思想としては、実装された処理の違いから
画面クリックは「クリックしたことを落とさないこと」重視、
ボタンクリックは「連打で一気に進まないこと」重視(cantSyoriCounterに引っかかって
無視されることがあるのは、大した問題ではないと判断)です。
補足情報(FW/ツールのバージョンなど)
Collision系の処理は使用していないので、気にしなくてよいです。
回答1件
あなたの回答
tips
プレビュー