Unity + Archimatix Pro でリアルタイム・パラメトリック・デザイン

この記事は「Unity #2 Advent Calendar 2017」の23日目の記事です。

# はじめに

![2017-12-23_1006.png](https://qiita-image-store.s3.amazonaws.com/0/42909/25fa580a-bcf5-28e0-6922-3a00af35fc3c.png)


Unity上でパラメータを変えることでモデリングができるパラメトリック・デザインという手法を、Archimatix Proというアセットを利用して実現します。ランタイム（ゲームプレイ時）でパラメータを変えてモデリングができるようになるので、モバイルデバイスやVR空間などで利用も可能です。


## Parametric Design (パラメトリック・デザイン）とは

> Parametric design is a process based on algorithmic thinking that enables the expression of parameters and rules that, together, define, encode and clarify the relationship between design intent and design response.

*引用元：https://en.wikipedia.org/wiki/Parametric_design*

言ってしまえば、パラメトリック・デザインとは関連性と行程のデザインです。パラメータを設定することで、そのパラメータに紐付けられた内部ロジックによってデザインが自動生成される仕組みを作ります。

建築の文脈で語られることが多く、またノードベースのエディターとの相性もよく、個人的にはGrasshopperやDynamo、最近ではHoudiniといったソフトウェアでそういった仕組みをよく作っています。

## Archimatix Proとは

![2017-12-18_0417.png](https://qiita-image-store.s3.amazonaws.com/0/42909/a09943c3-5847-702f-6e5a-ea1f6793700d.png)

[Archimatix Pro](https://assetstore.unity.com/packages/tools/modeling/archimatix-pro-59733) は、Unity上でパラメトリック・デザインを容易に行うことができるアセットです。なかなか値が張るアセットではありますが、デザインアセットを自分で作られている方や、建築やプロダクト系デザインの方にとって、このアセットを利用することの意義は非常に高いと感じています。あくまで、自分の視点から、下記に利用することのメリット・デメリットを並べてみたいと思います。

**利点**
- ゲームプレイ中でもリアルタイムでパラメータが変えられる（他に同じことができるツールは今のところない）
- クロスプラットフォーム対応。モバイルやVRなどで問題なく使える
- ノードベースエディタ（直感的にモデリングしやすい）
- リアルタイムの２D・３Dのブーリアン処理は◎
- 自分でカスタムノードを作れる（コーディングは必要）

**欠点**
- ちとエディタ上での反応が遅い
- 使えるモデリング手法がGrasshopperやHoudiniなどと比べるとまだ非常に限定的（ExtrudeやSweepなど）
- リストを利用したカスタム配列などが不可
- マテリアル付の書き出しはまだ難しそう

正直なところ、GrasshopperやHoudiniに慣れてしまっている身としては、パラメトリックデザインツールとしてはまだまだ不十分と言わざると得ないのですが、それでもこのツールでしか実現できない部分、特にランタイムでパラメータが変更できるという利点が非常に大きく、それだけでも使うに値するツールです。
（願わくばHoudini EngineがランタイムでUnityで使えるようになれば、それがベストソリューションなのですが、ライセンス上その実現は困難っぽいです）

# 準備

それでは、実際にArchimatix Proを使ったパラメトリックデザインの流れを説明したいと思います。細かいGUIとかの説明は抜きにして、こういう流れで形が作れるという説明の仕方になります。

## 何を作るか

パラメータを変更して形状を変更させるモチーフとして、家具はうってつけです。例えばテーブルであれば、足の高さや天板の大きさといったパラメータを設定することで、カスタムな形状の家具を生成する仕組みを作ることができるようになります。

ということで、一個簡単そうなモチーフを見つけてきました。

Andreas Kowalewskiというデザイナーによる[Wedge Table Caussa](http://www.andreaskowalewski.com/portfolio_page/wedge-table-1-caussa/)というテーブルです。

![2017-12-18_0449.png](https://qiita-image-store.s3.amazonaws.com/0/42909/2810645e-bed8-36f9-0a20-a6bb620c6a03.png)

最初椅子かと思いました。

今回は、簡略化バージョンとして、差し込みスリットやフィレットはない状態のとてもシンプルな状態のものを作りたいと思います。

## パラメータの選定

ではこの家具に対してパラメトリックな仕組みを与えたいので、家具として考えられるパラメータをいくつか想定しておきます。

Radius：家具の半径
Height: 家具の高さ
Thickness：家具の材の厚さ

## Archimatix Proのインストール

他のアセットと同じように、Unity Asset Storeから購入して、Unityの新規プロジェクト(5.6.4以降）にインポートしてください。

[Archimatix Proのページ](https://assetstore.unity.com/packages/tools/modeling/archimatix-pro-59733)

# Archimatix Proでパラメトリックデザイン（家具をつくってみる）

インストールが終わったら、早速このアセットを使ってパラメトリックデザインを行います。

下記のような流れで作っていきます。

Archimatix Proの構造の理解
　↓
天板を作る（家具の半径、材の厚さでコントロール）
　↓
足を作る（家具の高さ、家具の半径、材の厚さで形状をコントロール）
　↓
マテリアルを設定する
　↓
リアルタイムにパラメータを変えられるようにする

## Archimatix Proの構造の理解

新しいUnityのScene上で、Unityのメニューから、Window > Archimatix > Graph Editorを選択します。

![2017-12-23_0624.png](https://qiita-image-store.s3.amazonaws.com/0/42909/02b8d496-03f4-52b4-2d88-d8c154fd97f8.png)

ノードベースのエディタウィンドウが現れるので、そこで左上の矢印アイコンをクリックしてNew Modelを選択します。そうするとUnityのHierarchyにAXModelというオブジェクトと、RobotKyleBillboardというオブジェクトが生成されます。

![2017-12-23_0628.png](https://qiita-image-store.s3.amazonaws.com/0/42909/b25a61be-7504-b0fd-71a0-4004c54ee492.png)

![2017-12-23_0629.png](https://qiita-image-store.s3.amazonaws.com/0/42909/f7be837b-b29f-a66f-24f0-1002e40e685a.png)

RobotKyleBillboardというのはスケール感をみるためのKyle君の添景で、AXModelがGraph Editorで作った３Dモデルを表しています。

ここでモデリングをはじめていく最初のステップとして、GrouperというノードをGraph Editor上に置きます。これはその名の通り複数あるモデルをグループ化するためのノードで、整理整頓に使います。フォルダみたいな感じです。

![2017-12-23_0636.png](https://qiita-image-store.s3.amazonaws.com/0/42909/0a82d08a-89d6-6f63-1df8-f9cbff619eb0.png)

このGrouperをダブルクリックすると、そのフォルダの中身を見ることが出来ます。

![2017-12-23_0640.png](https://qiita-image-store.s3.amazonaws.com/0/42909/b1149c5d-71ca-349d-fc54-07fe876b94c5.png)

ここでさらに天板用と足用の２つのGrouperを作り、親のGrouperをTable、子のGrouperをPlateとLegsに名前を変えておきます。

![2017-12-23_0704.png](https://qiita-image-store.s3.amazonaws.com/0/42909/508d8794-6f0b-d84f-1006-afb516bd9f82.png)

ここでそれぞれのGrouperにパラメータを設定しておきます。Grouperの中のControlsという箇所の矢印をクリックすると、パラメータのリストが現れ、+ボタンを押すことで新しいパラメータを作ることができます。スクショの通りに、それぞれのGrouperにパラメータを作ります。タイプは全部Floatで大丈夫です。

![2017-12-23_0713.png](https://qiita-image-store.s3.amazonaws.com/0/42909/38afbe45-c1bc-d76d-7ed4-2d3d65e9e8f8.png)

次に作ったパラメータを親から子へとスクショのようにつなぎます。こうすることで、親で変更されたパラメータが子へと伝達されます。

![2017-12-23_0719.png](https://qiita-image-store.s3.amazonaws.com/0/42909/ee39a58a-47a1-22b0-0a26-eb01cf0e452e.png)

ただ、パラメータの値をそのまま流すのではなく、流れてくる値をベースに多少改変したい場合もあります。今回はTableのGrouperとLegsのGrouperを繋げているradius -> width_bottomの部分を改変します。

radius -> width_bottomをつなぐラインをクリックすると、Relation Expressionというダイアログが下の方に表示されるので、スクショのように値を変えます。width_bottomの値がradiusの0.25倍の値になります。

![2017-12-23_0740.png](https://qiita-image-store.s3.amazonaws.com/0/42909/281c7328-c45b-8c37-6912-fcae2ed48967.png)


ここで覚えておかなければいけないのは、Archimatix Proでは、パラメータの変更が双方向に影響されます。親で変更されたパラメータが子に影響を与えるのはもちろんのこと、子の方で変更されたパラメータは親に影響を与えます。便利だとは思うのですが、正直子から親へのパラメータ変更を考え始めると非常に煩雑になるので、個人的には親から子への流れだけを考えるようにしています。

最後にTableのGrouperのデフォルトのパラメータを下記の通りに設定しておきます。

radius: 0.6
thickness: 0.01
height: 0.6


これで準備ができたので、やっとモデリングを始めます。


## 天板を作る

Archimatix Proでのモデリングの基本は、最初に２Dの曲線プロファイル（Graph
 Editorの左上のパネル）を作成し、それをモディファイア（右のパネル）を使ってモデリングを行います。

![2017-12-23_0751.png](https://qiita-image-store.s3.amazonaws.com/0/42909/b023ba95-d5fb-2a86-091c-bda71bc41bfa.png)

天板を作るために、PlateというGrouperをダブルクリックして中に入り、スクショの用にプロファイルやモディファイヤを配置して繋げていきます。パラメータもスクショの通りに変更しておきます。

![2017-12-23_0757.png](https://qiita-image-store.s3.amazonaws.com/0/42909/bbe87adf-f163-3fc4-e0ee-aa4e7f003ede.png)

![2017-12-23_0805.png](https://qiita-image-store.s3.amazonaws.com/0/42909/96f0dbc8-c181-8ca1-accb-65ff8166a317.png)

Circleという２Dのプロファイラを用いて、辺の数を指定することで多角形を作れます。二種類の多角形をShapeMergerというノードを使って２Dのブーリアン処理を行います。その後、その結果をExtrudeのノードを使ってthicknessの分押出しを行います。これで半径と厚さがコントロールできる天板が作れます。


## 足を作る

次にLegsのGrouperをダブルクリックし、スクショのように机の足用にノードを組みます。

![2017-12-23_0845.png](https://qiita-image-store.s3.amazonaws.com/0/42909/9a241f3e-8564-5ce0-2064-02871d0043aa.png)

![2017-12-23_0849.png](https://qiita-image-store.s3.amazonaws.com/0/42909/73417722-564a-6b55-d9f7-87689d7fbe8b.png)

![2017-12-23_0850.png](https://qiita-image-store.s3.amazonaws.com/0/42909/7294a7b7-cf8b-3d2b-c209-a1c1d66b05cc.png)

一点、２Dの台形状の曲線を作るためにRectangleというノードを使っていますが、デフォルトのRectangleのままだと台形が作れません。なので、Rectangleのロジックを改変することで台形を作れるようにします。

ロジック自体はTurtle Scriptというスクリプト言語でスクショのように記述します。詳しい書き方に関しては下記のURLを参照してください。

[Archimatix Turtle Script API](http://www.archimatix.com/manual/archimatix-turtle-script-api) 

![2017-12-23_0857.png](https://qiita-image-store.s3.amazonaws.com/0/42909/e375d70b-c22b-59fa-33fd-02eecddab0f4.png)


## マテリアルを設定する

次に作った３Dモデルのマテリアルを設定します。設定自体は簡単で、１番上の階層でMaterial Toolのノードを配置し、それをTableのGrouperのMaterialのインプット部分に繋げます。そして子階層のGrouperにもMaterialを数珠つなぎで繋げていきます。

Material Toolノードのマテリアルのインプット欄に、Unity上で作ったマテリアルを入れます。

それに加えて、１番上の階層にTable以外にもう一つGrouperを作成し、Rot_Zに180を入力し、倒れているテーブルを反転させます。

![2017-12-23_0908.png](https://qiita-image-store.s3.amazonaws.com/0/42909/5743a698-59eb-a232-c4f8-eb1fcc6af279.png)

![2017-12-23_0910.png](https://qiita-image-store.s3.amazonaws.com/0/42909/03cd88dd-c52b-73f1-c851-ebd75072f75c.png)

これで３Dモデル自体は完成です。

![2017-12-23_0918.png](https://qiita-image-store.s3.amazonaws.com/0/42909/de7d65fe-5cb0-7ea3-6746-77584914db5b.png)



## リアルタイムにパラメータを変えられるようにする

あとは、設定したパラメータをリアルタイムに変えられるように設定します。１番最上位でradius、thickness、heightパラメータを開き、Exposeチェックをオンにすることでリアルタイムにコントロールできるパラメータに設定します。

![2017-12-23_0932.png](https://qiita-image-store.s3.amazonaws.com/0/42909/c0ea4f20-279f-dc6e-8d34-dc5222b6705e.png)

あとはスクリプトでこのArchimatixモデルのパラメータにアクセスできるようにします。わかりやすく、３つのパラメータに対応するスライダーを設置することにします。

![2017-12-23_0936.png](https://qiita-image-store.s3.amazonaws.com/0/42909/1686a8f8-62cd-ecc3-7b7f-9077cbb9a410.png)

新規にGameObjectを作成し、下記のようなコンポーネントをアタッチしておきます。

```C#:TableDesigner.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AX;

public class TableDesigner : MonoBehaviour {
    public AXModel model;

    public AXParameter p_radius;
    public AXParameter p_height;
    public AXParameter p_thickness;

	// Use this for initialization
	void Start () {
		if(model != null)
        {
            p_radius = model.getParameter("Chair_radius");
            p_height = model.getParameter("Chair_height");
            p_thickness = model.getParameter("Chair_thickness");
        }
	}
	
	// Update is called once per frame
	void Update () {
		
	}

    public void UpdateRadius(float val)
    {
        p_radius.initiateRipple_setFloatValueFromGUIChange(val);
        model.isAltered();

    }

    public void UpdateHeight(float val)
    {
        p_height.initiateRipple_setFloatValueFromGUIChange(val);
        model.isAltered();
    }

    public void UpdateThickness(float val)
    {
        p_thickness.initiateRipple_setFloatValueFromGUIChange(val);
        model.isAltered();
    }
}

```

modelの変数にAXModelをアタッチし、３つのスライダーのOn Value ChangeにそれぞれUpdateRadius、UpdateHeight、UpdateThicknessを登録します。

![2017-12-23_1002.png](https://qiita-image-store.s3.amazonaws.com/0/42909/298ab565-062a-efdb-6d63-a4126952b846.png)

この結果、プレイするとスライダーの値を変えることで、テーブルをパラメトリックにコントロールすることができます。

![screencapture.gif](https://qiita-image-store.s3.amazonaws.com/0/42909/7abda35f-3909-dc83-5aec-dec09180e1b4.gif)

# おわりに

今回はとてもシンプルな形状でしたが、他にも様々なモディファイアやベースモデル（２D、３D含め）があるので、それらを組み合わせることでもっと複雑なモデリングができるようになります。そしてどんなパラメータでもリアルタイムにコントロールできるので、非常に便利です。

モバイル環境とかウェブ環境（WebGL）でパラメトリックなモデリング環境を作りたい人にとってはこれ以上ないツールだと思います。

# プロジェクトファイル


**動作環境**

- Unity 2017.2f3
- Archimatix Pro 1.1.0 (Archimatix Proのプラグインは含まれていません。各自購入し、インポートしてください)

[Realtime Parametric Design with Archimatix Pro Example (Github)](https://github.com/jhorikawa/Realtime-Parametric-Design-with-Archimatix-Pro-Example)