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

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

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

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

Unity

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

Q&A

解決済

2回答

1307閲覧

instantiateを使ったボールの連結

DY2peace

総合スコア20

C#

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

Unity

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

0グッド

1クリップ

投稿2021/07/06 06:49

編集2021/07/27 02:39

背景

 長尺ロープ再現用に計算負荷を減らすことを目的としています。
↓の動画のようにロープの延長・引き戻しを根本から「発生・消滅」するように再現したいと考えております。
イメージ説明
※AssetStore『ObiRope』の画像

###今回やろうとしていること
基準となるボール(JyakanBall)の初期位置からの移動量(2m毎)に移動したときに
初期位置からボールをinstantiateで発生させ、 ジョイントで連結させたいと考えてます。

 これでロープ形状を作ってみようと思います。

###知りたいこと
instantiateで発生させた物体に、すでに発生させた物体へConfigurableJointで連結させる方法を知りたいです。

イメージ説明

現在作成途中のC#

上下の矢印キーで一定速度で前後動させ、初期位置からの移動距離をmagnitude

  public GameObject JyakanBall; public GameObject FirstBall ;//最初に出てくるボール。こいつの動きを基準にする。 public Transform FirstPosiBase; // ボール発射初期位置 public float speed = 10; // ボールの速度 private int counter = 0;//ボール採番用 private float Distance ; // Start is called before the first frame update Rigidbody Rb; void Start() { Rb = FirstBall.GetComponent<Rigidbody>() ;     Vector3 FirstPosition = FirstPosiBase.transform.position;//ボールの発生する位置の設定     Vector3 Direction = FirstBall.transform.forward;//初期ボール位置のZ軸方向  FirstBall.transform.position = FirstPosition;//初期位置に初期ボールを移動させる } // Update is called once per frame void FixedUpdate() { Vector3 BallPosition = FirstBall.transform.position; Vector3 FirstPosition2 = FirstPosiBase.transform.position; Distance = (FirstPosition2 - BallPosition).magnitude; Debug.Log (Distance) ; if(Input.GetKey(KeyCode.UpArrow)) { Rb.velocity = new Vector3(0,0,speed); } else if(Input.GetKey(KeyCode.DownArrow)) { Rb.velocity = new Vector3(0,0,-speed); } else { Rb.velocity = Vector3.zero; }

追記(2021年7月26日)

 距離2m時点では、1個発生するのですが、 4mほど動かした結果、Instantiateが止まらず、ダダ洩れるような状態になってしまいました。
イメージ説明
いただいた動画のように一つずつの発生方法について、ご教示いただけると幸いです。

追記 ロープの巻き取りについて

 「ホースリールのように」と申し上げましたが、実際は回転部分はダミーで、ただアニメーションで回すだけで、根本部分から今回のロープ発生を考えています。
イメージ説明

初歩的な質問でお手数をおかけいたしますが、ご教示いただけると幸いです。

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

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

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

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

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

y_waiwai

2021/07/06 08:48

で、しつもんはなんでしょうか
DY2peace

2021/07/06 09:26

わかりづらい質問で申し訳ございませんでした。 ↑キーを押したときにボールの発生をさせかつジョイントで接続されながら、ロープが伸びる方法と逆に↓キーを押したら、ロープが縮む方法をご教示いただけたらと思います。
guest

回答2

0

ベストアンサー

ボールを生成するのはおっしゃるようにInstantiateを使えばいいでしょうし、不要なボールはDestroyで削除してやればいいかと思います。
ボールの生成・削除自体よりも、むしろどういう条件で生成するか、削除するかということの方が悩みどころかもしれませんね。
ちょっと思いつきを申し上げさせていただきますと...

  • 操作ボールと鎖の末端ボールとの距離がボール設置間隔以上に離れたらボールを追加する。

図1

  • 操作ボールと鎖の末端ボールをつなぐ線分が大きく折れ曲がっている場合、末端ボールを削除する。

図2

という規則はどうでしょうか。下記のようなスクリプトを試したところ...

lang

1using UnityEngine; 2 3public class ChainGenerator : MonoBehaviour 4{ 5 public GameObject jyakanBall; // ボールのプレハブ...すでにRigidbodyを持っていると想定 6 public GameObject firstBall; // firstBallはあらかじめシーン上に存在していると想定 7 public Transform firstPosiBase; // ボール発射初期位置 8 public float speed = 10; // ボールの速度 9 public float interval = 2.0f; // ボールを設置する間隔 10 11 private Rigidbody firstRigidbody; 12 private Rigidbody terminalRigidbody; 13 private ConfigurableJoint primaryJoint; 14 private ConfigurableJoint secondaryJoint; 15 16 private void Start() 17 { 18 this.firstRigidbody = this.firstBall.GetComponent<Rigidbody>(); 19 var firstPosition = this.firstPosiBase.transform.position; 20 this.firstBall.transform.position = firstPosition; 21 22 // 初期位置に根元のボールを設置 23 this.terminalRigidbody = Instantiate(this.jyakanBall, firstPosition, Quaternion.identity).GetComponent<Rigidbody>(); 24 25 // ヒエラルキー上で確認しやすくするため、ボールには「プレハブ名 連番」のスタイルの名前を付ける 26 // 根元のボールは0番とする 27 this.terminalRigidbody.name = $"{this.jyakanBall.name} 0"; 28 29 // 根元は初期位置に固定することにする 30 this.terminalRigidbody.gameObject.AddComponent<FixedJoint>(); 31 32 // firstBallはまず根元と接続する 33 this.primaryJoint = this.firstRigidbody.gameObject.AddComponent<ConfigurableJoint>(); 34 this.primaryJoint.connectedBody = this.terminalRigidbody; 35 } 36 37 private void FixedUpdate() 38 { 39 // terminalRigidbodyに対するfirstBallの相対位置をrelativePositionとする 40 var ballPosition = this.firstRigidbody.position; 41 var relativePosition = ballPosition - this.terminalRigidbody.position; 42 43 // その相対位置ベクトルの長さがinterval以上であればボールを追加する 44 while (relativePosition.magnitude >= this.interval) 45 { 46 // terminalRigidbodyからintervalだけ離れた位置に新規ボールを設置する 47 var newTerminalPosition = this.terminalRigidbody.position + Vector3.ClampMagnitude(relativePosition, this.interval); 48 var newTerminalRigidbody = Instantiate(this.jyakanBall, newTerminalPosition, Quaternion.identity).GetComponent<Rigidbody>(); 49 var previousTerminalName = this.terminalRigidbody.name; 50 var previousTerminalIndex = int.Parse(previousTerminalName.Substring(previousTerminalName.LastIndexOf(' ') + 1)); 51 newTerminalRigidbody.name = $"{this.jyakanBall.name} {previousTerminalIndex + 1}"; 52 53 // ジョイントもアタッチし、既存のジョイントをつなぎ替える 54 this.secondaryJoint = newTerminalRigidbody.gameObject.AddComponent<ConfigurableJoint>(); 55 this.secondaryJoint.connectedBody = this.terminalRigidbody; 56 this.secondaryJoint.xMotion = ConfigurableJointMotion.Locked; 57 this.secondaryJoint.yMotion = ConfigurableJointMotion.Locked; 58 this.secondaryJoint.zMotion = ConfigurableJointMotion.Locked; 59 this.primaryJoint.connectedBody = newTerminalRigidbody; 60 61 // 新しいボールを次のterminalRigidbodyとし、relativePositionも更新する 62 this.terminalRigidbody = newTerminalRigidbody; 63 relativePosition = ballPosition - this.terminalRigidbody.position; 64 } 65 66 // secondaryJointが存在するならば、つまり根元とfirstRigidbodyの間に1つ以上ボールが 67 // 存在するならば、さらにrelativePositionがどれだけ折れ曲がっているかを調べる 68 while ((this.secondaryJoint != null) && (Vector3.Dot(relativePosition, this.terminalRigidbody.position - this.secondaryJoint.connectedBody.position) < 0.0f)) 69 { 70 // もし90°を超えて曲がっていれば、鎖を縮めようとしているものと見なし 71 // ジョイントのつなぎ替えを行い、terminalRigidbodyを削除する 72 this.primaryJoint.connectedBody = this.secondaryJoint.connectedBody; 73 Destroy(this.terminalRigidbody.gameObject); 74 75 // primaryJointの接続先を次のterminalRigidbodyとし、secondaryJointとrelativePositionも更新する 76 this.terminalRigidbody = this.primaryJoint.connectedBody; 77 this.secondaryJoint = this.terminalRigidbody.GetComponent<ConfigurableJoint>(); 78 relativePosition = ballPosition - this.terminalRigidbody.position; 79 } 80 81 // キーボード操作でfirstRigidbodyを移動 82 // (ご質問者さんの場合は速度のY成分も含めて書き換えている様子ですが、それだと 83 // 落下の動きがゆったりしてしまい、挙動の実演には向かないかな...と思いまして、 84 // Y成分を残すようにしています) 85 var velocity = this.firstRigidbody.velocity; 86 velocity.z = 0.0f; 87 if (Input.GetKey(KeyCode.UpArrow)) 88 { 89 velocity.z += this.speed; 90 } 91 if (Input.GetKey(KeyCode.DownArrow)) 92 { 93 velocity.z -= this.speed; 94 } 95 this.firstRigidbody.velocity = velocity; 96 } 97}

下図のような動きになりました。

図3

投稿2021/07/24 11:03

Bongo

総合スコア10807

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

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

DY2peace

2021/07/26 12:23

いつもご回答いただきありがとうございます。 本日の日付分で追記いたしましたが、2mほど動かしたときには問題なく一つ発生するのですが、距離4m位置時点で、instantiateが止まらず、ボールの発生が止まらない状態になってしまいました。 jyakanball はPrefabで使っていたので、それが問題かと思って直しても見ましたが、結果は変わりませんでした。 お手数をおかけして申し訳ございませんがご教示いただけると幸いです。
Bongo

2021/07/26 14:13

うう...予想外の不具合が起きてしまいましたね... なるべくご質問者さんのシーンの構成に似せた条件で試してみれば何か手がかりが得られるかもしれません。私の場合は... - jyakanBallプレハブはメニューから作成したSphereにRigidbodyをアタッチしただけのもので、それ以外にスクリプトなどはアタッチされていない。マテリアルは黄色に変えたが、これは挙動に影響しないはず。 - firstBallはjyakanBallプレハブをシーン上にドラッグ&ドロップしてインスタンス化したもので、構造的にはjyakanBallプレハブと同一。マテリアルだけ赤色に変えたが、これも挙動には影響しないはず。 - firstPosiBaseは単なる空のゲームオブジェクトで、スクリプトやその他コンポーネントはアタッチしていない。鎖の根元の位置を決めるためだけのもの。 - ChainGeneratorスクリプトは、シーン上に空のゲームオブジェクトを作ってそれにアタッチした。そしてインスペクター上でシーン上のfirstBallとfirstPosiBase、プロジェクトビュー上のjyakanBallプレハブをセットしている。 といった構成です。ご質問者さんのシーン構成と比べて相違点がありましたら、ぜひコメントください。 また、私の例示しましたスクリプトはご質問者さんがご提示いただいたスクリプトがベースになっているものの、思考の整理のためフィールド名だとかを一部変更してしまいました。ですので、ご質問者さんが私の案をお試しいただいた際には、もしかするとご質問者さんのシーン構成に合わせて何らかの変更を加えていらっしゃるかもしれません。その場合は、ご質問者さんが現状お使いのスクリプトもご提示いただけるとありがたいです。
DY2peace

2021/07/26 16:01

よく確認しておらずすみません。JyakanBallのPrefabに重力Onの状態にしていたら、この現象が起きたみたいです。  できれば、このロープには重力を働かせたいと考えております。 またボールの発生点もできれば、根本側から発生させ、FirstBallに引っ張れるような形でできたらうれしいです。イメージは無限に伸びる回転台付ホースリールのような感じを考えてます。
Bongo

2021/07/26 23:04

ご説明ありがとうございます。私の提示しました実験図ではご覧の通り鎖を足場の上に横たえていますが、確かに足場がないと鎖の自重でどんどんボールが引き出されてしまいますね。また、ボールの発生点を根本側にしたいという件も了承しました。何か案が思いついたら追記いたします。 それにあたってうかがいたいのですが、鎖の硬さはどの程度を想定していらっしゃるでしょうか。最初に例示していただいたObi Ropeの図では、ロープはある程度たわんでいるものの、おおむね棒状の形を維持しているように見えます。あれぐらいの硬さを持たせていいのでしたら、回答に提示しました方式をベースに先端と根元の関係を逆転させればうまくいくのではないか...ともくろんでいるのですが、ホースのような柔らかさだと先端を引っ張ってリールからホースを引き出すことはできるでしょうが、先端を押し込んでホースを巻き取らせようとしてもホースがたわんでぐにゃぐにゃになってしまいそうです。もしそういった柔らかい鎖をご希望でしたら、ボール生成・削除のルールを見直す必要があるかもしれません。
DY2peace

2021/07/27 02:44

いえ、こちらこそご回答ありがとうございます。  ホースリールの件、追加で絵を追記しました。巻き取り部分は今回はダミーで考えていますので、いったん忘れてください。  鎖の硬さですが、最終的にはConfigurableJointのパラメータで再現したいなと考えています。リミット角の制限、角度Springの強さで調整できると思いますので、最後に設定追加すればいいかなと考えてました。 なので今回は、ぐにゃぐにゃのロープでも大丈夫です。 ご迷惑をおかけいたしますがよろしくお願いいたします。
Bongo

2021/07/28 13:00

返信が遅くなりすみません。ある程度の硬さがあれば単純に先端と根元を逆転させればいいかと申し上げましたが、実際試してみると挙動が不安定になってしまい、結局ボールの繰り出しと巻き取りを異なるロジックで実装することにしました。投稿字数の限界に達してしまったので別回答となりすみませんが、変更案を投稿いたします。以前のご質問の折にも体験しましたが、ConfigurableJointはただでさえ設定項目が多いのに加えて、それを鎖状に繋げるとなると予想外の挙動が出てきて実に強敵ですね...
DY2peace

2021/07/28 15:19 編集

ご対応いただき誠にありがとうございます。ほぼ自分が意図していた通りの動きになっています。 ConfigurableJointのロック≠FixedJointみたいで、どうしてもConfigJointは崩れやすいのは仕方ないのかなと思います。 また全体のスケールを変えたり、Joint側のMassScaleを変えたりすると、硬さが強くなったりもするので、その部分もいじってみたいと思います。 これから確認しますので、そのあとに高評価押させてください。(明日いっぱいまでお待ちください)
DY2peace

2021/07/29 01:18

Unityで確認いたしました。 完璧な想定通りの動きです。大変助かりました。ありがとうございます。 高評価押させていただきます。
guest

0

##根元をボール発生源にする件について

スクリプトを下記のように変更してみました。上矢印キーで先端を引っ張ってボールを引き出し、下矢印キーで根元のリールを巻き取ってボールを回収するイメージで作ってみました。

lang

1using UnityEngine; 2 3public class ChainGenerator2 : MonoBehaviour 4{ 5 public GameObject jyakanBall; // ボールのプレハブ...すでにRigidbodyを持っていると想定 6 public GameObject firstBall; // FirstBallはあらかじめシーン上に存在していると想定 7 public Transform firstPosiBase; // ボール発射初期位置 8 public float speed = 10; // ボールの速度 9 public float interval = 2.0f; // ボールを設置する間隔 10 public float angularLimit = 6.0f; // ジョイントの曲がる角度の上限 11 public float spring = 100.0f; 12 public float damper = 10.0f; 13 14 private Rigidbody rootRigidbody; 15 private Rigidbody firstChildRigidbody; 16 private Rigidbody firstRigidbody; 17 private ConfigurableJoint primaryJoint; 18 private ConfigurableJoint secondaryJoint; 19 private Vector3 connectedAnchor; 20 private SoftJointLimit highLimit; 21 private SoftJointLimit lowLimit; 22 private JointDrive drive; 23 private bool isWinding; 24 25 // primaryJointを巻き取りモードに切り替えるプロパティ 26 private bool IsWinding 27 { 28 get => this.isWinding; 29 set 30 { 31 this.isWinding = value; 32 var joint = this.primaryJoint; 33 if (value) 34 { 35 joint.connectedAnchor = joint.connectedBody.transform.InverseTransformPoint(this.rootRigidbody.position); 36 joint.zMotion = ConfigurableJointMotion.Locked; 37 } 38 else 39 { 40 joint.zMotion = ConfigurableJointMotion.Free; 41 } 42 } 43 } 44 45 private void Start() 46 { 47 this.firstRigidbody = this.firstBall.GetComponent<Rigidbody>(); 48 var firstPosition = this.firstPosiBase.transform.position; //ボールの発生する位置の設定 49 this.firstBall.transform.position = firstPosition; //初期位置に初期ボールを移動させる 50 51 // 初期位置に根元のボールを設置 52 this.rootRigidbody = Instantiate(this.jyakanBall, firstPosition, Quaternion.identity).GetComponent<Rigidbody>(); 53 54 // 「firstChildRigidbody」はrootRigidbodyと直結している直接の子を表す 55 // まずはfirstBallをfirstChildRigidbodyとする 56 this.firstChildRigidbody = this.firstRigidbody; 57 58 // ヒエラルキー上での確認を容易にするため、ボールには「プレハブ名 連番」の形の名前を付ける 59 // rootRigidbodyは特別扱いで連番は付けず(さしあたり「プレハブ名 Root」とする)、firstBallを0番とする 60 this.rootRigidbody.name = $"{this.jyakanBall.name} Root"; 61 this.firstChildRigidbody.name = $"{this.jyakanBall.name} 0"; 62 63 // 根元は初期位置に固定することにする 64 this.rootRigidbody.gameObject.AddComponent<FixedJoint>(); 65 66 // rootRigidbodyとfirstChildRigidbodyを接続する 67 this.connectedAnchor = Vector3.back * this.interval; 68 this.highLimit = new SoftJointLimit {limit = this.angularLimit}; 69 this.lowLimit = this.highLimit; 70 this.lowLimit.limit *= -1.0f; 71 this.drive = new JointDrive 72 { 73 maximumForce = float.MaxValue, 74 positionSpring = this.spring, 75 positionDamper = this.damper 76 }; 77 this.primaryJoint = this.rootRigidbody.gameObject.AddComponent<ConfigurableJoint>(); 78 { 79 var joint = this.primaryJoint; 80 joint.rotationDriveMode = RotationDriveMode.XYAndZ; 81 joint.angularXDrive = joint.angularYZDrive = this.drive; 82 joint.xMotion = joint.yMotion = ConfigurableJointMotion.Locked; 83 joint.zMotion = ConfigurableJointMotion.Free; 84 joint.angularXMotion = joint.angularYMotion = ConfigurableJointMotion.Limited; 85 joint.angularZMotion = ConfigurableJointMotion.Locked; 86 joint.highAngularXLimit = joint.angularYLimit = this.highLimit; 87 joint.lowAngularXLimit = this.lowLimit; 88 joint.anchor = Vector3.zero; 89 joint.autoConfigureConnectedAnchor = false; 90 joint.connectedAnchor = Vector3.zero; 91 joint.connectedBody = this.firstChildRigidbody; 92 } 93 } 94 95 // 下矢印キーを押し下げると巻き取りモード、離すと通常モードとする 96 private void Update() 97 { 98 if (Input.GetKeyDown(KeyCode.DownArrow)) 99 { 100 this.IsWinding = true; 101 } 102 103 if (Input.GetKeyUp(KeyCode.DownArrow)) 104 { 105 this.IsWinding = false; 106 } 107 } 108 109 private void FixedUpdate() 110 { 111 var rootPosition = this.rootRigidbody.position; 112 var rootRotation = this.rootRigidbody.rotation; 113 114 // キーボード操作でfirstRigidbodyを移動 115 var velocity = this.firstRigidbody.velocity; 116 velocity.z = 0.0f; 117 if (this.IsWinding) 118 { 119 // 巻き取りモードの場合、connectedAnchorを縮めることでリールの巻き取りを表現する 120 this.primaryJoint.connectedAnchor = Vector3.MoveTowards( 121 this.primaryJoint.connectedAnchor, 122 Vector3.zero, 123 this.speed * Time.deltaTime); 124 125 // secondaryJointが存在するならば、つまりfirstChildRigidbodyの次に1つ以上ボールが 126 // 存在するならば、さらにconnectedAnchorがほぼゼロまで縮んだかを調べる 127 while ((this.secondaryJoint != null) && (this.primaryJoint.connectedAnchor.sqrMagnitude < 0.01f)) 128 { 129 // connectedAnchorが縮みきっていればジョイントのつなぎ替えを行い、firstChildRigidbodyを削除する 130 var newFirstChildRigidbody = this.secondaryJoint.connectedBody; 131 var newFirstChildPosition = newFirstChildRigidbody.position; 132 var newFirstChildRotation = newFirstChildRigidbody.rotation; 133 DestroyImmediate(this.firstChildRigidbody.gameObject); 134 this.primaryJoint.connectedAnchor = newFirstChildRigidbody.transform.InverseTransformPoint(rootPosition); 135 newFirstChildRigidbody.position = rootPosition; 136 newFirstChildRigidbody.rotation = rootRotation; 137 this.primaryJoint.connectedBody = newFirstChildRigidbody; 138 newFirstChildRigidbody.position = newFirstChildPosition; 139 newFirstChildRigidbody.rotation = newFirstChildRotation; 140 141 // primaryJointの接続先を次のfirstChildRigidbodyとし、secondaryJointも更新する 142 this.firstChildRigidbody = newFirstChildRigidbody; 143 this.secondaryJoint = newFirstChildRigidbody.GetComponent<ConfigurableJoint>(); 144 } 145 } 146 else 147 { 148 if (Input.GetKey(KeyCode.UpArrow)) 149 { 150 velocity.z += this.speed; 151 } 152 153 // firstChildRigidbodyに対するrootRigidbodyの相対位置をrelativePositionとする 154 var ballPosition = this.firstChildRigidbody.position; 155 var ballRotation = this.firstChildRigidbody.rotation; 156 var relativePosition = rootPosition - ballPosition; 157 158 // その相対位置ベクトルの長さがinterval以上であればボールを追加する 159 var distance = relativePosition.magnitude; 160 while (distance >= this.interval) 161 { 162 // firstChildRigidbodyからintervalだけ離れた位置に新規ボールを設置する 163 var newFirstChildPosition = ballPosition + Vector3.ClampMagnitude(relativePosition, this.interval); 164 var newFirstChildRigidbody = Instantiate(this.jyakanBall, rootPosition, rootRotation).GetComponent<Rigidbody>(); 165 var previousFirstChildName = this.firstChildRigidbody.name; 166 var previousFirstChildIndex = int.Parse(previousFirstChildName.Substring(previousFirstChildName.LastIndexOf(' ') + 1)); 167 newFirstChildRigidbody.name = $"{this.jyakanBall.name} {previousFirstChildIndex + 1}"; 168 169 // ジョイントもアタッチし、既存のジョイントをつなぎ替える 170 this.firstChildRigidbody.position = rootPosition; 171 this.firstChildRigidbody.rotation = rootRotation; 172 this.secondaryJoint = newFirstChildRigidbody.gameObject.AddComponent<ConfigurableJoint>(); 173 { 174 var joint = this.secondaryJoint; 175 joint.rotationDriveMode = RotationDriveMode.XYAndZ; 176 joint.angularXDrive = joint.angularYZDrive = this.drive; 177 joint.xMotion = joint.yMotion = joint.zMotion = ConfigurableJointMotion.Locked; 178 joint.angularXMotion = joint.angularYMotion = ConfigurableJointMotion.Limited; 179 joint.angularZMotion = ConfigurableJointMotion.Locked; 180 joint.highAngularXLimit = joint.angularYLimit = this.highLimit; 181 joint.lowAngularXLimit = this.lowLimit; 182 joint.anchor = Vector3.zero; 183 joint.autoConfigureConnectedAnchor = false; 184 joint.connectedAnchor = this.connectedAnchor; 185 joint.connectedBody = this.firstChildRigidbody; 186 } 187 this.primaryJoint.connectedBody = newFirstChildRigidbody; 188 newFirstChildRigidbody.position = newFirstChildPosition; 189 newFirstChildRigidbody.rotation = Quaternion.Lerp(ballRotation, rootRotation, this.interval / distance); 190 this.firstChildRigidbody.position = ballPosition; 191 this.firstChildRigidbody.rotation = ballRotation; 192 193 // 新しいボールを次のfirstChildRigidbodyとし、ballPositionとrelativePositionも更新する 194 this.firstChildRigidbody = newFirstChildRigidbody; 195 ballPosition = this.firstChildRigidbody.position; 196 relativePosition = rootPosition - ballPosition; 197 distance = relativePosition.magnitude; 198 } 199 } 200 201 this.firstRigidbody.velocity = velocity; 202 } 203}

デフォルトの設定値で動かすと下図のようになります。

図1

鎖の硬さについてですが、設定値をもっと硬くしてもさほど挙動は変化しなさそうでした。制限角度を大きくするなどの柔らかくする方向ではそれなりの効果があったのですが...

図2

もっと硬くして、制限角度を0°にしたとしてもけっこうたわんでしまうかと思います。これはもはや物理シミュレーション上の限界なのかもしれません。これ以上硬い棒を表現するとなると、下図のようにボールの間隔を広げてジョイントの数を減らす必要があるかもしれません。

図3

投稿2021/07/28 13:00

Bongo

総合スコア10807

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問