Created
March 5, 2016 19:32
-
-
Save nkjzm/a7052c1ee9a5fd4a57b6 to your computer and use it in GitHub Desktop.
リアルタイムに布シミュレーションをしながらメッシュを動的に変化させるスクリプト
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 (); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
この記事で説明?してあります。
http://kohki.hatenablog.jp/entry/UnityDynamicCutClothImpossible