プロシージャルに「じゃばら」を生成します。

b.gif

空のゲームオブジェクトにアタッチすれば使えるはずです。

using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(MeshRenderer))]
[RequireComponent(typeof(MeshFilter))]
public class Procedural_Jabara : MonoBehaviour {

    float _height = 5; // 今の高さ
    float pre_height = -1; // 前のフレームの高さ
    float valueConst = -1; // 体積。常にこれが一定となるようにする。
    Transform handleTransform;

    Vector3[] GenCircle(float r, float h, Vector3? offset = null, int divNum = 10)
    {
        List<Vector3> vv = new List<Vector3>();
        for (int i = 0; i < divNum; i++)
        {
            float rad = (float)i / divNum * 2 * Mathf.PI;
            Vector3 pos = new Vector3(r * Mathf.Cos(rad), h, r * Mathf.Sin(rad));
            // デバック用の球体を生成する
            {
                //var t = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
                //t.parent = transform;
                //t.position = pos;
                //t.position += offset ?? Vector3.zero;
                //t.localScale = Vector3.one * 0.05f;
            }
            vv.Add(pos);
        }

        return vv.ToArray();
    }

    void Vertex2ListIn(Vector3[] lowerCircle, Vector3[] upperCircle, ref List<Vector3> vv)
    {
        for (int j = 0; j < lowerCircle.Length; j++)
        {
            if (j < lowerCircle.Length - 1)
            {
                // 下側の三角形
                vv.Add(lowerCircle[j]);
                vv.Add(upperCircle[j]);
                vv.Add(lowerCircle[j + 1]);

                // 上側の三角形
                vv.Add(upperCircle[j]);
                vv.Add(upperCircle[j + 1]);
                vv.Add(lowerCircle[j + 1]);
            }
            else
            {
                // 一番最後だけ例外処理
                vv.Add(lowerCircle[j]);
                vv.Add(upperCircle[j]);
                vv.Add(lowerCircle[0]);

                vv.Add(upperCircle[j]);
                vv.Add(upperCircle[0]);
                vv.Add(lowerCircle[0]);
            }
        }
    }

    void ReCalcBaneMesh(float r, float height)
    {
        Mesh mesh = new Mesh();
        mesh.name = "baneMesh";

        List<Vector3> vv = new List<Vector3>();

        Vector3[] preUpperCircle = null;

        const int divNum = 10;

        float h = height / divNum;

        for (int i = 0; i < divNum; i++)
        {
            var lowerCircle = GenCircle(r, i * h);
            var upperCircle = GenCircle(r * 0.75f, (i + 0.5f) * h);

            if (preUpperCircle != null)
            {
                Vertex2ListIn(preUpperCircle, lowerCircle, ref vv);
            }

            Vertex2ListIn(lowerCircle, upperCircle, ref vv);

            preUpperCircle = upperCircle;
        }

        mesh.vertices = vv.ToArray();
        mesh.triangles = Enumerable.Range(0, vv.Count).ToArray();
        mesh.RecalculateNormals();

        GetComponent<MeshFilter>().sharedMesh = mesh;
    }

    void Start ()
    {
        // バネの一番上の部分の球体ハンドル
        handleTransform = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
        handleTransform.position = transform.position + Vector3.up * _height;

        // メッシュのマテリアル設定
        MeshRenderer mr = GetComponent<MeshRenderer>();
        Material bane_mat = new Material(Shader.Find("Standard"));
        bane_mat.color = Color.green;
        mr.material = bane_mat;

        // 体積の一定値を求める。
        float r = 0.5f; // 初期のジャバラの半径
        valueConst = r * _height;
    }
    void Update ()
    {
        _height = Vector3.Distance(transform.position, handleTransform.position);
        if (pre_height != _height) 
        {
            ReCalcBaneMesh(valueConst / _height, _height);
            pre_height = _height;
        }
    }
}

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.