質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

1回答

1130閲覧

音楽ゲームで判定処理の有効範囲を拡大したい

tuna-uniko

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2020/11/17 07:11

編集2020/11/18 12:35

音楽ゲーム関係で、判定処理の方法についてお聞きしたいです。
音符ごとに決まったタイミング(例:曲開始から6.0秒)と曲開始から経過した現在時刻を比較し、その差から判定処理を行うようプログラムしているのですが、現在使用しているもの(以下に示します)から「Mathf.Absによる絶対値<=(各音符のタイミング)」や「(各音符のタイミング)プラスマイナス〇秒と現在時刻を比較」での処理にし、一定範囲内で音符の処理を行えるようにしたいと考えています。しかしながらこれらスマートな形式にしたくとも、後述するエラーなどによって上手くいきません。

###使用中のコード

Unity

1if (notetim - timer<=-0.05 /*下限*/ && notetim -timer>=-0.1 /*上限*/){ 2// notetim:音符ごとに決められた時間(-1.6していません) 3// 追記 2020/11/18:notetimは音符ごとに決められた時間です。 4// -1.6しているのは音符生成をする別のスクリプト内に使用している変数で、 5// 判定ラインの中央に来るよう-1.6しています。 6// timer:曲開始からの経過時間です 7 //ここでパーフェクト/ミス判定を行います 8}

##エラーなど
これで一応は動くのですが、ごく狭い範囲でしか判定されず極端に厳しい判定になってしまいます。ラインの中央から若干遅れているのはいいのですが、判定エリアそのものをかなり広く取りたいため上側にこの判定範囲を拡大したいと思っています。そこでそのために上限の数値を変更するとこのごく狭いエリアごと上下に動いてしまい、範囲を広げることができません。
また「それなら先に下限を決めておいて後からif文で上限を決めればいいか」と思い先に下限の位置を設定したのですが、Destroy関数の場所で範囲外としてエラーが出ています。これに関連して、この特定範囲から外れた時にミスを返し音符を消す処理を足したときも同じ現象が起きています。

##実現したいこと
if文の中身を変更し、本来のタイミングからプラスマイナス〇秒の間にボタンを押すと判定処理を返す処理で、広い判定エリアを作りたいです。

使用環境 Unity2019.1.51f VisualStudio

追記(2020/11/18)
変数の説明が間違っていたため、該当部分の追記と修正を行いました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2020/11/17 07:32

なにが問題なのかはイマイチわかりません 提示のコードでだめな理由は何でしょうか また、エラーが出るならエラーメッセージを提示しましょう
tuna-uniko

2020/11/17 07:48

音符の縦の長さ(仮に5とします)より少し広い判定エリア(6ほど)にしたいのですが、それよりも非常に狭い長さ(約0.5)でしか判定されない点です。緩い判定のゲームにしたいため、この非常に狭くなっている判定範囲を広げたいです。 私自身上限と下限を設定しその中で判定を行うという形のつもりで書いているのですが、上限か下限どちらかを書き換えるとこの狭いエリア全てが上下に動いてしまいエリアが広くなるようなことがありません。 その他には、判定エリアの外に出たらその音符を消す処理を追加した時、 ArgumentOutOfRangeException: Argument is out of range. Parameter name: index というエラーが曲再生開始の前から出ており、それの出ている場所がDestroy関数のある場所になっています。
guest

回答1

0

ベストアンサー

「notetim:音符ごとに決められた時間-1.6」→ここの計算要らなくないですか?

まずは有効範囲を変数で示します。(以下は遅い方の許容値が大きい例)
パーフェクトは「音符ごとに決められた時間」が基準、OKは「パーフェクトの下限・上限が基準」と考えます。

  • パーフェクトの下限perfectMin:-0.1
  • パーフェクトの上限perfectMax:+0.2
  • OKの下限okMin:-0.2
  • OKの上限okMax:+0.4

これをコードにします。
timerは現在時刻、noteは「音符ごとに決められた時間」です。
「現在時刻が"音符ごとに決められた時間"を元にした各下限・上限内ならばいい」のでこうなります。

C#

1if (note + perfectMin < timer && timer < note + perfectMax) { 2 // パーフェクトの時の処理 3} else if (note + perfectMin + okMin < timer && timer < note + perfectMax + okMax) { 4 // OKの時の処理 5} else { 6 // ミスの時の処理 7}

例えばnote=6、timer=6.3の場合、
(5.9 < 6.3 && 6.3 < 6.2)はfalseなのでパーフェクトではない。
(5.7 < 6.3 && 6.3 < 6.6)はtrueなのでOK範囲内、となるので想定通りの動きになるかなと思います。
あとは値を調整して許容範囲が広くなるようにすればいいです。


Destroyのエラーは「配列内にそんな番号の項目は無いよ」というエラーなので、
音符群を読み込む前(=配列内にデータを入れる前)に消そうとしているとか、
配列内の要素の個数以上の要素を消そうとしているとかが原因ではないかと思います。
エラー文でググれば色々情報が出るので上記と合わせて確認してみてください。(それでも分からなければ該当部分のコードを記載してください)

投稿2020/11/18 01:29

編集2020/11/18 01:30
sakura_hana

総合スコア11427

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tuna-uniko

2020/11/18 12:44

sakura_hana様 回答ありがとうございます。おかげさまで理想の判定エリアを実装できただけでなく、のちに実装しようと考えていたパーフェクトとミスの間の判定を追加実装できました。またnotetimの説明が間違っていたため追記修正させていただきました(2020/11/18)。 Destroy関数についてもおっしゃる通りで、else文のみで実装したためにエラーを起こしているようでした。そのため教えてくださったnum+perfectMin+okMinを過ぎたタイミングでミスにしDestroyを呼ぶようにしたところ、エラーが消えて正常に動作しました。 教えていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問