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

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

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

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

Q&A

解決済

2回答

803閲覧

【Unity】カーリングゲームで一投目と二投目の飛距離が違う

sumikko6210

総合スコア138

C#

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

Unity3D

Unity3Dは、ゲームや対話式の3Dアプリケーション、トレーニングシュミレーション、そして医学的・建築学的な技術を可視化する、商業用の開発プラットフォームです。

0グッド

0クリップ

投稿2018/11/25 10:56

編集2018/11/28 09:57

前提・実現したいこと

カーリングゲームを作成しているのですが、一投目と二投目で石の飛距離が変わってしまう
問題を解決したいです。

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

イメージ説明
イメージ説明

赤が一投目、青が二投目なのですが、写真のように飛距離が
全く違っています。
三投目に関しては奥の壁に当たってしまいます。
エラーも出ていない状況です。

該当のソースコード

Stone.csは石に
NearestScript.csは真ん中の白いSphereに入れています。

Stone.cs

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class Stone : MonoBehaviour 6{ 7 public static Rigidbody rb; 8 public static bool Ika = false; 9 10 bool straight = false; 11 bool right = false; 12 bool left = false; 13 Vector3 speed; 14 15 public GameObject isi; 16 // Use this for initialization 17 void Start() 18 { 19 rb = GetComponent<Rigidbody>(); 20 } 21 22 void Update() 23 { 24 Debug.Log(speed); 25 speed = rb.velocity; 26 if (Input.GetKeyDown("up") ) 27 { 28 straight = true; 29 Ika = true; 30 } 31 32 if (Input.GetKeyDown("right")) 33 { 34 right = true; 35 } 36 if (Input.GetKeyDown("left")) 37 { 38 left = true; 39 } 40 } 41 42 // Update is called once per frame 43 void FixedUpdate() 44 { 45 if (straight) 46 { 47 rb.velocity = transform.forward * 30f;//石を前に飛ばす 48 straight = false; 49 } 50 51 if (right) 52 { 53 rb.AddForce(Vector3.right *speed.magnitude* 1f); 54 right = false; 55 } 56 if (left) 57 { 58 rb.AddForce(Vector3.left * speed.magnitude * 1f); 59 left = false; 60 } 61 if (rb.IsSleeping() && Ika) 62 { 63 Vector3 pos = transform.position; 64 pos.x = 0; 65 pos.y = 0; 66 pos.z = -65; 67 Instantiate(isi, pos, transform.rotation); 68 Ika = false; 69 gameObject.GetComponent<Stone>().enabled = false; 70 } 71 } 72 private void OnCollisionEnter(Collision other) 73 { 74 if(Ika && other.gameObject.CompareTag("wall")) 75 { 76 Vector3 pos = transform.position; 77 pos.x = 0; 78 pos.y = 0; 79 pos.z = -65; 80 Instantiate(isi, pos, transform.rotation); 81 Ika = false; 82 } 83 } 84} 85 86

カーリングの距離判定
NearestScript.cs

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class NearestScript : MonoBehaviour 6{ 7 GameObject nearestStone = null; 8 public GameObject[] stones; 9 10 11 // Use this for initialization 12 void Start() 13 { 14 15 } 16 void Update() 17 { 18 measure(); 19 score(); 20 } 21 // Update is called once per frame 22 void measure() 23 { 24 if (Stone.rb.IsSleeping() && Stone.Ika) 25 { 26 GameObject[] stones = GameObject.FindGameObjectsWithTag("stone"); 27 float minDis = 100f; 28 foreach (GameObject stone in stones) 29 { 30 float dis = Vector3.Distance(transform.position, stone.transform.position); 31 if (dis < minDis) 32 { 33 minDis = dis; 34 nearestStone = stone; 35 } 36 } 37 } 38 } 39 40 void score() 41 { 42 int point = 0; 43 if(Stone.count == 6) 44 { 45 if (nearestStone.name.Contains("aka")) 46 { 47 GameObject[] stones = GameObject.FindGameObjectsWithTag("stone"); 48 float minDis = 1000f; 49 foreach (GameObject stone in stones) 50 { 51 float dis = Vector3.Distance(transform.position, stone.transform.position); 52 if (dis < minDis && stone.name.Contains("ao")) 53 { 54 minDis = dis; 55 } 56 } 57 58 foreach (GameObject stone in stones) 59 { 60 float dis = Vector3.Distance(transform.position, stone.transform.position); 61 if (dis < minDis && stone.name.Contains("aka")) 62 { 63 point++; 64 } 65 } 66 Debug.Log(point); 67 } 68 69 if (nearestStone.name.Contains("ao")) 70 { 71 GameObject[] stones = GameObject.FindGameObjectsWithTag("stone"); 72 float minDis = 1000f; 73 foreach (GameObject stone in stones) 74 { 75 float dis = Vector3.Distance(transform.position, stone.transform.position); 76 if (dis < minDis && stone.name.Contains("aka")) 77 { 78 minDis = dis; 79 } 80 } 81 82 foreach (GameObject stone in stones) 83 { 84 float dis = Vector3.Distance(transform.position, stone.transform.position); 85 if (dis < minDis && stone.name.Contains("ao")) 86 { 87 point++; 88 } 89 } 90 Debug.Log(point); 91 } 92 } 93 } 94 95} 96

投げた石が止まったときに次の石を生成したいため、bool型変数Ikaを使用しています。
投げた時(上キーを押したとき)にIkaをtrue、かつその投げた石が止まったとき(IsSleeping())に次の石を生成したいために利用しています。(使わないと、生成したときに、IsSleeping()がtrueになってしまう)

staticなのはNearestScriptで変数を利用したいがためにのみ使っています。

キー入力では左右は石の左右の動作、上は真っすぐの動作を記載しています。
今回は真っすぐの動作が期待通りの動作をしていない状況です、

FixedUpdate内で投げた時のrb.velocityの大きさを確認しましたが、
大きさはすべて(0, 0, 30)でした。

一投目の石はInstantiateではなく、元から置いてあります。

試したこと

【追記】
距離が変わる原因なのですが、すでに投げてある石のrigidbodyが投げる石のrigidbodyに加算されているようでした。すでに投げてある石のrigidbodyを除くと同じ飛距離を飛んでくれました。
原因はわかったのですが、解決策がわからずに今困っている状況です。

補足情報(FW/ツールのバージョンなど)

Unity2017.4

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2018/11/25 14:22

static bool Ika; はどのような目的のものなのでしょうか? また、いくつか入力を受け取っていますが、それぞれどのように動作することを目的としていますか?(左右の入力を受け取っていることをどのように反映させたいか)
sakura_hana

2018/11/26 02:07

石を投げる(生成する)部分のスクリプトも提示してもらえますか? rb.velocityが常に(0,0,30)とのことですが、停止していてもその値ですか?
MMashiro

2018/11/26 03:39

手持ちの環境で試してみましたが(Stone.csのみ)1投目・2投目…と繰り返してみましたが全て同じ距離進みました。回答ではありませんが補足情報として提示しておきます。
sumikko6210

2018/11/26 13:13

修正依頼のご質問の回答は質問に加えました。 MMashiroさんの環境では動いたんですね。ご報告ありがとうございます。 設定などを見てみます
Bongo

2018/11/26 13:55

私も試してみましたが、おっしゃるような飛距離の変わってしまう現象は見られませんでした。スクリプトもご提示のものをほぼそのまま使っております(唯一、NearestScript内で使っているStone.countが見つからなかったので追加しましたが...)。これらスクリプト以外には石に作用するスクリプトは存在しないのでしょうか?
sumikko6210

2018/11/28 09:51

ご回答ありがとうございます。提示してあるスクリプト以外は使用していません。
guest

回答2

0

ベストアンサー

public static Rigidbody rb;
public static bool Ika = false;
こちらそれぞれstaticをつけていますが、これには何かしらの意図がありますか?
staticはゲーム上で唯一の変数になるので、
stone.scを付与しているstoneが複数ある場合、最後にstart関数を呼び出したrigitbodyが全stone.scのrbに入ることになります。

今回の現象ですが、おそらく
まず一つ目のstone(A-stone)を生成した際はsumikko6210さんが想定した飛距離に飛ぶと思われます。
二つ目のstone(B-stone)が生成された際に、rbに2つ目のstoneのrigitbodyが入ります。
そうすることで、A-stoneのFixedUpdate内でB-stoneのvelocityを加えてしまいます。
また、B-stoneでもFixedUpdateは呼ばれますので、2重に力を加えてしまっているわけです。
同様に、三つ目も生成すると、3重になります。

説明が下手で申し訳ないですが、特に意図がないのであればstaticを消せば解決するのではないのでしょうか?

投稿2018/11/25 13:02

yuuyu

総合スコア1135

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

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

sumikko6210

2018/11/25 14:14

ご回答ありがとうございます。 staticをつけているのは、別スクリプトからこれらの変数を呼び出しているためです。 staticを取り除いて試したのですが、結果は同じでした。。。
yuuyu

2018/11/26 12:30

修正されたものを見てみましたが、自分が思い当たる点がここしかないようなので、もしかすると解決へのお手伝いはできないかもしれません。申し訳ないです。 ちなみにstaticを取り除いたと仰いましたが、staticを取ると別スクリプトで参照していた箇所でエラーが発生するかと思いますが、こちらどう対処されましたか? あと直接解決とは関係ありませんが、見た感じStone.scとNearestScript.csはどちらも同じオブジェクトにつけていると思われますので、 NearestScript.cs内に、 public Stone st; //変数名がstoneだと被るのでstにしました。 を追加し、Inspecter上でstに同じオブジェクトのStone.csを入れ、 st.rbやst.Ikaのような参照にした方が今後のためかと思います。
sumikko6210

2018/11/26 12:58

staticをとったときの動作を見たかったので、staticをとったときのエラーはコメントアウトしました。 説明しそびれましたが、NearestScript.csは写真の白いSphereに入れています。 説明不足ですいません。追記しておきます
yuuyu

2018/11/26 13:34

なるほどです。 では違うところで不審点がありましたのでそちらの方をお聞きします 1投目はシーンに設置してあり、2投目以降はおそらく Instantiate(isi, pos, transform.rotation); のところで生成しているかと思います。 Ikaがtrueに戻る記述がどこにも記載されていないのですが、3投目はどのようにして投げました? またここではなく別で生成した場合、そちらのコードがあるかと思われますので、Instantiateが記述された関数のみで構いませんので、そちら書いていただけないでしょうか? (>説明しそびれましたが、NearestScript.csは写真の白いSphereに入れています。 でしたら同じように、1投目のstoneのものをstに入れ、2投目以降は生成時に再代入(GetComponent<Stone>())としていくのがいいかと思います。 ただ状況が正しく把握しているわけではないので、分かりづらければこちらの話は無視していただいて構いません。)
sumikko6210

2018/11/28 09:55

if (Input.GetKeyDown("up") ) { straight = true; Ika = true; } ここでIkaをtrueしています。 生成も投げることもすべてStone.csに記述しており、ほかのスクリプトは使用していません。 距離が変わる原因なのですが、rigidbodyに加算されているようでした。すでに投げてある石のrigidbodyを除くと同じ飛距離を飛んでくれました。 原因がわかったのですが、解決策がわからず苦しんでいます・・・
yuuyu

2018/11/28 10:11

>ここでIkaをtrueしています。 記述してありましたね。見落としでした。申し訳ないです >距離が変わる原因なのですが、rigidbodyに加算されているようでした。すでに投げてある石のrigidbodyを除くと同じ飛距離を飛んでくれました。 原因がわかったのですが、解決策がわからず苦しんでいます・・・ 何故そういう仕様になってしまったのか、原因が今の所解明できていないので、暫定的な対処法しか思いつかないのですが、スクリプトを無効化させているのと同様、 gameObject.GetComponent<Rigidbody>().enabled = false; こちらをgameObject.GetComponent<Stone>().enabled = false;の後ろに記述することでrigidbodyを取り除くことができるとは思われます。 根本的な解決にはなっていないので、この先派生させていくとすればまたどこかで引っかかるかもしれないですが・・・。
sumikko6210

2018/11/28 13:05

ご丁寧な回答ありがとうございました。 useGravityをfalseにしたことでも同じような挙動になったのでその操作をスクリプト上で うまく書きました。 とても助かりました!
yuuyu

2018/11/28 13:11

いえいえ〜 最後まで直接的な解決を提示できなかったですけど、 無事に晴れて良かったです
guest

0

speed = rb.velocity;
は、FixedUpdateの中で参照した方が良いと思います。
それで直る可能性がありますが、自信はあまり無いので是非1度お試しください。
ふわっとした回答で申し訳ないですが、取り急ぎ……

投稿2018/11/25 11:14

plman

総合スコア8

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

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

sumikko6210

2018/11/25 11:59

ご回答ありがとうございます。 speed = rb.velocity;をFixedUpdate内に記載したのですが、変化なしでした。。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.51%

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

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

質問する

関連した質問