UnityでClothに玉を衝突させる

投稿者: | 2020-03-07


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の使い方はこちら

それをプレイ中にスクリプトで行います。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4.  
  5. public class ThrowBallScript3 : MonoBehaviour
  6. {
  7.  
  8. public GameObject ball;
  9. public float thrust = 10f;
  10. public GameObject plane;
  11.  
  12. Vector3 cursorPosition;
  13. Vector3 cursorPosition3d;
  14. RaycastHit hit;
  15. Vector3 cameraPosition;
  16. Vector3 throwDirection;
  17. GameObject rb_ball;
  18.  
  19. Cloth planeCloth;
  20. ClothSphereColliderPair[] ballColliders;
  21. int n;
  22.  
  23. // Start is called before the first frame update
  24. void Start()
  25. {
  26. planeCloth = plane.GetComponent<Cloth>(); // Clothコンポーネントを取得
  27. ballColliders = new ClothSphereColliderPair[10];
  28. n = 0;
  29. }
  30.  
  31. // Update is called once per frame
  32. void Update()
  33. {
  34.  
  35. if (Input.GetMouseButtonDown(0)) // マウスの左クリックをしたとき
  36. {
  37. rb_ball = Instantiate(ball, Camera.main.transform.position, transform.rotation); // 玉を生成
  38. rb_ball.GetComponent<Rigidbody>().AddForce(ThrowDirection() * thrust, ForceMode.Impulse); // カーソルの方向に力を一度加える
  39. rb_ball.name = n.ToString();
  40.  
  41. ballColliders.SetValue(new ClothSphereColliderPair(rb_ball.GetComponent<SphereCollider>()), n);
  42. planeCloth.sphereColliders = ballColliders;
  43.  
  44. n++;
  45. if (n > 9) n = 0; // 10以上でnを0に戻す
  46. }
  47. }
  48.  
  49. Vector3 ThrowDirection()
  50. {
  51. cursorPosition = Input.mousePosition; // 画面上のカーソルの位置
  52. cursorPosition.z = 10.0f; // z座標に適当な値を入れる
  53. cursorPosition3d = Camera.main.ScreenToWorldPoint(cursorPosition); // 3Dの座標になおす
  54.  
  55. return cursorPosition3d - Camera.main.transform.position; // 玉を飛ばす方向
  56. }
  57. }

空のゲームオブジェクトを新規作成して上のスクリプトを付けました。

同じスクリプトで玉を発射していますが、それはこちらの記事で解説しています。

Clothコンポーネントにコライダーをアタッチするには、Clothコンポーネントの「Sphere Colliders」のSizeにその数を、各要素にSphereコライダーを入れます。

2つのSphereコライダーを入れると、それらをつなげた円錐カプセル形を定義できます。1つだけを使うときはSecondをnullにします。

この「Sphere Colliders」は、ClothSphereColliderPair型の配列なので、玉を生成したときにClothSphereColliderPair型の配列に要素を追加して、それをSphere Collidersメンバに代入してみました。

  1. ballColliders = new ClothSphereColliderPair[10];
  2. // ---
  3. ballColliders.SetValue(new ClothSphereColliderPair(rb_ball.GetComponent<SphereCollider>()), n);
  4. planeCloth.sphereColliders = ballColliders;

玉の数を10個に制限しているので、インデックスに使うnを発射のたびに1増加させて、10以上のときに0に戻るようにしています。

すると、プレイ中に玉を発射したときに、Clothコンポーネントにコライダーがアタッチされていきます。

11個目のコライダーは1個目のコライダーと入れ替わります。

Clothを制御する

Clothコンポーネントで曲げ剛性や減衰を上げると、Clothの動きが鈍くなって荒ぶりにくくなります。

ですが、玉の制限を少なくして玉を連射すると、たまにClothに強い力が加わることがあります。

この理由はよくわかりません。

コメントを残す

メールアドレスが公開されることはありません。