🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Unity

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

Q&A

1回答

717閲覧

【unity】ある決まった落下始点からボールを落下させたい

uni_001

総合スコア4

Unity

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

0グッド

0クリップ

投稿2019/10/21 07:20

・前提・実現したいこと

unityで、自分が決めた特定の落下始点からボールを落下させるプログラムを作成したい。(ボールは複数で、ボールごとに落下始点を変えたいため、その都度落下始点を与えています)

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

もともと、transformで落下始点の指定を、rigidbody で重力落下の反映をしていたのですが、うまくいかず、
調べたところ同時に使うのは良くないということがわかりました。

そこで、addforceなどrigidbodyに代わる、重力を加える方法も試してみましたがうまくいきませんでした。
特定の始点からボールを落下させるプログラムについてわかる方がいらっしゃれば教えて頂きたいです。

unity初心者なので、詳しく教えていただけると助かります。
よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

3Dの場合:
ボールオブジェクトにRigidbodyコンポーネントを追加すれば自動的に落下すると思います。(Use Gravityにチェックが入っていること)

2Dの場合:
ボールオブジェクトにRigidbody 2Dコンポーネントを追加すれば自動的に落下すると思います。(Simulatedにチェックが入っていること)

落下始点については質問者さんもわかっているかもしれませんが、ボールを生成したときなどに適当な座標を1度与えるだけで十分です。(逆にUpdateなどで毎フレーム同じ場所を指定しているともちろん動きません)

投稿2019/10/21 08:36

megumin

総合スコア78

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

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

uni_001

2019/10/21 08:48

megumin様 お忙しい中、回答ありがとうございます! 書き忘れていたのですが、ボールオブジェクトのrigidbodyコンポーネントのuse gravityをチェックしても上手く重力落下ができず、スクリプトで重力を指示できる方法がないか探しています。(おそらく、use gravityとtransformを同時には使えないからだと思います…) 説明が不足しており申し訳ありません。 もし、ご存知でしたら教えて頂きたいです。よろしくお願いします!
megumin

2019/10/21 08:59

transformを同時に使うというのがちょっと良くわかりませんが、何か処理を平行してtransformコンポーネントを参照・変更しているということでしょうか?(transform情報で位置を変更する必要はありませんよ?) こちらで試しにSphereオブジェクトを生成し、Rigidbodyを追加して再生してみましたが期待通り落下しました。スクリプトも追加していません。(Unityバージョン2019.2.6f1) そちらでも同じように簡易的なものを作成して確認してみてはどうでしょう?
uni_001

2019/10/21 13:44

丁寧にコメントありがとうございます! おっしゃっておられるように、updateの中にtransform.positionで、落下始点を定めています… これが原因で動かないのでしょうか? STEPごとに、ボールの落下始点を変えたいため、transform.positionで落下始点を指定しています。 STEP1の時は、この始点から落下。 STEP2の時は、STEP1とは違う始点から落下。 ・・・というようにif文で条件分けをして、それぞれのif文の中に、transform.positionを書いています。 お時間があるときに教えていただけると助かります。
Hawn

2019/10/22 12:27

一日近く経過しているので代わりに答えさせて頂くと >updateの中にtransform.positionで、落下始点を定めています…これが原因で動かないのでしょうか? 9割方これが原因です。 if文を修正して"STEPごとに一度だけ"落下始点を定めて下さい。 コードを書いているならばそれも質問文に記述すると明確な回答頂けると思います。
uni_001

2019/10/24 02:16

ha_wn様 代わりにお答えいただき、ありがとうございます。助かりました。 やはり、そこが問題なのですね… STEPごとに、一度だけTransform.positionで落下始点を定めているつもりなのですが、これでは動かないのでしょうか… 教えて頂いた通り、簡単にですが、該当箇所のプログラムをのせておきます。 細かい話をすると、Leap motionという指の位置を判定する機器と組み合わせたプログラムを作成しています。 ある落下始点から落下するボールに指でタッチができたら、そのボールを消して、次のボール(落下始点の異なる)を発生させる…という動作を繰り返し行いたいです。 長くなり、申し訳ありません。お時間があるときにお返事よろしくお願い致します。 void Update ()  { … //ボールの位置を移動 if (GameManager.step == -1) { SokuteiText.text = " "; transform.position = new Vector3(-0.3f, 0.3f, 0.3f); NowPoint.text = "1"; //何個目のボールかを表示 } //ボールが消えたら次のボールを出す    // GameManager.step%2で求めているので-1,1,3,5…となっていますが問題ないと思います if (GameManager.step == 1 && GameManager.sokutei == 1) { SokuteiText.text = " "; transform.position = new Vector3(0.3f, 0.3f, 0.3f); NowPoint.text = "2"; } if (GameManager.step == 3 && GameManager.sokutei == 1) { SokuteiText.text = " "; transform.position = new Vector3(0.3f, -0.3f, 0.3f); NowPoint.text = "3"; } if (GameManager.step == 5 && GameManager.sokutei == 1) { SokuteiText.text = " "; transform.position = new Vector3(-0.3f, -0.3f, 0.3f); NowPoint.text = "4"; } …  }
Hawn

2019/10/24 02:35 編集

条件式で使っているGameManager.stepとGameManager.sokuteiに値を代入している箇所が見当たらないのでこれだけでは判断出来ません。 せめてUpdate内全文載せてください。 エスパー力を発揮すると条件式内で条件となる値が変わっていないので同じ条件式に繰り返し入っています。 実際にそうなっているかはデバッガーでブレイクポイントを置いて確認するか、Debug.Log(1);を使って複数回表示されるかなど自身で確認して下さい。
uni_001

2019/10/24 03:40

丁寧に返信ありがとうございます。 申し訳ありません…不十分でした。 スクリプトファイルがいくつかあって、全てをのせるととても長いので、関連するところのみ抜粋します。 先ほどのスクリプト名は「Point」、下記のものが「GameManager」です。GameManager.stepとGameManager.sokuteiは「GameManager」のスクリプトの変数を使用しています。 実行すると、ボールがうまく重力落下しないだけで、指定した位置にボールが表示されており、動きは問題はありませんでした。 // 今何個目のボールか public int step = -1; //sokutei==0:測定が終わっていない sokutei==1:測定済み public int sokutei; void Update() { if (Input.GetKeyDown(KeyCode.RightArrow) && step <16) //キーボードが押されたら { step++; //初期化 sokutei = 0; } //次のボールの表示 if (step%2 == 1) { Vector3 point = Point.transform.position; if (sokutei == 0) { if (Hand_R.activeSelf == true && use_hand == true)  //右手で測定 { sokutei = 1; } else { //まだ測定が終わっていない if(step <= 15) { //エラー処理 step = step - 1; sokutei = 0; ErrorText.text = "Error"; } } } }   }
uni_001

2019/10/24 03:41

追記 試しに、本プロジェクトとは関係のない新たなプロジェクトでボールオブジェクトを一個表示させ、そのボールに以下のプログラムを反映させ、RigidbodyコンポーネントでUse GravityをONにして、実行したところ、ボールの位置が移動するだけで、重力落下は起きませんでした… やはり、そもそもtransform.positionとUse Gravityを同時に使うことはできないのでしょうか… void Update() { transform.position = new Vector3(3f, 3f, 3f); } 複数投稿し、申し訳ありません…
Hawn

2019/10/24 04:03 編集

>やはり、そもそもtransform.positionとUse Gravityを同時に使うことはできないのでしょうか… 出来ます 追記のコードは1フレーム毎にVector3(3f, 3f, 3f)へ移動されているのでそうなります。 ゲーム開始時一回だけ位置指定する時はStartを使って下さい。 下記で落下するかどうか試して下さい。 void Start() { transform.position = new Vector3(3f, 3f, 3f); }
Hawn

2019/10/24 03:54

それと本題の方ですがやはりそれでは同じ位置に何度も移動される処理が行われ落下しないので、 フラグを作成して上手くそれを使って処理を一回しか行わないよう修正して下さい。
uni_001

2019/10/24 04:54

返信ありがとうございます。 追記で送った方ですが、updateではなくstartの方でtransform.positionを指定したところうまく動きました。 本題の方も、transform.positionをあらかじめupdateで指定するなどして改良してみようと思います。 フラグは使ったことがないのでうまくできるかわかりませんが挑戦してみます。(うまくいかなかったらまた質問させてもらいます…) 色々と丁寧に教えていただきありがとうございました。とても助かりました。
megumin

2019/10/24 05:23

きっかけを知ることができたのでもしかしたら自己解決できるかもしれませんが、わからなかったらこちらを答えだと思って後でご覧になってみてください。 貼り付けられたソースに関してぱっと見ただけなんですけど、 ・GameManager.stepはキーボードが押されたときに進めている ・GameManager.stepが奇数のときに座標を新たに設定している(1度だけセットしたいつもりがずっとセットされ続けている) ・そしておそらくの原因がGameManager.sokuteiが0になっていないのでPointスクリプトのUpdateでずっと同じ座標を与え続けているのでボールが落下しない(移動しない)ということになっているのでしょう。 ボールの位置をセットする条件が期待している内容と違うため今回のようになっていると思うので、 ha_wnさんがおっしゃっているように以下のようにGameManager.isStartというボールの座標を決めるためのフラグを作成すればよろしいかと思います。 (結局最初に回答したときの内容に戻ってしまいましたね^^;(Updateなどで毎フレーム同じ場所を指定している)難しいかもしれませんが少しだけがんばってみてください!) ------------------------------------------------------------------- GameManagerスクリプト public int step = -2;//-2にすればキーボードを押したときに-1からスタートできるよ public bool isStart = false;//①ボールの座標は決めていないよ! void Update() { if (Input.GetKeyDown(KeyCode.RightArrow) && step <16) //キーボードが押されたら { step++; //初期化 sokutei = 0; isStart = true;//②ボールの座標を決めるよ! } } ------------------------------------------------------------------- ------------------------------------------------------------------- Pointスクリプト void Update() { //③ボールの位置を決めたときだけ座標をセットするよ! if (GameManager.step == -1 && isStart) { SokuteiText.text = " "; transform.position = new Vector3(-0.3f, 0.3f, 0.3f); NowPoint.text = "1"; //何個目のボールかを表示 isStart = false;//④ボールの座標を決めたよ! } } ------------------------------------------------------------------- ①フラグの宣言(まだボールは表示されていないよ、最初からボールを表示したいならstep = -1とisStart = trueから始めよう!) ②キーボードが押されたときにボールをセットするよ! ③でステップが奇数のときかつisStartがtrueのときにボールの座標を決めるよ! ④ボールの座標を決めたらisStart = false;で次のフレームで③の条件に入らないようにするよ! それら以外のstep == 1,3,5...ってやっているところも同じくGameManager.sokutei == 1の代わりに③と同じことをして④で座標をセットしたことを知らせれば期待した結果になると思います。 終わり!閉廷!以上!みんな解散!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問