Unityで揺れモノを風で揺らす表現
Unity


「Unity揺れ物スクリプト」でも揺れモノを風で揺らす表現が出来たらいいなとちょっと取り組んでみました。

ユニティちゃんアセットの「SpringBone」は「RandomWind」というスクリプトで揺れモノを風で揺らす表現をさせることが出来ます。

「RandomWind」も参考にさせてもらい、パーリンノイズを使って「Unity揺れ物スクリプト」に揺れモノが風で揺れる機能を追加する「YureWind」スクリプトを書いてみました。


YureWind.cs
using UnityEngine;

  namespace Yuremono {

      public class YureWind : YureManager {

        [SerializeField, Range(-3, 3)]
        private float WindForceX = 0.0f;
        [SerializeField, Range(-3, 3)]
        private float WindForceY = 0.0f;
        [SerializeField, Range(-3, 3)]
        private float WindForceZ = 0.0f;
        [SerializeField, Range(1, 3)]
        private float WindSpeed = 1.7f;
        [SerializeField, Range(0.001f, 0.01f)]
        private float noiseStrong = 0.004f;
        public bool moreDynamic = false;

        public bool strongWind = false;
        [SerializeField, Range(-3, 3)]
        private float strongWindL = -2.0f;
        [SerializeField, Range(-3, 3)]
        private float strongWindR = 2.0f;
        [SerializeField, Range(1, 2)]
        private float WindCycle = 1.0f;

        float timer = 0;
        float timer2 = 0;
        float wfx;

        void Start() {
            wfx = WindForceX;
        }

        void Update() {
            if (moreDynamic) {
                timer += Time.deltaTime;
                if (timer >= 0 && 3 > timer)
                    WindForceX = Mathf.MoveTowards(WindForceX, wfx * 0.8f, 0.002f);
                else
                if (timer >= 3 && 5 > timer)
                    WindForceX = Mathf.MoveTowards(WindForceX, -wfx * 0.8f, 0.05f);
                else
                if (timer >= 5 && 6 > timer)
                    WindForceX = Mathf.MoveTowards(WindForceX, wfx, 0.1f);
                else
                    timer = 0;
            }
            if (strongWind) {
                timer2 += Time.deltaTime;
                if (timer2 >= 0.0f && 0.1f * WindCycle > timer2)
                   WindForceX = strongWindL;
                else
                if (timer2 >= 0.1f * WindCycle && 0.2f * WindCycle > timer2)
                   WindForceX = strongWindR;
                else
                    timer2 = 0;
            }
        }

        void LateUpdate() {
            float pnoise = Mathf.PerlinNoise(Time.time * WindSpeed, 0.0f) *
            noiseStrong;
            for (int i = 0; i < springBones.Count; i++)
                springBones[i].springForce = new Vector3(pnoise * -WindForceX,
                pnoise * WindForceY, pnoise * -WindForceZ) * WindSpeed;
        }
    }
}
(YureWind.csは、https://yahoo.jp/box/_e4KIDに置いてあります)


「YureWind.cs」を使うためには、nscripter.comさんのところで公開されている「Unity揺れ物スクリプト」が必要です。

この「YureWind」スクリプトは「YureManager」スクリプトと同じところにアタッチして使います。YureWindクラスはYureManagerクラスをスーパークラスとして継承させるかたちにしています。




揺れ方をカスタマイズできるように色々盛ってみました。

「Wind Force XYZ」はXYZ各軸に沿って風の吹く方向を変えることが出来ます。ここの値はグローバル座標なのでキャラクターを回転させれば揺れ方も変わります。

「Wind Speed」はパーリンノイズの周期を変化させることで風速を変えているように見せます。「Noise Strong」はパーリンノイズの値幅を変えることで揺れ幅を抑えたり、より大袈裟な動きにしたい時に使います。

だだ、これだけだと一方向に吹いたきりになり、動きが少し物足りないと思います。それで、2つの風揺れパターンのアルゴリズムを付けてみました。

「More Dynamic」にチェックを入れると、例えば右向きに吹いていた風が左向きに変わってまた右向きに戻るという動きになります。この時、ループさせるために実行前に設定した「Wind Force X」の値をキャッシュしておいて使用しているので実行中はインスペクターから「Wind Force X」の操作は出来なくなります。

「Strong Wind」にチェックを入れると、強風でバタバタと髪や服が左右になびく様な動きになります。「Strong Wind LR」の値で「Wind Force X」を0.1秒ごとに交互させています。この値をLは-1、Rは3などと平行にずらせば斜め前から吹く風も表現できます。「Wind Cycle」を大きくするとバタバタする速さは遅くなります。

「YureWind」を使ったデモ動画を作ってみました。髪の長いキャクターの方が分かりやすいかと思い、カレンを使ってみました。今回はスカートはクロスではなくボーンを使っています。


YouTubeの動画元はこちらです。


ImgurでGIF動画にするには15秒以内にしなくてはならず、そのため時間ぴったりに一連の動作が収まるようにスクリプトから「YureWind」の値を操作しています。




いい機会だったのでカレンの直そうと思っていたところの修正をいくつかしました。何箇所かのメッシュの修正と髪のテクスチャを描き直しました。シェーダーは「ユニティちゃんトゥーンシェーダー」に変えました。透過テクスチャを使わなくても眉が透けて見えるようになりました。




あと、髪ボーンの追加です。はじめ、カレンの後ろ髪のボーンは一列で4本だけでした。それはMMDモデルなら一本のボーンでも板状の剛体を付ければ髪の幅をカバーできると想定していたからでした。




しかし、「Unity揺れ物スクリプト」ではコリダーは球状のみなのでボーン一列では腕にコリダーを付けても届かないので貫通しやすくなってしまいます。

より自然に風でなびかせるためにも髪の束をそれぞれ独立させておいた方が良いかなとも思いました。それで後ろ髪のボーンを大幅に増やしました(4本→44本)。

今回試してみて、よりなめらかな揺れをさせるためには一列8本ぐらい必要かとも思いました(44本→88本ぐらい)。ゲーム用ならこのままで妥協も出来ますが映像用となれば多くするべきでしょうね。

「YureWind.cs」については「Unity揺れ物スクリプト」の製作者様同様、私も権利は主張いたしません。ご自由にどうぞ。


~後日追加~


pixivのうごイラに110フレームほどのショートループ版を投稿していたのですが、こちらの方が画質も良く、揺れ方も15秒版とは違う感じでうまくまとまってくれたので、もし良かったらこちらも観てみて下さい。
スポンサーサイト
テーマ: CG ジャンル: 日記
Unity、クロス、ボーン、試行錯誤
Unity



前回触れました、まいティーちゃんのスカートのUnity上での挙動の件にについて書いておきたいと思います。

とりあえず、MMDでも動かせるようにスカートにはボーンを付けていましたが、クロスシミュレーションの方が自然な動きになってくれそうかなと思い、Unityではクロスコンポーネントを使う予定でした。




まず、スカートにクロスコンポーネントをアタッチして、スカートの頂点にクロスコンストレイントを設定します。そして、足と腰にコリダーを設定して動作テストしてみました。




そしたら、スカートのメッシュがとんでもないことに!?

まさに、メッシュの爆発状態ですねぇ(汗)。前にカレンでクロスを使った時は普通に使えたのですけど。あの時のUnityのバージョンは5.4でしたが今回は2017です。それが原因なのか?

5.4は5.6を入れる時に上書きしてしまったのですが、2017を入れる時は念のため5.6を残して置いたので、そちらでも試してみたのですがメッシュは同じく崩壊状態でした。

それで、もっとシンプルなモデルで試したらどうなのかと、Blenderで簡単なモデルを用意してFBXで書き出して試してみたら、やはりクロスを設定したメッシュは形状が崩壊してしまいます。

まいティーちゃんは一からBlenderで作ってあったのですが、カレンはShadeで作ったものです。まさかそれが原因だったりするのかと、Shade3Dでも同じようなテストモデルを作って試してみたら、そちらは普通でした。




左の緑のがShade3Dで作ったもの、右の青いのがBlenderで作ったものです。それぞれ、アニメーション付きのFBXで書き出したものをインポートしたものです。




GIF動画にしてみました。クロスの設定は3つとも同じです。セッティングは「Stretching Stiffness」、「Bending Stiffness」が共に1。「Damping」が0.5です。

Shadeで作ったものは元の形状を保っているのですが、どういうわけかBlenderで作ったものはメッシュの元の形状を保てず伸びきってしまってます。理由は分かりません。(汗)

FBX形式は何かと相性とかが問題になったりします。一応、Autodesk FBX Converterでバージョンの変換とかも試してみたのですが改善はしませんでした。

では、FBX形式じゃなかったらどうなのだろうと、Blenderから傘の部分だけOBJ形式で書き出して、Unity上で左の青いモデルを複製して、その傘の部分を付け替えてみたものが真ん中の赤いメッシュです。こちらは形状を保っています。

とりあえず、Blenderで作ってあってもOBJ形式のメッシュならメッシュの破綻はないようです。しかし、カレンはShadeで作ってあってもFBXのエクスポートはBlenderからしていました。元のメッシュがどのソフトで作ってあるかが関係しているのか、はたまた自分の環境だけそうなるのかは分かりません。

それでとりあえず、まいティーちゃんのスカートのみをOBJ形式でインポートして取り替えてクロスコンポーネントを付けてテストしてみました。

形状は保てるようになったのですが、今度は黒いノイズが現れる様になりました。




スカートは溝もメッシュで段差を付けて作っておいたのですが、そこの頂点が近すぎるために揺れる時に奥の頂点が表側より前に出たりするのが原因のようでした。




それで、溝の段差を無くして単純なメッシュ構造に変更してみました。モデラーとしては溝も凝ってみたのですが、揺らしてみて不都合となるようなら修正せざるを得ませんね。動き重視です。(あと、若干全体的に膨らませました)




黒いノイズは出なくなりましたが、なんか想像していた動きと違っていました(もっと形状を維持してくれるのかと)。しかも、なんか動作も少し重いような感じもありました。それで、クロスは諦めてボーンでやることにしました。




スカートの前のボーンは始めは一本だったのですが、一本だと横に振られた時に大袈裟に動いてしまうので、ボーンを2本に変更して影響を分散させることにしました。

スカートの場合、複数のボーンの影響を受けた方がより自然になるということでウエイトは自動でやり直しました。こういうのはケース・バイ・ケースですね。

使わせてもらっている「Unity揺れものスクリプト」はシンプルでコリジョンと自然な揺れを表現できる素晴らしいスクリプトです。ただ、剛体形状が球のみなので、ぶつかった角度に対して素直に跳ね返るし隙間も出来やすいので、スカートのように平面的なものを表現したい時に少し考えなくてはならなくなります。

MMDだとスカートには、広がっても突き抜けにくく前後に揺れやすい板状の剛体を使うのが一般的なので少し困りました。




そこで、腿のところと股間辺りの2箇所にコリダーを置いてスカートのボーンをなるべく前に弾くようになるようにしました。片側の足を上げた時、反対側のスカートも前方に動くようにすることでうまくごまかそうという訳です。




股間のところのコリダーが無いとメッチャ左右に揺れてしまうことになり後ろ側に比べると結構前だけ横方向に大袈裟な動きになってしまいます。それよりはまだマシに見えるかなという感じです。

走らせることを前提としているのならば、お椀型のようにスカートの前方をもっと広くして足から離れるようにしたらもう少しすんなりいったかもしれません。ちょっと、このキャラには将来的にはギターとかも持たせてみようかなとか思っていて前面はあまり広がらないようにしておいたのです。

Blenderで作ったメッシュは本当にUnityのクロスシミュレーションと相性が悪いのか気になります。ググっても同じような症状になるという話題は見かけませんでしたので、自分環境なのでしょうかね。

今思えば、スカートをShadeで作ってクロスを試してみれば、また印象が変わるのでしょうか。

先程の傘モデルのように、同じ「Stretching Stiffness」、「Bending Stiffness」が共に1の設定でも、緑のShadeの傘は元の形状を保っていますが、赤いBlenderの傘は垂れてなんか柔らかい感じがします。クロスが垂れないのならShadeで作り直してみる価値もあるかもしれませんが、今すぐには気力が湧きませんね。(^^;)

揺れものは一筋縄ではいきませんねぇ。走らせるのならホットパンツとかならもっと楽だったとは思いますが、何事もやってみないと分かりませんからね。

あと、Unity 2017はインスペクターからは日本語入力が出来なくなってしまいましたね。必要があれば、メモ帳に書いてからコピペという感じです。次のアップデートでは対応してくれるとよいのですが。


~後日追記~

BlenderからスカートのみをFBXでエクスポートしてクロスを試してみたら、OBJと同様でメシュの崩壊はありませんでした。しかし、同じく柔らかくて垂れますね。

関連記事:

Unityでオリキャラのモーションテスト

テーマ: CG ジャンル: 日記
Unityでオリキャラのモーションテスト
Unity



さて、Blenderで作り上げたオリキャラをUnityにFBXでインポートしてみた図です。Unity 2017使ってみました。




そろそろ、このキャラクターの名前を決定しておくことにしました。

その名も『桃実沢まい』。小柄で華奢な割にはけっこう力持ち、チャレンジ精神が旺盛で身体能力も並外れているところから、周りからは「Mighty」をもじって「まいティーちゃん」と呼ばれている、という感じで。(^^;)




シェーダーは「ユニティちゃんトゥーンシェーダー2.0」を使ってます。今回は、前髪に隠れている眉を透けて見えるようにしてみました。ただ、眉と髪が同じ色だと境目が分からなくなってしまうので、より効果的にするために眉のテクスチャに輪郭線を描き足しました。




設定の仕方は、隠れているもの(眉)のシェーダーを「StenciMask系」に、透かして見せるもの(前髪)のシェーダーを「StenciOut系」にすると言う具合です。




「ユニティちゃんトゥーンシェーダー2.0」ではポリゴンの片面表示と両面表示の設定が出来るようになってます。デフォルトで「BACK」になっていてスカートの裏側が黒かったのですが「Cull Mode」をOFFにすると両面表示になりました。




Blenderでモデルを作ってモーションを付けてもUnity上でどう動いて見えるかは実際にUnityで動かしてみないと分かりません。それで、まいティーちゃんにBlenderでいくつかアニメーションを作ってUnityで動作チェックしてみました。


今回もImgurのGIF動画にしてみました。

元のYouTube動画はこちら
https://youtu.be/kiVnTLmzjUc


前に作った動画の画質が悪くてどうしたものかと思っていたらブラウザにもよるみたいですね。普段IE11を使っているのですが、Chromeで見てみたら普通に綺麗でした。なんででしょう?




一応、モーションの解説的なものを。まず、「待機」です。ここから各モーションへ分岐するということに。

キーボードのキーにも各モーションを割り当てていたのですが、動画的にUIボタンも付けてみました。「走る」と「ピース」はボタンを押したら3秒間モーションを再生するとしてみました。




「走る」です。今まで走るモーションはいろいろなソフトでチャレンジしましたがかなり苦戦したものです。意外にもBlenderが一番付けやすかったですね。Blenderだとボーンコンストレイントを簡単に設定できるので今後はモデリングだけではなくモーション付けにも大いに役立ってくれそうです。

髪やスカート等の揺れモノは今回も「Unity揺れものスクリプト」を使わせてもらってます。リボンの動きがちょっとコミカルで面白いですね。やはり、手付けではこんなに自然な動きは付けられません。

ただ、難航したのはUnity上でのスカートの挙動です。結局、かなり試行錯誤と修正が必要でした。これについてはまたの機会に。




「がんばるぞい!」。ではなく、「よし!」です。(笑)




「おー!」。本当は「やったー!」のつもりでしたが思っていたよりモーションが短かったので「おー!」に変更しました。(^^;)

髪用として左右の肩にコリダーを付けていますが、左腕を上げたとき髪が貫通しないように左腕にさらに2つコリダーを追加してあります。うまくいったようです。




「ピース」。実際にピースする時は薬指と小指はぎっちり握ってないんですよね。あと、腰に手を当てるときは腰骨の手を置く方が少し上がるのが自然です。これらも作った後に気がついて修正です。




「ユニティちゃんトゥーンシェーダー」だとリアルタイムでのベタ塗りの影がいい感じですね。逆光の演出も使えそうです。




せっかくなので、「走る」の別角度を「うごイラ」にしてみました。



関連記事:

Unity、クロス、ボーン、試行錯誤

テーマ: CG ジャンル: 日記
Blenderで衣装を作る
Blender



Benderでオリジナルのフィギュアを作っていたのですが、衣装がなかなか決められなくて長らく作業がストップしていました。

とりあえず、完成させてしまおうと衣装を決めてみました。





衣装はデザインを決めてしまってからは早いものでモデリング自体は大体3~4時間ぐらいで完成させました。

はじめは、スポーティーな衣装を考えていたのですが、うまくイメージがまとまらずウェイトレス風な衣装に変更しました。とりあえずはうまくまとまったとは思います。気力が湧けば他のも考えたいですが、しばらく湧きそうもありません。f(^^;)

自分の場合、キャラクター自体はすぐに描いたり出来るのですが、衣装がなかなか決められないんですよねぇ。自分にとってはフィギュアをモデリングすることより衣装を考えることの方がはるかに難しいことかもしれません。(汗)

しかし、モデリングの後はテクスチャを描くのでモデリングの5倍ぐらいの時間がかかっているかもしれません。
(テクスチャは凝りだすと出すとキリがなくなってくるんですよねぇ、汗)








今回、衣装のテクスチャは全部Blenderのペイント機能だけで描いてみました。

Blenderではマテリアル設定や画像設定など切り替える時は結構ややこしくなり面倒だなと感じる部分が多々あるわけです。

こんなとき、「yPanel」というペイント機能を便利に強化してくれるアドオンがあるのです。これはとても秀逸でペイント時にUVの画像を簡単に切り替えたりペイントソフトのように簡単な操作でレイヤーを重ねて描くことも出来ます。

服の模様や髪のハイライトとかもレイヤーを使えば気が済むまで描き直すこともできます。

あと、今回は使ってませんがバンプなどもペイントできるし、その描いた凹凸をノーマルマップに変換する事も出来ます。Blenderの機能をよりリッチにしてくれるとてもありがたい今では欠かすことのできないアドオンです。





リギングと足IKも付け終えています。このキャラはUnityで動かすことが前提なのでスカートはクロスシミュレーションを使えばボーンは入れなくてもいいのですが、一応MMDでも動かせるようにしておこうとボーンを入れてあります。

髪とスカートのスキニングは自動では不自然なところが出るのは当たり前なのでいつも手動で設定しています。自分の場合、ウェイトペイントというのはどうも苦手ですね。やりだすとキリがなくなってくるというか。

きっちり数字で管理したい自分としては、こういう場合は事前にスキンのウェイト値を計算してノートに表に書いて手動で設定しています。


そういえば、先月ZBrush 4R8がリリースされましたね。でも、やはり自分にとって今すぐ必要とか思わないかなぁ。

自分の場合、まず動くキャラを作りたいわけです。動かすとなるとボーンを入れてスキニングすることになります。自分でポリゴンモデリングをする時は、後で入れるボーンに対する頂点のウェイト値を考えながらポリラインを増やしてきます。そうして作れば、後でウェイトを手動で設定したい時などは作業がやりやすくなります。

スカルプトでは、ハイポリで作った後に自動でリトポロジーしながらポリゴンリダクションしていきます。そこで出来たポリラインはある程度は意に沿っていたとしても結局は機械的なもので、それをそのまま人がウェイト設定するのはおそらく大変だろうなと思います(まだやったことはないですけど)。

(なおさら、ZBrushCoreでモデルを作ってBlenderでリトポというのは手間がかかり過ぎて現実的ではないかもしれませんね。これはやってみましたが)

後からの手間を考えれば、ローポリモデルを作るのならスカルプトより、やはりポリゴンモデリングの方が向いている気はします。でも、それは人それぞれなのでしょうね。ポリゴンモデリングよりスカルプトの方がやりやすいという人もたくさんいるようですし。

とりあえず、今のところ自分はBlenderでのポリゴンモデリングでとくに不満もありません。Blender様様ですね。(本音を言えば、資金に余裕があったらもちろんZBrush 4R8にも手を出したいところなのですが)



関連リンク

Blenderでフィギュアを作る

Blenderでテクスチャーペイント

・Blenderで衣装を作る

テーマ: CG ジャンル: 日記
Shade3Dで学校でも作ってみる
Shade 3D



学校3Dモデルを作っておけば漫画用の背景素材やゲーム用のアセットでも使えるだろうし、ここは一つShade3Dで作ってみようということで建設開始してみました。




まず教室内部。やはりShadeはこういう寸法が決まっているようなものを作るのが得意なのですよね。サクサク作っていけます。




黒板や掲示板、窓やフレームもきっちりした寸法で作ってあります。蛍光灯も実際の製品のCAD図を参考にほぼ同じサイズで作ってあります。







この教室を1ユニットとして同じような教室はリンクで複製して重ねていきます。(パーツが結構な量なのでリンクを使わないとだんだん動作が重くなってしまいます)







とりあえず、階段も作り4階ぐらいに重ねてみるといかにも学校っぽく見えてきますね。(屋上は重要なものですからね、後からちゃんと作ることにしましょう^^;)

しかし、今までのShadeだと込み入ってくると中の様子を確かめるのが非常に困難になってくるのでした。




ここで、ver.16の新機能の「切断面表示」を使うとオブジェクトを好きなところで切断して簡単に中を確認できます。




X軸の「切断面表示」。




Y軸の「切断面表示」。




Z軸の「切断面表示」。

確かにあると便利な機能ですね。GIFアニメにしてみましたが、今のところShadeでは「切断面表示」にキーフレームを打つことは出来ずアニメーションには出来ません。切断面アニメーションが出来たらけっこう面白いと思うのですけどね。

しかし、ここまでで完成の8分の1ぐらいでしょうか?先はまだ長いですね(^^;)。一度、一から校舎や校庭全部作ってみたいとは思ってはいたのですが、なかなか時間が回せず気が向いたらという感じになりそうです。

でも、建物を作るのも楽しいですね。


テーマ: CG ジャンル: 日記
Shade3D ver.16へバージョンアップ
Shade 3D



数日前、Shade3D ver.17が7月14日に発売されるとのお知らせメールが着ていました。自分はver.15 Professionalを所有していますが、前回のver.16へのバージョンアップは見送っていました。

Blenderを使い始めたらフィギュア等のキャラクターものならBlenderの方が機能が充実していてるし、表情等もFBXにつけることも出来るし、フリーだし、これはもう完全にBlenderに乗り換えてしまおうかとも思いました。

しかし、建物や細かい部品を寸法通りに作ろうとすればこれはBlenderより断然Shade3Dの方が作りやすいのです。三面図表示を同時に拡大縮小などShadeで普通に出来ることですがBlenderではできません。 (※後日追記あり)

自分的には、「Shadeでもフィギュアを作ろうと思えば作ることが出来るが、Blenderでやった方が作業は捗る。」「Blenderでも建築物を作ろうと思えば作ることは出来るが、Shadeでやった方が作業は捗る。」という感じです。

モデリングの負担が少しでも減らせるのならケース・バイ・ケースで作業効率が良い方を選んで使い分ければいいだけと割り切りたいです。
(一つのソフトで全て済ませられればそれに越したことはありませんが、現実はそうもいきません- -;)

それで、やはりShade3Dは自分にとっては必要なアプリとしてver.17へのバージョンアップはしてみようかなと思いました。ver.17の新機能としてProfessionalにCADモードが追加されるという、どのようなものか気になりますね。

今月の15日から30日の期間中に予約すれば早期予約特典を受けられるとのこと。早期予約特典はver.17を予約すれば印刷マニュアルが貰えるというのと、期間中にver.16へバージョンアップすればver.17への無償アップグレード権が貰えるというもの。

自分的にはマニュアルは電子書籍の方が読みやすいのでとくに印刷マニュアルは無くても構いません。Shade3D ver.16では「寸法表示」や「切断面表示」、「ウォーク・ウォークスルーアシスタント」など建築物を作るには役立つ機能が追加されてます。

今、ver.16にバージョンアップしておいてver.17がリリースされるまでの1ヶ月、事前にver.16の新機能を色々試しておいた方がいいかなと思い、まずver.16にしてみることにしました。




Professional ver.17へのバージョンアップのお値段は、通常は¥25,056のところ早期予約特典で今なら¥22,572、って全然お買い得な気分はしませんね(^^;)。というか値下げどころか通常価格は値上げしちゃってますね。(- -;)

購入手続きをしてもすぐにはダウンロードできないのは2年半ぐらい前にShade3D社自社販売になってから変わってないんですね(汗)。待つこと約1時間半、Shade3D社から支払い完了のメールが着てようやくダウンロード出来るようになりました。
(ネットショッピング決済でこんなに待たされるということはまず他にはないので結構もやもやしてしまいますね(^^;)、もう少し消費者の心理を考慮してもらいたいものですとか思ってしまいます)




ver.16購入と同時にver.17が予約されたことになってます。あとは、ver.17の発売日にアップグレードすればいいだけですね。




Shade3D ver.16をダウンロードしてインストールしてみました。

さっそく、以前に公式フォーラムに要望を書いていたらver.16で叶って追加されていた機能を試してみることに。




まず、「スライドツール」。これは稜線や頂点を稜線に沿って移動させることが出来る機能です。面切断などで一度確定してしまった稜線を後からずらしたいなぁとか思うことが多々ありまして、是非ともShadeでも欲しかった機能ですね。




あと、「サブディブジョンサーフェスをレベル単位で分割」も叶いました。しかし、じつは元々Shadeでも「>」、「<」記号を使うと出来た機能で、私が出来ないとものだと勘違いしていただけでした(^^;)。でも、ver.16からは「形状情報ウィンドウ」から分かりやすく操作できるようになりました。

ver.16には、他にも新機能が色々ありますが追々試してみましょう。

結局、バージョンアップしてしまいました。なんだかんだ言ってShadeって不思議な愛着があるソフトなんですよね。今現在、体験版では一足先にver.17のフル機能が試せるようです。私は発売日まで待ちます。(^^;)



~後日追記~

この記事を書いた後にBlenderでも四分割表示時に三面図を同時に拡大縮小が出来るとことがわかりました。お詫びと訂正いたします。

表情をスクリプトで滑らかに遷移
Unity



前回、Unity上でスクリプトからBlendShapesを操作して中割り無しでキャラの表情を変えることをやってみましたが、今回はスクリプトから表情を滑らかに遷移させるということをやってみたいと思います。

Unityでは、ある値からある値へと徐々に近づかせる手段としてMathfクラスのLerp関数とMoveTowards関数を使う方法があると思います。とりあえず、Mathf.MoveTowardsとコルーチンを使ってそれっぽい動きになるようにしてみました。

動画にしてみました。

https://youtu.be/beKhRQ-W4-Q


このキャラは、Blenderのみで作っているオリキャラです。半年前にボーンとモーフを入れてあったのですが、なかなかそちらに時間が回せず衣装をまだ考えてなく放置したままでした。今回、表情テストモデルとして登場させてみました。

シェーダーには「ユニティちゃんトゥーンシェーダー2.0」を使ってみました。しかし、Youtubeにアップした動画をImgurでgifにして貼ってみたのですが驚くほど画質がよくありませんねぇ(汗)。一応、表情がなめらかに変化しているのは伝わりますでしょうか。(リンク先は大きくてキレイな画質ですので)

スクリプトはこのような感じです。

using System.Collections;
using UnityEngine;
using UnityEngine.UI;

public class FacialMorphingScript : MonoBehaviour {

    SkinnedMeshRenderer SKMR_head;
    Transform head;
    public Text eye, mouth;
    float we, wm = 0;

    void Awake() {
        head = transform.FindChild("Head");
    }

    void Start () {
        SKMR_head = head.GetComponent<SkinnedMeshRenderer>();
    }

    public void OnEyesButton() {
        if (we == 0) {
            StartCoroutine(EyeClose());
        } else
        if (we == 100) {
            StartCoroutine(EyeOpen());
        }
    }
    public void OnMouthButton() {
        if (wm == 0) {
            StartCoroutine(MouthOpen());
        } else
        if (wm == 100) {
            StartCoroutine(MouthClose());
        }
    }

    IEnumerator EyeClose() {
        for (int i = 0; i <= 100; i += 10) {
            we = Mathf.MoveTowards(0, 100, i);
            SKMR_head.SetBlendShapeWeight(3, we);//目「笑顔」閉じる
            eye.text = we.ToString();
            yield return new WaitForSeconds(0.02f);
        }
    }
    IEnumerator EyeOpen() {
        for (int i = 100; i >= 0; i -= 10) {
            we = Mathf.MoveTowards(0, 100, i);
            SKMR_head.SetBlendShapeWeight(3, we);//目「笑顔」開く
            eye.text = we.ToString();
            yield return new WaitForSeconds(0.02f);
        }
    }
    IEnumerator MouthOpen() {
        for (int i = 0; i <= 100; i += 10) {
            wm = Mathf.MoveTowards(0, 100, i);
            SKMR_head.SetBlendShapeWeight(10, wm);//口「あ」開く
            mouth.text = wm.ToString();
            yield return new WaitForSeconds(0.02f);
        }
    }
    IEnumerator MouthClose() {
        for (int i = 100; i >= 0; i -= 10) {
            wm = Mathf.MoveTowards(0, 100, i);
            SKMR_head.SetBlendShapeWeight(10, wm);//口「あ」閉じる
            mouth.text = wm.ToString();
            yield return new WaitForSeconds(0.02f);
        }
    }
}


目が完全に開いている時に「目ボタン」を押すと目を閉じ、完全に閉じている時に「目ボタン」を押すと開く。口が完全に閉じている時に「口ボタン」を押すと開いて、完全に開いている時に「口ボタン」を押すと閉じる。「両方ボタン」を押すと両方同時に押すのと同じ、という風にしてみました。

コルーチンを使うとアニメーションクリップを扱うような感覚でわかりやすく扱いやすくなりますね。アニメーションのスピードも調整しやすくなります。BlendShapeの値は0から100までの値を10づつで増減させています。手描きのアニメーションでは目の中割りは通常は1~3枚ぐらいだと思うので8フレームもあれば十分ですね。

(ちなみに、コルーチンを使わない関数にすると、for文の処理が終わるまでしばらく待った後で表情が中割り無しでいきなり変わる事になります。)

はじめはMathf.Lerpを使ってみたのですが、目的値に近づいていってもきっちりその値にならなかったり、たどり着く時間も不明瞭な感じで、きっちり正確な数字で管理するのには向いていない気がしました。

Mathf.Lerpは目的値にだんだんゆっくりたどり着くカーブ的な動きをするのなら、Mathf.MoveTowardsは一定速度で目的値に近づけさせる直線的な動きで、今回のやり方に都合が良かったです。

(線形補間はQuaternion.Slerpなどのようにオブジェクトをゆっくりこっちの方に向かせたいような使い方をしたい(厳密な値でなくても良い)時にはいい感じで動いてくれるのですが)

スクリプトからBlendShapesを操作する方法は、会話や歌うときなどリアルタイムで正確に口パクさせたいときなど結構使えるのかもしれないと前回とは違う感想を持ちました。

今回使ってみた「ユニティちゃんトゥーンシェーダー2.0」は映像用向けとして輪郭線や影の扱いが色々細かく設定が出来るようです。やっぱり、標準のトゥーンシェーダーよりクオリティーが上がる気がします。これは使いこなしたいところですね。




せっかくなので、本来のキレイな画質の静止画も載せておきます。

ところで、ユニティちゃんアセット利用でのキャラクターではなくスクリプトやシェーダーのデータのみの使用についてですが、自分的に曖昧だったので確認してみました。

トゥーンシェーダー版のユニティちゃんはUCL2.0で、キャラクターデータを含まない「ユニティちゃんトゥーンシェーダー」のシェーダーコード自体は「アセットストア利用規約およびエンドユーザーライセンス契約」で利用可能です!
’http://unity-chan.com/contents/news/unity-chan-toonshader/’より

とのことです。ユニティちゃんシェーダーのみならライセンス表示はしなくても良いみたいですね。


関連リンク:

Unityでキャラの表情コントロール

Unityでキャラの表情コントロール2

表情をスクリプトで滑らかに遷移

テーマ: CG ジャンル: 日記
Unityでキャラの表情コントロール2
Unity



Blenderで作ったシェイプキー付きのフィギュアをFBXでUnityにインポートするとメッシュごとにインスペクター上の「Skinned Mesh Renderer」の「BlendShapes」で操作できるようになっています。




カレンの顔には29個の表情シェイプキーが付けてあります。あと、眉毛に8個、目に5個、その他に汗や赤面等が12個ほど付けてあります。




モーフのブレンド値は3Dソフトでは一般的に0が最小値で1.0が最大値だと思いますが、Unityでは100が最大値となります。はじめ、1にしても変化したように見えなくて焦りました。

表情アニメーションをUnity上から付ける方法は2つあります。新規にアニメーションクリップを作って「Animation」でキーフレームを打ってさせる方法。もう一つは、スクリプトからBlendShapesを操作する方法です。

しかし、最初スクリプトから動かそうとしてもうまくいきませんでした。「Animation」でキーフレームを打ってさせる方法は重ねたいアニメーションにレイヤーで重ねればよいのですが、スクリプトからでは元のアニメーションのキーフレームの方が優先されるらしく反応してくれませんでした。(スクリプトからレイヤーのようなものを作ってブレンドさせる方法があるのかまでは分かりません)

手っ取り早い解決方法は、元のアニメーションの表情のキーフレームを削除してしまうことです。しかし、FBXでインポートしたアニメーションはデフォルトでは(Read-Only)となっていてキーフレームの削除どころか編集できないようになっています。




こういう時は、FBXのアニメーションクリップを複製(Ctrl + D)してそちらを使用すれば編集可能になります。




とりあえず、シェイプキーのキーフレームを全部削除しておきます。


public class FacialMorphing2 : MonoBehaviour {

    private SkinnedMeshRenderer SKMR_Kao;
    private SkinnedMeshRenderer SKMR_Mayu;  
    private SkinnedMeshRenderer SKMR_me;
    private SkinnedMeshRenderer SKMR_other1;  
    private SkinnedMeshRenderer SKMR_other2;

    private Transform kao;
    private Transform mayu;
    private Transform me;
    private Transform other1;
    private Transform other2;

    public Mesh kaoMesh;

    private int shape_me;
    private int shape_kuti;
    private int shape_mayu;

    void Awake() {
        kao = transform.FindChild("kao");
        mayu = transform.FindChild("mayu");
        me = transform.FindChild("me");
        other1 = transform.FindChild("other1");
        other2 = transform.FindChild("other2");
    }

    void Start() {
        SKMR_Kao = kao.GetComponent<SkinnedMeshRenderer>();
        SKMR_Mayu = mayu.GetComponent<SkinnedMeshRenderer>();
        SKMR_other1 = other1.GetComponent<SkinnedMeshRenderer>();
        SKMR_other2 = other2.GetComponent<SkinnedMeshRenderer>();
    }
...


あとは、各メッシュのSkinnedMeshRendererコンポーネントを取得し各BlendShapesの値を操作します。各メッシュそれぞれにスクリプトをアタッチするとモーフミキシングがバラバラになりやりにくくなるので親元から子のメッシュを取得するようにしました。

FindChildで取得する数が増えると処理が重くなることを想定して、明確にStart()の前に実行されるAwake()を使っています。(FindChildって公式リファレンスに載ってないのですがあんまり使うべきではないのでしょうかね。publicで直接取得でも良かったと思いつつ。)


        shape_mayu = 6;
        shape_me = kaoMesh.GetBlendShapeIndex("ジト目");
        shape_kuti = kaoMesh.GetBlendShapeIndex("たじろぎ_歯無し");

        SKMR_Mayu.SetBlendShapeWeight(shape_mayu, 100);
        SKMR_Kao.SetBlendShapeWeight(shape_me, 56);
        SKMR_Kao.SetBlendShapeWeight(shape_kuti, 100);

BlendShapesのブレンド値には
SkinnedMeshRenderer.SetBlendShapeWeightを使います。引数1はint型でブレンドシェープのインデックス番号で引数2がfloat値のブレンド具合です(リファンレスではウェイトは [0から100] の範囲に制限されないそうです)。

ブレンドシェープの数がひと目で分かるぐらいならインデックス番号でいいんですが、30、40ぐらいになってくるといちいち数えるのが大変になります。

こういう時、Mesh.GetBlendShapeIndexを使えばブレンドシェープに登録されてある名前の文字列からint型のインデックス値を返してくれます。日本語名でも使えるのでこちらの方が見分けやすいですね。ただし、対象のメッシュを予めMesh型で取得しておく必要があります。




スクリプトからBlendShapesを操作して表情を変えさせてみたものをbxSliderを使ってGIFアニメ風に再現してみました。(今回は動かす必要も無いと思い直立不動で表情のみ変化させています)

スクリプトのみで表情を動かすためには次の表情の前に表情を戻す処理や滑らかに遷移させるための処理を考える必要があったりと、やはりスクリプトだけでやるよりはAnimationを使った方が楽だと思いました。

あえて、スクリプトでBlendShapesを操作してアニメーションをさせるならリニアカーブ的に中割り無しで表情を切り替えるような演出をしたい時には使えるかなとかとも思いました。

Unity5.6にしてよく落ちるようになったという話ですが、Unity5.6で新規でプロジェクトを作ったものに関しては落ちることはまだありません。古いバージョンのプロジェクトを扱う時に注意しておけば安心のようです。


関連リンク:

Unityでキャラの表情コントロール

Unityでキャラの表情コントロール2

表情をスクリプトで滑らかに遷移

テーマ: CG ジャンル: 日記
Unityでキャラの表情コントロール
Unity



カレンは表情モーフも作ってあるので、ならばUnity上からでも表情を操作できるようにしたい、ということでやってみることにしました。

まず、Blenderから表情のアニメーションをFBXでUnityに渡せるようにするところからです。




Blenderでは単体のモーションクリップを「アクション」と言うかたちで管理します。その「アクション」を「NLAエディタ」上で複数ブレンドして新たなモーションを作ることも出来ます。「NLAエディタ」ではシェイプキーによる表情も「アクション」に合成させることも出来ます。

表情が不要なら単体「アクション」だけでいいのですが、表情も必要な時は「NLAエディタ」での編集が必要になります。

シェイプキーのみのアニメーションはFBXでUnityに持っていくことは出来ないようで、表情をFBXに入れたい時はフィギュアのアーマチュア(ボーン)のアニメーションと重ねておく必要があります。(必ずしも動かさなくてもよい)

ですので、「T-Pose」に「まばたき」と「眉怒り」と「あ(歯あり)」の表情を付けてFBXでUnityに渡し、Unity側でアニメーションクリップの分割をしてそれぞれの表情を切り出す方法でいきたいと思います。




「T-Pose」からそれぞれの表情を切り出しました。これらの表情にはT-Poseのキーフレームが打たれていますのでモーションの妨げにならないように必要ないところはマスキングしておきます。




このモデルは剣のボーンの扱いをちょっと試す必要があるため、今のところRigは「Humanoid」ではなく「Generic」のままです。ですので、マスクは「アバターマスク」ではなく「Transform」からかけることにします。表情に関係していないところはチェックを外します。




切り出したクリップをAnimatorのLayerにセットします。それぞれの遷移はBool型でスクリプト上から操作します。レイヤーのブレンドは眉は「OverRide」、まぶたと口は「Additive」です。




まず、「まばたき」は自動でするようにしたいのでコルーチンを使うことにします。

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class FacialMorphing : MonoBehaviour {
  private bool mayu_ikari = false;
  public Slider mouth_a;
  public Text mabataki_ib;
  private Animator animator;

void Start () {
  animator = GetComponent<Animator>();
  StartCoroutine("MabatakiCor");
}

private IEnumerator MabatakiCor() {
  for (;;) {
      float rand = Random.Range(0.5f, 3.0f);
      mabataki_ib.text = rand.ToString();
      Mabataki();
      yield return new WaitForSeconds(rand);
  }
}

private void Mabataki() {
  animator.SetBool("mabataki", true);
  Invoke("Mabataki0", 0.3f*Time.deltaTime);
}
private void Mabataki0() {
  animator.SetBool("mabataki", false);
}

「まばたき」は一定時間で繰り返しても味気ないので不定期になるようにWaitForSeconds()の引数をRandom.Rangeでランダムに0.5から3.0の間の値になるようにしました。

「まばたき」のクリップは閉じるのと開くのを別々のクリップにしたので閉じたら時間差で開くアニメーションを実行するようにしています。

public void MayuIkariOn() {
  if (!mayu_ikari) {
      animator.SetBool("mayu_ikari", true);
      mayu_ikari = true;
  } else
  if (mayu_ikari) {
      animator.SetBool("mayu_ikari", false);
      mayu_ikari = false;
  }
}

眉毛はUIのボタンを押すたびに「普通」と「怒り」を交互させるようにしました。

口はレイヤーのWeightをスライダーでコントロールして制御してみようと思いました。




public void MouthA3_Slider() {
  float slwma = mouth_a.value;
  animator.SetLayerWeight(3, slwma);
}

レイヤーのWeight値のコントロールにはAnimator.SetLayerWeightを使います。引数1はint型のレイヤーの番号で、引数2は0から1間のFloat値でレイヤーのブレンド具合になります。

それで完成したのをGIFアニメーションにしてみました。


Imgur.comの動画をGIFのようにブログ等に貼れる用に出来るサービスを使ってみました。GIFより軽くてキレイに使えるメリットがある反面、ブラウザ上でピッタリと動画のループを合わせるのは至難の業ですね(汗)。けっこう、格闘しましたが妥協することにします(- -)。なんか再生速度もおかしくなってる気もしますが、いちおう自動まばたきとUIから表情を操作している雰囲気は伝わりますでしょうか(^^;)。(始めに用意したGIFアニメはFC2BLOGのアップロード2BM以内の制限に余裕で超過でした)

とりあえず、Unityでモーフを操作して表情を変えることが出来るようになりました。しかし、こういう感じで作ったモーフをUIから全て操作出来るようにするのはすごく骨が折れそうな作業になりそうですね。さすがに全部はやる気はありませんけど(^^;)。始めからモーションに表情をベイクしておく方が楽ですからね。要所要所で使い分けた方が良さそうですね。

ところで、Unity5.4からUnity5.6にしてみたのですが、Unityがなんかすごい頻度で落ちてしまいます。今まで、こんなに落ちたこともなかったのですが。Unity5.4以前で作ったプロジェクトを扱っていたからかもしれませんが、ちょっと怖いですね。うっかり、残そうと思っていたUnity5.4を上書きインストールしてしまいました。しかし、また入れ直す気にはなれませんので、もう少し様子をみることにしましょう。


~後日追記~

Blenderで作ったシェイプキーはFBXでUnityにインポートするとメッシュごとに「Skinned Mesh Renderer」の「BlendShapes」というかたちでUnity上から全てのモーフが使えるようになっているのを後から知りました。そのことについては次回に書いてみたいと思います。


関連リンク:

Unityでキャラの表情コントロール

Unityでキャラの表情コントロール2

表情をスクリプトで滑らかに遷移

Unityで揺れモノの表現
Unity



今回はUnityでMMDモデルではなく、FBXモデルでオリキャラの揺れモノの物理セットアップをしてみようと思います。




揺れモノですので、何かモーションが必要になります。今回はカレンにBlenderで歩行モーションを付けてみました。




Blenderからアニメーション付きのFBXでエクスポートして、Unityにインポートしました。トゥーンマテリアルは前のを流用しています。

・Unityでのトゥーンセットアップ




今回は、スカートというか腰巻の部分はUnityのクロスシミュレーションを使ってみたいと思います。腰巻のメッシュにPhysicsのClothコンポーネントを追加します。




クロスのEditモードで矩形選択、ペイント等を使いクロスのコンストレイントの影響範囲を設定します。赤が影響力0、緑が影響力Maxになります。クロスが他のメッシュと接触している部分は影響力0にしておかないとずり落ちてしまいます。




クロスの当たり判定のコリダーにはGameObjectのカプセルと球を使います。足にはカプセル、腰には球を設置しました。これらのコリダーだけ必要なので、形状は見えないようにMeshRenderはオフにしておきます。




後は、コリダーを各ボーンの入れ子にしてコリダーの配列にセットします。(球コリダーが一つの場合、Sphere Collidersの2番目はべつにnullのままでいいみたいです)

髪の揺れモノはこちらで配布されている「Unity揺れものスクリプト」を使わせてもらいました。3つのスクリプトを使ってセットアップしていきます。

使い方は、まずルートボーンにスクリプト「YureManager.cs」をアタッチします。




次に、揺らしたいボーンに「YureBone.cs」をアタッチして子ボーンを指定。後は、コリダーにしたいオブジェクトに「YureCollider.cs」をアタッチと、とくに難しい設定無しで揺れモノ表現することができました。




剣と羽のところもこのスクリプトで揺れるようにしました。




GIF動画にしてみました(GIFなので色合いが変わってしまいましたが)。揺れモノの動きは結構いい感じになっていてくれていると思います。設定はコリダーの半径ぐらいしか変更していません。シンプルなのに効果は絶大ですね。

せっかくなので、クロスの各項目の設定で見た目に大きく反映されそうなことをメモしておこうと思います。

「Stretching Stiffness(布の伸縮率)」
「Bending Stiffness(布の曲げ剛性)」
「Damping(モーションの減衰係数)」

上の3つに絞って比較してみたいと思います。




今回のセッティングは「Stretching Stiffness」、「Bending Stiffness」が共に1。「Damping」が0.5です。




「Stretching Stiffness」を0にするとクロスが縮み上がります。




「Bending Stiffness」を0にすると重力に従ったようにだらんと垂れる感じになります。よりリアルな布の感じになりますね。しかし、内側に黒いノイズが頻繁に現れます。ローポリ形状ではちょっとキビしいのかもしれません。(トゥーンシェーダーで両面表示だからというのもあるのかもしれませんが)

布であっても垂れずにモデリングした形状をなるべく保ってほしい時にはここの値は大きい方がいいかもしれませんね。




「Stretching Stiffness」、「Bending Stiffness」を共に0にすると、ちょっと使えそうにありません。




「Damping」を1にすると布がフワフワしたようになびきます。しかし、これもローポリではムリがあるのかもしれません。メッシュが貫通しやすくなります。




「Damping」を0にすると塩ビ素材のようにベランベランとした感じになりますね。やはり、ローポリならば0.5ぐらいが無難でしょうか。

あと、「Solver Frequency(一秒間ごとのソルバー反復の回数)」は480あたりがちょうどいい気がします。

今回はこのような感じになりましたが、他のモーションをさせる時に設定の変更もありうるかもしれません。揺れモノは奥が深いですね。また長くなってしまいましたね、本日はこの辺で。(^^;)


テーマ: CG ジャンル: 日記
カテゴリ
ini-T MUSIC SKY
プロフィール