Clothコンポーネントを付けたオブジェクトに玉を衝突させてみました。
まず、BlenderでPlaneメッシュを作って、細分化してUnityに持ってきました。
これにClothコンポーネントをつけて、Edit cloth constraintsボタンを押します。
シーン画面にClothの頂点を固定するツールが表示されるので、「Select」を押して、マウスドラッグでPlaneの一番上の頂点だけを矩形選択します。
そして、Max Distanceにチェックを入れて、値を0にします。
Sphereオブジェクトを新規作成して、SphereコライダーとRigidbodyを付けます。
これをProjectのどこかにドラッグアンドドロップしてプレハブ化します。
この玉とClothに衝突できるようにしますが、Clothコンポーネントでは玉がClothに影響を与えても、Clothが玉に影響を与えて玉が反発するということはないので、玉はClothを通り抜けます。
https://docs.unity3d.com/ja/2018.4/Manual/class-Cloth.html
スクリプトでClothに玉が衝突できるようにする
Clothが他のオブジェクトと衝突できるようにするには、Clothコンポーネントに衝突させたいコライダーをアタッチします。
Clothの使い方はこちら
それをプレイ中にスクリプトで行います。
- using System.Collections;
- using System.Collections.Generic;
- using UnityEngine;
-
- public class ThrowBallScript3 : MonoBehaviour
- {
-
- public GameObject ball;
- public float thrust = 10f;
- public GameObject plane;
-
- Vector3 cursorPosition;
- Vector3 cursorPosition3d;
- RaycastHit hit;
- Vector3 cameraPosition;
- Vector3 throwDirection;
- GameObject rb_ball;
-
- Cloth planeCloth;
- ClothSphereColliderPair[] ballColliders;
- int n;
-
- // Start is called before the first frame update
- void Start()
- {
- planeCloth = plane.GetComponent<Cloth>(); // Clothコンポーネントを取得
- ballColliders = new ClothSphereColliderPair[10];
- n = 0;
- }
-
- // Update is called once per frame
- void Update()
- {
-
- if (Input.GetMouseButtonDown(0)) // マウスの左クリックをしたとき
- {
- rb_ball = Instantiate(ball, Camera.main.transform.position, transform.rotation); // 玉を生成
- rb_ball.GetComponent<Rigidbody>().AddForce(ThrowDirection() * thrust, ForceMode.Impulse); // カーソルの方向に力を一度加える
- rb_ball.name = n.ToString();
-
- ballColliders.SetValue(new ClothSphereColliderPair(rb_ball.GetComponent<SphereCollider>()), n);
- planeCloth.sphereColliders = ballColliders;
-
- n++;
- if (n > 9) n = 0; // 10以上でnを0に戻す
- }
- }
-
- Vector3 ThrowDirection()
- {
- cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
- cursorPosition.z = 10.0f; // z座標に適当な値を入れる
- cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす
-
- return cursorPosition3d - Camera.main.transform.position; // 玉を飛ばす方向
- }
- }
空のゲームオブジェクトを新規作成して上のスクリプトを付けました。
同じスクリプトで玉を発射していますが、それはこちらの記事で解説しています。
Clothコンポーネントにコライダーをアタッチするには、Clothコンポーネントの「Sphere Colliders」のSizeにその数を、各要素にSphereコライダーを入れます。
2つのSphereコライダーを入れると、それらをつなげた円錐カプセル形を定義できます。1つだけを使うときはSecondをnullにします。
この「Sphere Colliders」は、ClothSphereColliderPair型の配列なので、玉を生成したときにClothSphereColliderPair型の配列に要素を追加して、それをSphere Collidersメンバに代入してみました。
- ballColliders = new ClothSphereColliderPair[10];
- // ---
- ballColliders.SetValue(new ClothSphereColliderPair(rb_ball.GetComponent<SphereCollider>()), n);
- planeCloth.sphereColliders = ballColliders;
玉の数を10個に制限しているので、インデックスに使うnを発射のたびに1増加させて、10以上のときに0に戻るようにしています。
すると、プレイ中に玉を発射したときに、Clothコンポーネントにコライダーがアタッチされていきます。
11個目のコライダーは1個目のコライダーと入れ替わります。
Clothを制御する
Clothコンポーネントで曲げ剛性や減衰を上げると、Clothの動きが鈍くなって荒ぶりにくくなります。
ですが、玉の制限を少なくして玉を連射すると、たまにClothに強い力が加わることがあります。
この理由はよくわかりません。