プロ生ちゃんに落書きした

# プロ生ちゃんに落書きする
おでこに「肉」とか書いてみる（昭和生まれ）。

![pronama_niku.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/90cdc5b5-1929-de4d-d467-03b831af8829.png)

プロ生肉ちゃんの出来上がりである・・・ごめんなさい。
おでこが狭くて書きにくかったです。

## 基本方針
実行時に３Dモデル上に手描きさせる場合、
真っ先に思い浮かべるのはテクスチャペイントみたいなやつだと思いますが、
そんな方法はとりません（なんか面倒くさそうだから）。
今回は落書きを３Dオブジェクトとして生成します。

## 立体上にペンを走らせる準備
多分最も手軽なのは、MeshColliderにRayを当てる方法だと思いますのでそうします。水のごとく低い所へと流れるべし。
となると、MeshColliderに割り当てるためのMeshが必要です。
プロ生ちゃんのをそのまま使用する手もありますが、
MeshColliderはスキニングに対応していない（多分）のでアニメーションさせた際に不都合が生じます。
従って今回は頭部のみのモデルをBlenderで作りました。

![pronama_head.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/59ba1e63-f768-eb04-16d5-7191fdac5130.png)

プロ生首ちゃんの出来上がりである・・・ごめんなさい。
これをUnityに取り込んでMeshColliderに割り当て、適当に回してやるとこうなります。
一応Inspector情報も置いておきますね。

![head_collision.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/8455fe0e-8288-4b11-7c4c-577e7f61b346.png)
![collider_prop.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/00d2ed4c-d2e0-4594-ed59-86e1b89199de.png)

これでプロ生ちゃんの顔面が触れるようになりました。
このままだとアニメーションさせたときにColliderが置き去りになるので、
頭部のノードにぶら下げます。
あと別件ですが、落書き用途以外に干渉しないでほしいので、他のLayerと衝突しないよう設定したRakugakiレイヤーに割り当てます。

![hierarchy.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/202b5c7b-94cd-2a1b-2007-42aaf5b8ee82.png)
![collider_prop2.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/2d44e47a-b568-17cb-0352-b02d4059d94f.png)

これでアニメーションしても大丈夫です。
よく体に馴染みます。

![collider_anim.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/67d5aa35-2309-8360-56fe-4eba0781d08f.png)


## 実際やってみる
面倒くさいのでコードを貼りますね。
ソースコードが最大のドキュメントだと誰か偉い人が言ってた気がします。

	void Update () {

        if (Input.GetMouseButton(0))
        {
            Vector3 mousePos = Input.mousePosition;
            Ray ray = mainCamera.ScreenPointToRay(mousePos);

            RaycastHit hitInfo;
            int layerMask = 1 << 8; // 8:rakugaki layer
            if (Physics.Raycast(ray, out hitInfo, 50.0f, layerMask))
            {
                // try adding metaball cell
                Vector3 pos = hitInfo.point;
                
                GameObject inst = (GameObject)Instantiate(brushPrefab);
                inst.transform.position = pos;

                inst.transform.parent = hitInfo.collider.transform;
            }
        }
	}

軽く説明すると、カメラからマウスで指しているポイントへRayを飛ばして、
先ほど設定したColliderに当たったらそこにPrefab化したオブジェクトを生成して、
ぶつかった先の子ノードに設定する、と。

これで一応書けるはず。書けました。
さっそく、プロ生ちゃんに**髭**を書き足してやろう・・・！

![hige01.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/83cb0bf3-3a8c-5949-30b6-eac048bcba60.png)

アニメーションで動かしても当然ついてきます。

![hige02.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/e323c5aa-c4d7-0934-4f7e-47ee79a51311.png)

ただし、ヒエラルキーがひどいことになります。

![hige_hierarchy.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/d7e1f1c1-9af2-cde1-9825-9f519ac903f7.png)

毎フレームインスタンスを生成してるのだから当然です。
一杯描くとクソ重くもなると思います。
でもま・いっか★


## おまけ
この前作った陰関数曲面生成コードがあるのでそれを使ってみます。
先ほどCubeを置いていたところに、代わりにメタボールを配置します。

![nama.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/9f3951be-18b9-3778-f6e6-e5bfab4c933f.png)

・・・動作が、重いです・・・
一粒置く毎に0.5秒くらい止まります（多分環境次第）。
書いている時が重いだけでその後はただの単体メッシュになるので何ともないんですけどね。

尚メッシュの細やかさをメタボールの半径と比例させているため、
細い線を描こうとすると重いという次第です。

こういうときはスッパリ諦めて、
太い線で何かできないか考えます。

こんなんでどうでしょう。
青りんごソースをかけるテスト。
この太さならわりとすいすい動きます。
movie
http://youtu.be/x_jRiPVSTfM
webplayer
http://unityroom.com/games/play/316
![green.PNG](https://qiita-image-store.s3.amazonaws.com/0/61553/34ffe575-ab90-f847-bdea-00bd19fcc15c.png)

ソースを動かすのは自重しておきますね。
（参考アプリケーション）
http://unitygameuploader.jpn.org/game/1850.html

キャラクターカスタマイズの一手法としてどうでしょう（ない）。

## この先
できればメッシュは簡略化したほうがパフォーマンス上好ましいです。

体の各部で同じことをすればあちこちに書けます。
でもデータを作るのが大変、かつ複数のボーンから影響を受ける部分では難しい。

スキニングに対応すれば全身への拡張が自然にできるはずです。
デフォルトのポーズでペイント後アニメーションを適用する感じになるでしょう。
多分ウェイトの計算が大変だと思います。