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に強い力が加わることがあります。
この理由はよくわかりません。