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

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

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

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

Unity

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

Q&A

解決済

2回答

9482閲覧

[Unity 2D]キャラが攻撃中に動かなくする方法を教えてください。

nya3720197

総合スコア12

C#

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

Unity

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

0グッド

4クリップ

投稿2018/12/27 08:34

#[Unity 2Dゲーム]キャラクターが攻撃中に動かなくする方法を教えてください。
現在色んなサイトを拝見してキャラクターの移動と攻撃は作成できたのですが、
攻撃のアニメーション実行中にもキャラクターが移動してしまいます。

色々初心者の自分なりに考えたのですが、挙動が不安定になってしまうので改善できないままに…
改善策を教えてください。

一応コードも載せてみましたがわかりにくくてすいません…

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Controller : MonoBehaviour 6{ 7 Animator animator; 8 Rigidbody2D rb2d; 9 public float Speed = 10f; 10 float Scroll = 0f; 11 bool Attack = false; 12 string State; 13 string SaveState; 14 void Start() 15 { 16 rb2d = GetComponent<Rigidbody2D>(); 17 animator = GetComponent<Animator>(); 18 } 19 void Update() 20 { 21 GetKey(); 22 ChangeState(); 23 ChangeAnimation(); 24 Move(); 25 } 26 void GetKey() 27 { 28 if (Input.GetMouseButtonDown(0)) 29 { 30 Attack = true; 31 } 32 else if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow)) 33 { 34 Scroll = 1f; 35 } 36 else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow)) 37 { 38 Scroll = -1f; 39 } 40 else 41 { 42 Scroll = 0; 43 } 44 } 45 void ChangeState() 46 { 47 if (Attack == true) 48 { 49 State = "Attack"; 50 } 51 else if (Scroll != 0) 52 { 53 State = "Run"; 54 } 55 else 56 { 57 State = "Stop"; 58 } 59 } 60 61 void ChangeAnimation() 62 { 63 if (SaveState != State) 64 { 65 switch (State) 66 { 67 case "Stop": 68 animator.SetBool("Run", false); 69 animator.SetBool("Stop", true); 70 animator.SetBool("Attack", false); 71 break; 72 73 case "Run": 74 animator.SetBool("Stop", false); 75 animator.SetBool("Attack", false); 76 animator.SetBool("Run", true); 77 break; 78 79 case "Attack": 80 animator.SetBool("Run", false); 81 animator.SetBool("Stop", false); 82 animator.SetBool("Attack",true); 83 84 break; 85 } 86 } 87 Attack = false; 88 SaveState = State; 89 } 90 void Move() 91 { 92 rb2d.velocity = new Vector2(Scroll * Speed, rb2d.velocity.y); 93 } 94}

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

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

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

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

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

guest

回答2

0

ベストアンサー

【回答 1】 ← 取り消します。失礼しました。
実際に動かして確認できていませんが、取り急ぎ。
変数 Scroll の値で移動量を決めているなら、攻撃中はその値を0にしておけばよいのではないでしょうか。
~~ void ChangeState()~~
~~ {~~
~~ if (Attack == true)~~
~~ {~~
~~ State = "Attack";~~
~~ Scroll = 0; // 攻撃中は Scroll = 0 にして移動させない~~
~~ }~~


【回答2】
あらためて回答します。さきほどは失礼しました。
考え方は nya3720197 さんの回答と同じで、攻撃中は入力を受け取らないというものです。
コードが質問者さんのものではなく自分流になってしまいましたが、ご参考まで。

メインのスクリプトはこちら。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class SkeltonController : MonoBehaviour 6{ 7 [SerializeField] float speed; 8 [SerializeField] Rigidbody rb; 9 [SerializeField] Animator anim; 10 11 private float inputH, inputV; 12 private bool mouseClick = false; 13 14 private void Update () 15 { 16 // 攻撃モーション中なら入力を受け取らない 17 if ( anim.GetBool ( "Attack" ) == true ) return; 18 19 // 各種入力を受け取る 20 inputH = Input.GetAxis ( "Horizontal" ); 21 inputV = Input.GetAxis ( "Vertical" ); 22 mouseClick = Input.GetMouseButtonDown ( 0 ); 23 } 24 25 private void FixedUpdate () 26 { 27 if ( mouseClick ) // マウス左クリックで攻撃 28 { 29 anim.SetBool ( "Attack", true ); 30 anim.SetBool ( "Walk", false ); 31 return; 32 } 33 34 if ( inputH == 0 && inputV == 0 ) // 待機 35 { 36 anim.SetBool ( "Walk", false ); 37 } 38 else // 歩き 39 { 40 anim.SetBool ( "Walk", true ); 41 var moveVal = new Vector3(inputH, 0f, inputV) * speed; 42 rb.MovePosition ( rb.position + moveVal ); 43 } 44 } 45}

AnimatorControllerはこのような形で設定してみました。
イメージ説明

さらに、Attackモーションの部分にStateMachineBehaviorのスクリプトをアタッチします。
イメージ説明
内容はこちら。これによって、攻撃モーションの終わり間際に、AnimatorのAttackの値をfalseに戻します。

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5// Animator の Attack モーションにアタッチする StateMachineBehavior 6public class AttackBehaviour : StateMachineBehaviour 7{ 8 override public void OnStateUpdate ( Animator animator, AnimatorStateInfo stateInfo, int layerIndex ) 9 { 10 // 攻撃モーションの最終盤で Attack パラメーターの値を false に戻す 11 if ( stateInfo.normalizedTime > 0.9f ) 12 { 13 animator.SetBool ( "Attack", false ); 14 } 15 } 16}

参考GIF
![イメージ説明
以上です。

投稿2018/12/27 09:26

編集2018/12/27 13:21
negitama

総合スコア943

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

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

nya3720197

2018/12/27 11:58

攻撃キーを押したら 変数 Scrollはゼロになりますが、攻撃アニメーション再生中に移動キーを押すと、 変数 Scroll に新たな値が入ってしまうので移動してしまいます…
nya3720197

2018/12/27 12:01

AnimatorのHas Exit Time はオンにしているので、攻撃アニメーションしながら移動しちゃう感じです。
negitama

2018/12/27 13:16

あらためて回答しなおしました。回答2を参照願います。
nya3720197

2018/12/27 14:20

何から何まで丁寧な解説ありがとうございました(> <) ベストアンサーにさせていただきます!
guest

0

攻撃中はキー入力を受け取る関数を無効化して、攻撃が終わった時点でまた有効化するという考え方でなんとかなりました。

具体的には攻撃キーが押されたら変数Attackにtrueを代入します。
もしAttackがtrueならキー入力を受け取らないようにします。
そして攻撃アニメーションが終わったら関数AttackFinishを実行(←unityのanimatorで設定可能)する事で変数Attackにfalseを代入してまたキー入力受付を再開します。

プログラム初心者の僕が考えたのでもっと良い方法はあると思います…

c#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Controller : MonoBehaviour 6{ 7 Animator animator; 8 Rigidbody2D rb2d; 9 public float Speed = 10f; 10 float Scroll = 0f; 11 bool Attack = false; 12 string State; 13 string SaveState; 14 void Start() 15 { 16 rb2d = GetComponent<Rigidbody2D>(); 17 animator = GetComponent<Animator>(); 18 } 19 void Update() 20 { 21 GetKey(); 22 ChangeState(); 23 ChangeAnimation(); 24 Move(); 25 } 26 void GetKey() 27 { 28 if (Input.GetMouseButtonDown(0)) 29 { 30 Attack = true; 31 } 32 //攻撃中はキー入力を受け取らない(boolで判断) 33 else if (Attack == false) 34 { 35 if (Input.GetKey(KeyCode.D)) 36 { 37 Scroll = 1f; 38 } 39 else if (Input.GetKey(KeyCode.A)) 40 { 41 Scroll = -1f; 42 } 43 else 44 { 45 Scroll = 0; 46 } 47 } 48 } 49 void ChangeState() 50 { 51 if (Attack == true) 52 { 53 State = "Attack"; 54 Scroll = 0; 55 } 56 else if (Scroll != 0) 57 { 58 State = "Run"; 59 } 60 else 61 { 62 State = "Stop"; 63 } 64 } 65 66 void ChangeAnimation() 67 { 68 if (SaveState != State) 69 { 70 switch (State) 71 { 72 case "Stop": 73 animator.SetBool("Run", false); 74 animator.SetBool("Stop", true); 75 animator.SetBool("Attack", false); 76 break; 77 78 case "Run": 79 animator.SetBool("Stop", false); 80 animator.SetBool("Attack", false); 81 animator.SetBool("Run", true); 82 break; 83 84 case "Attack": 85 animator.SetBool("Run", false); 86 animator.SetBool("Stop", false); 87 animator.SetBool("Attack",true); 88 break; 89 } 90 } 91 SaveState = State; 92 } 93 94 void Move() 95 { 96 rb2d.velocity = new Vector2(Scroll * Speed, rb2d.velocity.y); 97 } 98 99 //アニメーションが終わったら実行(unityのanimatorで設定可能) 100 void AttackFinish() 101 { 102 Attack = false; 103 } 104}

このコードは様々サイト+僕の考えで作ったので完全オリジナルではないです

投稿2018/12/27 12:45

nya3720197

総合スコア12

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問