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

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

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

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

2回答

14400閲覧

Unity 特定のキーやジョイスティックの入力を一時的に無効化する方法がわかりません

avonavonavon

総合スコア15

C#

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

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

1クリップ

投稿2018/12/04 19:39

前提・実現したいこと

unity、c#でやっています。 
例えばGキーを押してから1秒間Tキーが入力できなくなる、という風にするにはどうすればいいでしょうか? 
自分で調べてみた範囲ではキー入力をDisableにするような方法がわからなかったのでこちらで質問させていただきます。
サンプルのコードなどいただけるとありがたいです。

 

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

ソースコード

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

ベストアンサー

Gキーが押されたときに1秒後の時刻を求めて、現在時刻がその時刻を過ぎるまでTキーやジョイスティックの読み取りを行わないというのはどうでしょうか。

C#

1 // Gキーが押されたら... 2 if (Input.GetKeyDown(KeyCode.G)) 3 { 4 // 現在から1秒後の時刻を覚えておく 5 this.timeToEnableInputs = Time.time + 1.0f; 6 Debug.Log("G"); 7 } 8 9 // 現在時刻が覚えておいた時刻に満たなければ、入力読み取りをスキップするようにする 10 // 時間によって無効化したい入力読み取りは、このifブロックの中に入れる 11 if (Time.time >= this.timeToEnableInputs) 12 { 13 if (Input.GetKeyDown(KeyCode.T)) 14 { 15 Debug.Log("T"); 16 } 17 18 var stick = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")); 19 if (stick.sqrMagnitude > 0.01f) 20 { 21 Debug.Log(stick); 22 } 23 }

#追記
そのようなケースはMMashiroさんの方針がおすすめですね。個々のスクリプトが直接Inputクラスから入力情報を得るのではなく、Inputクラスと似たような使い勝手で入力情報を取得できる入力仲介クラスを用意して、他のスクリプトはInputの代わりにそこから入力を取得するよう書き換えてはいかがでしょう。

イメージをつかむためのシンプルな例ですと、たとえば下記のようなstaticクラスを作り...

C#

1using UnityEngine; 2 3public static class CustomInput 4{ 5 private static float timeToEnableInputs; 6 7 public static void DisableInputs(float time) 8 { 9 timeToEnableInputs = Time.time + time; 10 } 11 12 public static float GetAxis(string axisName) 13 { 14 return Time.time >= timeToEnableInputs ? Input.GetAxis(axisName) : 0.0f; 15 } 16 17 public static bool GetKeyDown(KeyCode key) 18 { 19 return (Time.time >= timeToEnableInputs) && Input.GetKeyDown(key); 20 } 21}

他のスクリプトはInputの代わりにCustomInputを使うというルールを定めれば、CustomInputの作り方次第でさまざまな独自の振る舞いをさせることができるはずです。

下記CustomInputTestの場合、最初に例示しましたコードと異なり、こちらのクラスでは時刻の判定が記述されていない点にご注目ください。時刻の判定はCustomInputに任されており、CustomInput.DisableInputsで設定した時間が経過するまで常にCustomInput.GetKeyDownfalseCustomInput.GetAxis0.0fとなります。

C#

1using UnityEngine; 2 3public class CustomInputTest : MonoBehaviour 4{ 5 private void Update() 6 { 7 if (CustomInput.GetKeyDown(KeyCode.G)) 8 { 9 CustomInput.DisableInputs(1.0f); 10 Debug.Log("G"); 11 } 12 13 if (CustomInput.GetKeyDown(KeyCode.T)) 14 { 15 Debug.Log("T"); 16 } 17 18 var stick = new Vector2(CustomInput.GetAxis("Horizontal"), CustomInput.GetAxis("Vertical")); 19 if (stick.sqrMagnitude > 0.01f) 20 { 21 Debug.Log(stick); 22 } 23 } 24}

もっと複雑な振る舞いをさせたい場合、MMashiroさんの言及されているシングルトン方式が役に立つかもしれません。シングルトン方式ではシーン上にゲームオブジェクトを一つだけ作成し、そこでUpdateやコルーチンを走らせることも可能になるでしょう。
ちょっといい例が思いつきませんが、少し複雑な時間的制御を必要とする処理...文字入力時のキーリピートのような、キーダウン直後に1回true、一呼吸置いてtrueが連打される...なんて挙動も実装できそうな気がします。

投稿2018/12/04 21:01

編集2018/12/05 12:18
Bongo

総合スコア10807

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

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

avonavonavon

2018/12/05 02:30 編集

ご回答ありがとうございます!早速以下のように試してみたのですが、エラーが出てしまいました。 using System.Collections; using System.Collections.Generic; using UnityEngine; public class NewBehaviourScript : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { // Gキーが押されたら... if (Input.GetKeyDown(KeyCode.G)) { // 現在から1秒後の時刻を覚えておく this.timeToEnableInputs = Time.time + 1.0f; Debug.Log("G"); } // 現在時刻が覚えておいた時刻に満たなければ、入力読み取りをスキップするようにする // 時間によって無効化したい入力読み取りは、このifブロックの中に入れる if (Time.time >= this.timeToEnableInputs) { if (Input.GetKeyDown(KeyCode.T)) { Debug.Log("T"); } var stick = new Vector2(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical")); if (stick.sqrMagnitude > 0.01f) { Debug.Log(stick); } } } } ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー ↓エラー内容です /Users/XXX/Downloads/UNITY Projects/XXX/Assets/My Scripts/NewBehaviourScript.cs(18,18): Error CS1061: 'NewBehaviourScript' does not contain a definition for 'timeToEnableInputs' and no extension method 'timeToEnableInputs' accepting a first argument of type 'NewBehaviourScript' could be found (are you missing a using directive or an assembly reference?) (CS1061) (Assembly-CSharp) timeToEnableInputsが引っかかっているようなのですが、どうしたらよいでしょうか?
MMashiro

2018/12/05 02:31

timeToEnableInputs はメンバ変数として自分で定義してください (既存で用意されている変数ではありません)
Bongo

2018/12/05 03:36

MMashiroさん補足ありがとうございます。 ご説明いただいた通り、「public class NewBehaviourScript : MonoBehaviour {」の次の行あたりにでも「float timeToEnableInputs;」を追加願います...
avonavonavon

2018/12/05 04:47

基礎的なところをすみません、お二方ともありがとうございます。  改めてスクリプトを見直してみてみたのですが、これってつまりキー入力そのものを無効にしているわけではなく、処理を1秒間スキップしてる感じですよね? Gキーの入力とTキーの入力を別のスクリプトで扱わなければならない場合、どうすればよいのでしょうか?
avonavonavon

2018/12/06 03:03

追記ありがとうございます。丁寧に説明してくださって恐縮です。 添付してくださったスクリプトで動くには動いたのですが、TキーだけでなくGキーも一秒間押せなくなってしまいます。Tキーだけ押せなくすることはできませんか?  CustamInputの ーーーーーーーーーーーーーー public static bool GetKeyDown(KeyCode key) { return (Time.time >= timeToEnableInputs) && Input.GetKeyDown(key); } ーーーーーーーーーーーーーーーーー ↑この辺りをいじればいいのかな?と思ってみたのですが、どうにもわかりません。
Bongo

2018/12/06 03:27

Gキーだけ通常のInputを使う手もあるでしょうが、せっかく決めた「入力読み取りはCustomInputを使う」というルールを早速破ることになってしまいますね。 では、入力無効化を無視するオプションを加えてみましょうかね? public static bool GetKeyDown(KeyCode key, bool ignoreDisabling = false) { return ((Time.time >= timeToEnableInputs) || ignoreDisabling) && Input.GetKeyDown(key); } とでもしておいて、Gキーの入力読み取り部分だけ... if (CustomInput.GetKeyDown(KeyCode.G, true)) { CustomInput.DisableInputs(1.0f); Debug.Log("G"); } としてみてはいかがでしょう。すみませんが今はUnityが手元になく、携帯電話から入力していますので、うっかり打ち間違いがあるかもしれませんのでご注意ください。
guest

0

Unity側にはキーボード入力の受付を一時的に止めるということは基本的にできません

また入力処理を複数スクリプトから行うというのはあまりよくない設計です
今回のような問題も起きやすい上、
規模が大きくなってきたときに複数個所に入力処理があると追跡が困難になる等々拡張性に欠ける為です

しかしそういった仕様にする場合はInputManager的なクラスを用意し、
両クラスから単一の変数にアクセス可能な仕組みを用意する必要があります。

そういった仕組みの例

  1. static変数
  2. Singletonパターン

追記

海外のフォーラムでstatic変数を用いた例がありました、参考にしてみてください
https://answers.unity.com/questions/1275232/disable-all-inputs.html

投稿2018/12/05 05:23

編集2018/12/05 05:29
MMashiro

総合スコア2378

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問