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

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

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

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

Unity

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

Q&A

解決済

1回答

1286閲覧

移動方向に応じて表示アニメを切り替えるスクリプトで、他のクラスでオブジェクトを移動させた場合にアニメ表示を変えたい

usagi3kaku

総合スコア9

C#

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

Unity

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

0グッド

0クリップ

投稿2019/09/09 22:31

編集2019/09/09 23:26

以下の2つのスクリプト(①、②)をアタッチして、移動方向に応じて歩行アニメを切り替えつつ自機を追従する敵を作りたいのですが、
②での移動方向に応じて①のnowMode(再生クリップ名を指定するstring)を更新することがうまくできません。

テストのために、「追従移動②」ではなく「キー入力による直接移動③」を用意し、①とセットで運用してみたのですが、
その場合は問題なく表示アニメが変更されました。

②も③も、移動自体はUpdate中に取得したVector座標をFixedUpdate時にRigidbodyのvelocityに代入して位置を更新する同じ仕組みだと思うのですが、なぜか②の方では③と同じ様に機能しないのです。

  • また、これ以下の事柄は上記の問題に関係あるのかわからず参考までに書きますが、プレイ時に①と②をアタッチしたオブジェクトがターゲットを追従する際、アニメは静止状態のままで座標移動だけが起きるのですが、その状態で障害物に引っかかって移動が停止(velocityが0まで減衰?)した際に、なぜかその移動方向の向きのアニメーションクリップの再生に切り替わります。

その後にまた仕切り直しと接近によって追従移動が始まっても、移動方向はやはり反映されず、引っかかった時に更新されたクリップのアニメのままで再生されつづけます。追従中に何かに引っかかって時に一度だけクリップが変更されるような挙動です。

原因や解決方法がわかる方、ご教示をお願い致します。


######①:Mob_Anime_Setting(移動方向に応じて表示アニメを切り替えるクラス)

C#

1public class Mob_Anime_Setting : MonoBehaviour 2{ 3 4 Rigidbody2D rigid2D; 5 Animator animator; 6 7 8 // GameObject gameObject; 9 10 public string nowMode; 11 12 public string upAnime; 13 public string downAnime; 14 public string rightAnime; 15 public string leftAnime; 16 public string down_stop; 17 public string up_stop; 18 public string right_stop; 19 public string left_stop; 20 21 public bool moving ; 22 23 24 public Vector3 pastpos; 25 public Vector3 nowpos; 26 27 28 void Start() 29 { 30 this.rigid2D = GetComponent<Rigidbody2D>(); 31 this.animator = GetComponent<Animator>(); 32 } 33 34 void Update () 35 { 36 37 pastpos = nowpos; 38 nowpos = this.gameObject.transform.position; 39 40 41 42 43 if (nowpos.x == pastpos.x) 44 45 { 46 if (nowpos.y > pastpos.y) { nowMode = upAnime; } 47 else if (nowpos.y < pastpos.y) { nowMode = downAnime; } 48 } 49 50 else if (nowpos.y == pastpos.y) 51 { 52 if (this.rigid2D.velocity.x > 0) { nowMode = rightAnime; } 53 else if (this.rigid2D.velocity.x < 0) { nowMode = leftAnime; } 54 } 55 56 57 58 if(rigid2D.velocity.x == 0 && rigid2D.velocity.y == 0)//ベロシティがゼロなら止まっている 59 { moving = false; } 60 else 61 { moving = true; } 62 63 } 64 65 66 public void FixedUpdate() 67 { 68 if (moving == false) { GetComponent<Animator>().speed = 0.0f; } 69 else { GetComponent<Animator>().speed = 1.0f; } 70 71 GetComponent<Animator>().Play(nowMode); 72 73 74 75 } 76}
②:MobChase_A(ターゲットオブジェクトを追従するクラス)

C#

1public class MobChase_A : MonoBehaviour 2 3 4{ 5 public string targetObjectName; 6 public float speed = 1; 7 public bool LockOn; 8 public bool moving; 9 10 public Vector3 pastpos; 11 public Vector3 nowpos; 12 13 14 GameObject targetObject; 15 Rigidbody2D rbody; //「リジットボディ2D」型の変数「rbody」を用意 16 17 Mob_Anime_Setting animeSet; 18 19 20 void Start() 21 { 22 targetObject = GameObject.Find(targetObjectName); //目標オブジェクトを見つけておく 23 24 rbody = GetComponent<Rigidbody2D>(); //「rbody」にリジッドボディ2Dを搭載 25 animeSet = GetComponent<Mob_Anime_Setting>(); 26 rbody.gravityScale = 0; //重力は0 27 rbody.constraints = RigidbodyConstraints2D.FreezeRotation; //衝突時に回転させない 28 29 LockOn = false; 30 } 31 32 33 void OnTriggerEnter2D(Collider2D collision)   34 { 35 if (collision.gameObject.tag == "Player")   36 { LockOn = true; } 37 } 38 //トリガーに入ったのが 、タグ「Player」のobjectの場合、ロックオンする。 39 40 41 void OnTriggerExit2D(Collider2D collision) 42 { 43 if (collision.gameObject.tag == "Player") 44 { LockOn = false; }  45 } 46 //トリガーから出たのが 、タグ「Player」のobjectの場合、ロックオン解除 47 48 49 50 void FixedUpdate() 51 { 52 53 if (LockOn == true) //ロックオンしてる時 54 { 55 56 Vector3 dir = (targetObject.transform.position - this.transform.position).normalized; //目標オブジェクトの方向をVector3で調べる 57 58 float vx = dir.x * speed; 59 float vy = dir.y * speed; 60 rbody.velocity = new Vector3(vx, vy); //取得したVector座標へむかって指定量で進む 61 62 63 pastpos = nowpos; 64 nowpos = this.gameObject.transform.position; 65 66 67 } 68 } 69 70 71  void Update() 72 { 73 74 if (nowpos.x == pastpos.x) 75 76 { 77 if (nowpos.y > pastpos.y) { GetComponent<Mob_Anime_Setting>().nowMode = GetComponent<Mob_Anime_Setting>().upAnime; } 78 else if (nowpos.y < pastpos.y) { GetComponent<Mob_Anime_Setting>().nowMode = GetComponent<Mob_Anime_Setting>().downAnime; } 79 } 80 81 else if (nowpos.y == pastpos.y) 82 { 83 if (this.rbody.velocity.x > 0) { GetComponent<Mob_Anime_Setting>().nowMode = GetComponent<Mob_Anime_Setting>().rightAnime; } 84 else if (this.rbody.velocity.x < 0) { GetComponent<Mob_Anime_Setting>().nowMode = GetComponent<Mob_Anime_Setting>().leftAnime; } 85 } 86 87 88 if (Input.GetKeyDown("space")) 89 { 90 LockOn = false; 91 } 92 } 93}
③:OnKeyPress_Move(キー入力の示す方向に移動を行うクラス)

C#

1public class OnKeyPress_Move : MonoBehaviour 2{ 3  public float speed = 2; 4 public float vx = 0; 5 public float vy = 0; 6 7 Rigidbody2D rbody; 8 Walk_Anime_Setting animeSet; 9 10 void Start() 11 { 12 animeSet = GetComponent<Walk_Anime_Setting>(); 13 rbody = GetComponent<Rigidbody2D>(); 14 rbody.gravityScale = 0; 15 rbody.constraints = RigidbodyConstraints2D.FreezeRotation; 16 } 17 18 19 void Update() 20 { 21 vx = 0; 22 vy = 0; 23 24 if (Input.GetKey("right")) 25 { 26 vx = speed; 27 28 GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().rightAnime; 29 } 30 31 if (Input.GetKey("left")) 32 { 33 vx = -speed; 34 35 GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().leftAnime;} 36 37 if (Input.GetKey("up")) 38 { 39 vy = speed; 40 41 GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().upAnime; 42 43 } 44 45 if (Input.GetKey("down")) 46 { 47 vy = -speed; 48 49 GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().downAnime; 50 51 } 52 53 if (Input.GetKeyUp("right")) 54 { GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().right_stopAnime; } 55 56 if (Input.GetKeyUp("left")) 57 { GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().left_stopAnime; } 58 59 if (Input.GetKeyUp("up")) 60 { GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().up_stopAnime; } 61 62 if (Input.GetKeyUp("down")) 63 { GetComponent<Walk_Anime_Setting>().nowMode = GetComponent<Walk_Anime_Setting>().down_stopAnime; } 64 65 66 } 67 private void FixedUpdate() 68 { 69 { 70 rbody.velocity = new Vector2(vx, vy); 71 } 72 } 73} 74

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

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

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

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

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

guest

回答1

0

自己解決

ようやく解決できました。もとのコードは今見返すと散らかりすぎていて、もはやどこ原因だったのか、わかりません。解決までの試行錯誤の間に学んだことで一番大きかったのは

  • 他のクラスの変数などを多数参照する場合は「GetComponent」からの長いコードを連発せずに、フィールドとスタートで対象クラスを紐づけておけば、参照先の変数名だけの記述で利用できる。

ということでしたので、その辺りの整理をしていくうちに、繋がっていなかった変数と処理がしっかり繋がったのだと思います。

繰り返し使う処理はメソッドとしてカプセル化することも覚えましたので、今後はもう少し可読性の良いコードが書けるようになると思います。
初学者とはいえ、本件では自分でも整理の出来ていないコードをアップしてしまい、まずかったなと反省いたしました。
もしもアドバイスを下さろうとして目を通された方がいらっしゃいましたら申し訳ありませんでした。

投稿2019/09/11 04:03

usagi3kaku

総合スコア9

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問