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

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

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

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

Q&A

解決済

1回答

910閲覧

オブジェクトの移動する向きに応じて、表示されるアニメクリップを変化させたい。UNITY2D

usagi3kaku

総合スコア9

C#

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

0グッド

0クリップ

投稿2019/09/08 05:11

編集2019/09/09 08:18

前提・実現したいこと

UNITYで、オーソドックスな2DのRPGのような見降ろし視点のゲームを作り始めました。初学者です。
オブジェクトの移動する方向に応じて、上下左右に歩くアニメーションクリップの表示を切り替える、というごく基本的な事なのですが実現できず困っています。

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

上下移動時は意図したとおりに上向きや下向きに歩くアニメーションが表示されるのですが、
左右の移動時にも上下移動のアニメーションになってしまい、左右用に用意したスプライトが一切見えません。

また、試行錯誤してコードを足したり引いたりする過程で、上と左右だけは表示され下だけ表示されない時期などもありましたが、
根本的に何が原因で表示され方が変わったのかも良くわかりません。

該当のソースコード

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5 6 7public class Mob_Anime_Setting : MonoBehaviour 8{ 9 10 Rigidbody2D rigid2D; 11 Animator animator; 12 13 14 public string upAnime ; 15 public string downAnime ; 16 public string rightAnime ; 17 public string leftAnime ; 18 public string stopAnime ; 19 20 public string nowMode; 21 22 23 Vector3 pastpos; 24 Vector3 nowpos; 25 26 27 void Start() 28 { 29 this.rigid2D = GetComponent<Rigidbody2D>(); 30 this.animator = GetComponent<Animator>(); 31 32 } 33 34 35 36 37 38 void Update() 39 { 40 pastpos = nowpos; 41 nowpos = this.gameObject.transform.position; 42 43 44 45 46 if (nowpos.y > pastpos.y) 47 { 48 if (nowMode != upAnime) 49 { 50 if (nowpos.y - pastpos.y > nowpos.x - pastpos.x) 51 { 52 nowMode = upAnime; 53 } 54 } 55 56 } 57 else if (nowpos.y < pastpos.y) 58 { 59 if (nowMode != downAnime) 60 { 61 if (nowpos.y - pastpos.y < nowpos.x - pastpos.x) 62 { 63 nowMode = downAnime; 64 } 65 } 66 67 } 68 69 else if (nowpos.x > pastpos.x) 70 { 71 if (nowMode != rightAnime) 72 { 73 if (this.rigid2D.velocity.y < 0) 74 { 75 nowMode = rightAnime; 76 } 77 } 78 } 79 80 else if (nowpos.x < pastpos.x) 81 { 82 if (nowMode != leftAnime) 83 { 84 if (this.rigid2D.velocity.y < 0) 85 { 86 nowMode = leftAnime; 87 } 88 89 } 90 } 91 else 92 { 93 nowMode = stopAnime; 94 } 95 96 97 } 98 99 100 void FixedUpdate() 101 { 102 103 this.GetComponent<Animator>().Play(nowMode); 104 105 } 106 107} 108 109

試したこと

色々な語句で検索して、同じような事を実現しようとするハウトゥー記事をいくつか探し、
例えば「移動量からベクトルを取得しさらにアングルに変換する方法」など試してみたのですが、
どの場合もまだ知らない概念が出て来て、試行錯誤しても結局応用ができなかったり、載っているコードをコピペしてもなぜか通らなかったりしております。
位置の移動距離でなく、ベロシティというのを使って向きを検出する試みもしました。シンプルなコードでエディター上でもエラーはなかったのですが、なぜか下向き移動の時だけ、左右どちらかのクリップになってしまっていました。

単純なものでも組み合わせで機能しさえすれば良い、と思い、今の自分に理屈を理解できる要素だけで上記のコードを書きました。
とても無駄が多いのだろうとは思いつつも、確実を期して冗長に書いたつもりでしたが、それすらも意図通りに機能せず、原因がわからず困り果てております。
このコードの問題点や、それとは別のもっと簡単な方法でも、ご教示いただけると幸いです。
よろしくお願いいたします。

##解決しましたので
完成版のコードを掲載しておこうと思います。

C#

1public class Mob_Anime_Setting : MonoBehaviour 2{ 3 Rigidbody2D rigid2D; 4 Animator animator; 5 6 public string nowMode; 7 8 public string upAnime; 9 public string downAnime; 10 public string rightAnime; 11 public string leftAnime; 12/* 13 public string down_stop; 14 public string up_stop; 15 public string right_stop; 16 public string left_stop; 17  停止時用のアニメーションクリップも用意しましたが、今回は移動中を示すbool変数をつかってアニメの再生自体を止める仕様にしました。 18*/ 19 20 bool moving ; //移動中かどうか。 21 22 Vector3 pastpos; 23 Vector3 nowpos; 24 25 void Start() 26 { 27 this.rigid2D = GetComponent<Rigidbody2D>(); 28 this.animator = GetComponent<Animator>(); 29 } 30 31 32 void Update() 33 { 34 pastpos = nowpos; 35 nowpos = this.gameObject.transform.position; 36 37 38 39 if (nowpos.x == pastpos.x) 40 41 { 42 if (nowpos.y > pastpos.y) { nowMode = upAnime; } 43 else if (nowpos.y < pastpos.y) { nowMode = downAnime; } 44 } 45 46 else if (nowpos.y == pastpos.y) 47 { 48 if (this.rigid2D.velocity.x > 0) { nowMode = rightAnime; } 49 else if (this.rigid2D.velocity.x < 0) { nowMode = leftAnime; } 50 } 51 52 53 54 if(rigid2D.velocity.x == 0 && rigid2D.velocity.y == 0) 55 { moving = false; } 56 //ベロシティがゼロなら止まっている 57 58 else 59 { moving = true; } 60 //さもなくば動いている 61 } 62 63 64 void FixedUpdate() 65 { 66 if (moving == false) { GetComponent<Animator>().speed = 0.0f; } //止まっている時はアニメーターの速度を0にして動きを停止 67 else { GetComponent<Animator>().speed = 1.0f; } //止まっていないならアニメ速度を標準に戻す 68 69 GetComponent<Animator>().Play(nowMode);               //現在のモードに指定されているクリップを再生 70 71 72 } 73}

ありがとうございました!

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2019/09/08 05:20

コードはMarkdownを使って質問お願いしますm(_ _)m
退会済みユーザー

退会済みユーザー

2019/09/08 05:44

編集ありがとうございますm(_ _)m
usagi3kaku

2019/09/08 05:52

マークダウンを使って修正しました。以後はマークダウンを使う用にいたします。m(_ _)m
退会済みユーザー

退会済みユーザー

2019/09/08 05:57

ありがとうございますm(_ _)m
izmktr

2019/09/08 12:24

this.GetComponent<Animator>().Play(nowMode); ・ここに直接、leftAnimeやrightAnimeを入れるとその向きのアニメが表示されますか? ・操作はアナログスティックを使ってますか?
usagi3kaku

2019/09/08 14:51

>ここに直接、leftAnimeやrightAnimeを入れるとその向きのアニメが表示されますか? 表示されました。 操作に使っているのはキーボードだけです。
guest

回答1

0

ベストアンサー

if (this.rigid2D.velocity.y < 0){ nowMode = rightAnime; }

nowModeの値がrightAnimeになっていれば、表示はされるといいうことですから、
このnowModeの値を代入する処理に通っていません
その原因はそこまでにあるif文のどこかで弾かれていると思われます

さて、if文ですが、else ifで全体がつながっていますから、
横方向のアニメに変わるのはnowpos.y == pastpos.y のときだけです
もしアナログ操作も考えるのなら、移動方向が大きい方向を採用するべきですね

全体的に、if (nowMode != upAnime) の処理も謎で、
今回のケースでは取り除いたほうがスッキリすると思います

投稿2019/09/09 03:58

izmktr

総合スコア2856

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

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

usagi3kaku

2019/09/09 08:03

ご回答ありがとうございます。 nowpos.y == pastpos.yが横方向を表すというのが良いヒントになり、全体的に簡潔なコードにすることができたと思います。 (言われて見返すと「 if (nowMode != upAnime) 」の処理は我ながら謎です。) このスクリプトは敵objectにアタッチし、敵の移動自体はまた別のクラスで行う予定でしたので、入力の事はあまり考えていませんでした。 しかしおかげさまで何とか満足のいく実現ができました。ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問