Skip to content

Instantly share code, notes, and snippets.

@nkjzm
Created March 5, 2016 19:32
Show Gist options
  • Save nkjzm/a7052c1ee9a5fd4a57b6 to your computer and use it in GitHub Desktop.
Save nkjzm/a7052c1ee9a5fd4a57b6 to your computer and use it in GitHub Desktop.
リアルタイムに布シミュレーションをしながらメッシュを動的に変化させるスクリプト
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
[RequireComponent(typeof(SkinnedMeshRenderer))]
[RequireComponent(typeof(Cloth))]
public class DynamicCreateMesh : MonoBehaviour
{
[SerializeField]
private Material _mat;
private SkinnedMeshRenderer meshRenderer;
public List<Vector3> vertices;
List<Square> squares;
[SerializeField]
private float size = 1f;
[SerializeField]
private int height = 20;
[SerializeField]
private int width = 10;
// 四角形の情報
public class Square
{
public int h, w;
public List<int> triangles;
public Square (int _h, int _w, List<int> _triangles)
{
h = _h;
w = _w;
triangles = _triangles;
}
}
private Square GetSquare (int _h, int _w)
{
foreach (Square st in squares) {
if (st.h == _h && st.w == _w) {
return st;
}
}
return null;
}
private void Start ()
{
//メッシュをセットするよ
meshRenderer = GetComponent<SkinnedMeshRenderer> ();
// メッシュ情報を扱いやすいように保持しておくよ
squares = new List<Square> ();
vertices = new List<Vector3> ();
for (int h = 0; h < height; ++h) {
for (int w = 0; w < width; ++w) {
vertices.Add (new Vector3 ((1f + w) * size, 0, (1f + h) * size));
vertices.Add (new Vector3 ((1f + w) * size, 0, (0f + h) * size));
vertices.Add (new Vector3 ((0f + w) * size, 0, (0f + h) * size));
vertices.Add (new Vector3 ((0f + w) * size, 0, (1f + h) * size));
List<int> triangles = new List<int> ();
triangles.Add (0 + (w + (h * width)) * 4);
triangles.Add (1 + (w + (h * width)) * 4);
triangles.Add (2 + (w + (h * width)) * 4);
triangles.Add (0 + (w + (h * width)) * 4);
triangles.Add (2 + (w + (h * width)) * 4);
triangles.Add (3 + (w + (h * width)) * 4);
// 反対側からの描画にも対応
triangles = DuplicateReverseTriangles (triangles);
squares.Add (new Square (h, w, triangles));
}
}
UpdateMesh (true);
}
private void UpdateMesh (bool isInit = false)
{
var mesh = isInit ? new Mesh () : meshRenderer.sharedMesh;
List<int> allTriangles = new List<int> ();
foreach (Square st in squares) {
allTriangles.AddRange (st.triangles);
}
mesh.Clear ();
mesh.vertices = vertices.ToArray ();
mesh.triangles = allTriangles.ToArray ();
meshRenderer.sharedMesh = mesh;
}
private List<int> DuplicateReverseTriangles (List<int> triangles)
{
int setCount = triangles.Count / 3;
for (int i = 0; i < setCount; ++i) {
triangles.Add (triangles [0 + (i * 3)]);
triangles.Add (triangles [2 + (i * 3)]);
triangles.Add (triangles [1 + (i * 3)]);
}
return triangles;
}
// 指定した四角形を切断
// 一旦テスト用に単純な分割のみに対応
public void Cut (int h, int w)
{
Square square = GetSquare (h, w);
int maxIndex = vertices.Count;
float bottomRate = 0.8f;
float topRate = 0.8f;
float interval = 0.05f;
vertices.Add (new Vector3 ((bottomRate + interval + w) * size, 0, (0f + h) * size));
vertices.Add (new Vector3 ((topRate + interval + w) * size, 0, (1f + h) * size));
vertices.Add (new Vector3 ((topRate - interval + w) * size, 0, (1f + h) * size));
vertices.Add (new Vector3 ((bottomRate - interval + w) * size, 0, (0f + h) * size));
List<int> triangles = new List<int> ();
triangles.Add (0 + (w + (h * width)) * 4);
triangles.Add (1 + (w + (h * width)) * 4);
triangles.Add (0 + maxIndex);
triangles.Add (0 + (w + (h * width)) * 4);
triangles.Add (0 + maxIndex);
triangles.Add (1 + maxIndex);
triangles.Add (2 + maxIndex);
triangles.Add (3 + maxIndex);
triangles.Add (2 + (w + (h * width)) * 4);
triangles.Add (2 + maxIndex);
triangles.Add (2 + (w + (h * width)) * 4);
triangles.Add (3 + (w + (h * width)) * 4);
triangles = DuplicateReverseTriangles (triangles);
square.triangles = triangles;
maxIndex += 4;
UpdateMesh ();
}
public void Execute()
{
for (int h = 0; h < height; ++h) {
Cut (h, width / 2);
}
}
void Update ()
{
// スペースキーで切断実行
if (Input.GetKeyDown (KeyCode.Space)) {
Execute ();
}
}
}
@nkjzm
Copy link
Author

nkjzm commented Mar 5, 2016

この記事で説明?してあります。
http://kohki.hatenablog.jp/entry/UnityDynamicCutClothImpossible

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment