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

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

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

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

Unity

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

Q&A

解決済

1回答

11805閲覧

オブジェクトの移動中はキー入力を受け付けないようにしたい

YYGAME

総合スコア15

C#

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

Unity

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

0グッド

0クリップ

投稿2017/03/06 03:44

ユニティでキー入力をしたらオブジェクトを動かすスクリプトを書いています。

連続してキーの入力をすると予期せぬ動きをしてしまうので、オブジェクトが動いている最中はキー入力を受け付けないようにしたいです。

どのようなスクリプトを書いたらいいでしょうか。

よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

※僕はUnityやってないし、ゲームプログラマーでもないから参考程度に

現在のアクションの実行状態を何等かの形で管理しましょう。
複数通りの管理方法があると思います。

1.コルーチンで実行中受け付けないようにする

private bool IsDoingSomething; IEnumarator DoSomething() { if (IsDoingSomething) yield break; IsDoingSomething = true; animation.Play("DoSomething"); // 戻ってくる条件を返す。例えばアニメーションが終わるまで、とか。 yield return new WaitUntil(() => !animation.IsPlaying("DoSomething")); IsDoingSomething = false; }

コルーチンの停止について参照するといいでしょう。
http://tsubakit1.hateblo.jp/entry/2015/04/06/060608

コルーチン自体がまだよくわからない場合はこっちの情報を参照するといいかな。
https://cfm-art.sakura.ne.jp/sys/archives/419

ようはアクション中にもう一度実行依頼が来ても実行しないよー、という単純なスクリプトです。
欠点もあります。
先行入力や、アクション中に違うアクションにする、等がこのままだと実装しにくいことです。
ゼルダの伝説で箱を動かすぐらいの動作ならこれでも困らないと思います。

2.実行状態を厳密に管理する
アクション実行中、どこかに現在の状態を纏めて管理しておき、状態を参照して次のアクションを決定しましょう。
1の方法でいうところの、IsDoingSomethingをもっと具体的なクラスに状態としてまとめておき、次のアクションに利用します。

アクションの実行状態を複雑に管理する場合はこういう方法がどうしてもいると思います。

if (/*現在何も受け付けない状態なら*/) { return Action.None; } // 各入力の優先順に処理.. if (Input.GetButton("Attack")) { if (State.IsAttacking) { // 何もしない } else if (State.IsJumping) { return Action.JumpAttack; } else { return Action.Attack; } } // .. return Action.None;

#追記

コルーチンの呼び出し方がわからない、という意味でしょうか。
僕に書けるのはリファレンスから想像して書くぐらいですが

マニュアル通りだと、あるアニメーションの排他制御は以下のような形になると思います。

C#

1public class Sample : MonoBehaviour 2{ 3 private Animation animation; 4 private bool isRunning; 5 6 void Start() 7 { 8 animation = GetComponent<Animation>(); 9 } 10 11 void Update() 12 { 13 if (Input.GetKey(KeyCode.Space)) 14 { 15 StartCoroutine(Concurrent()); 16 } 17 } 18 19 private IEnumerable Concurrent() 20 { 21 if (isRunning) yield break; 22 23 isRunning = true; 24 25 animation.Play("Sample1"); 26 27 yield return new WaitUntil(() => !animation.IsPlaying("Sample1")); 28 29 isRunning = false; 30 } 31}

yield return で次にいつアクションを実行するのかを制御するようですから、例えば1秒かけて動作させるとかそういった条件を合わせて書いておくといいでしょう。

Updateメソッドは毎フレーム呼ばれますが、Concurrentが1度実行状態に入るとアニメーションが終わるまではyield return new WaitUntilを超えることができません。
そして、アニメーションが終わった後にフラグがfalseになる、という想定です。

投稿2017/03/06 08:07

編集2017/03/06 12:16
haru666

総合スコア1593

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

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

YYGAME

2017/03/06 08:40

丁寧な回答本当にありがとうございます。 現在オブジェクトを動かす際に、動いているときはflagをturuにして、処理が行われていない場合はflagをfalseにしています。 これらを使えば教えていただいた上の方法で書けるかなと思ったのですが、どこにどのように書いていいか分からず困っています。 ここまで丁寧に回答してくださったのに申し訳ありません。 もしよろしければもう一度ご教授のほど、よろしくお願いいたします。
haru666

2017/03/06 12:18

基本的には処理の入り口にif (flag) return; を追加して、直後にflag = true; 最後に flag = falseとかけばいいです。同時実行制御のガード句ですから。動かないとしたら、1フレーム内に全て処理が終わっており、flag が落ちてしまう場合です。
YYGAME

2017/03/10 06:00

遅くなり申し訳ありません 解決できました。丁寧な回答本当にありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問