読者です 読者をやめる 読者になる 読者になる

Onoty3D

Unityに関するメモとか

中野シスターズの表情を変化させる

中野シスターズ、公開後しばらく触っていなかったので久々に触りました。
中野シスターズ(ナカシス) 公式サイト

触ったついでに前回のユニティちゃんに続いて、中野シスターズの表情変化のスクリプトを作ります。
ほぼ前回からのコピペですが。

姉妹に適用後、EyeBall、Faceにそれぞれのmodel_eyeball, model_face(姉)/model_face1(妹)を設定してください。
f:id:onoty3d:20150901191805p:plain

f:id:onoty3d:20150901191812p:plain

瞳とまつ毛の動きは同時に変更できるようにしようかと思いましたが、別々にしたほうが上図のように白目に出来たりと表情の幅が広がりそうなので、あえて別々にしました。

なお現在公開されているFBXのバージョンは1_1ですが、1_1だと妹の方のmodel_face1への変更が表情に反映されません。
前バージョンの1_0では変更できていたので、デグレているようです。
公開から日が経っているので既知情報かもしれませんが、一応ガミングさんに報告しておきました(※)。
※2015/09/03にガミングさんより「確認してみてください」ということで、修正版のFBXを頂きました。バッチリ直っていたので、近日中に修正版が公開されるかと思います。

また本内容からは外れますが、Unityエディタ上で姉妹のRigをHumanoidに変更した場合、姉妹ともに両手の人差し指だけボーンが設定できていません。
手動でセットしてやる必要があります。
f:id:onoty3d:20150901192458p:plain

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

namespace NakaSis
{
    public class FaceUpdate : MonoBehaviour
    {
        public SkinnedMeshRenderer EyeBall;
        public SkinnedMeshRenderer Face;

        //各スライダーの現在値を保持するリスト
        private List<float> _sliderValues;

        //BlendShape名の表示スタイル
        private GUIStyle _labelTitleStyle;

        //スライダー値の表示スタイル
        private GUIStyle _labelValueStyle;

        private int _blendShapeCount;

        private void Start()
        {
            if (this.EyeBall == null || this.Face == null) return;

            //blendShapeのカウント
            this._blendShapeCount = this.EyeBall.sharedMesh.blendShapeCount + this.Face.sharedMesh.blendShapeCount;
            this._sliderValues = Enumerable.Repeat<float>(0f, this._blendShapeCount).ToList();

            this._labelTitleStyle = new GUIStyle { fixedWidth = 190f, alignment = TextAnchor.MiddleRight, normal = new GUIStyleState { textColor = Color.white } };
            this._labelValueStyle = new GUIStyle { fixedWidth = 20f, alignment = TextAnchor.MiddleRight, normal = new GUIStyleState { textColor = Color.white } };
        }

        private void OnGUI()
        {
            if (this.EyeBall == null || this.Face == null) return;

            GUILayout.Box("", GUILayout.Width(330), GUILayout.Height(15 * (this._blendShapeCount + 1)));
            Rect screenRect = new Rect(10, 10, 300, 15 * (this._blendShapeCount + 1));
            GUILayout.BeginArea(screenRect);

            var sliderIndex = 0;
            //EyeBall
            for (var defIndex = 0; defIndex < this.EyeBall.sharedMesh.blendShapeCount; defIndex++)
            {
                sliderIndex = defIndex;
                GUILayout.BeginHorizontal();

                //BlendShape名
                var labelName = this.EyeBall.sharedMesh.GetBlendShapeName(defIndex);
                labelName = labelName.Substring(labelName.IndexOf('.') + 1);
                GUILayout.Label(labelName, this._labelTitleStyle);

                //スライダー
                this._sliderValues[sliderIndex] = GUILayout.HorizontalSlider(this._sliderValues[sliderIndex], 0f, 100f);

                //スライダーの値
                GUILayout.Label(((int)this._sliderValues[sliderIndex]).ToString("#0"), this._labelValueStyle);

                GUILayout.EndHorizontal();

                //スライダーの値をBlendShapeに反映
                this.EyeBall.SetBlendShapeWeight(defIndex, this._sliderValues[sliderIndex]);
            }

            //Face
            var adjustCount = this.EyeBall.sharedMesh.blendShapeCount;
            for (int defIndex = 0; defIndex < this.Face.sharedMesh.blendShapeCount; defIndex++)
            {
                sliderIndex = adjustCount + defIndex;
                GUILayout.BeginHorizontal();

                //BlendShape名
                var labelName = this.Face.sharedMesh.GetBlendShapeName(defIndex);
                labelName = labelName.Substring(labelName.IndexOf('.') + 1);
                GUILayout.Label(labelName, this._labelTitleStyle);

                //スライダー
                this._sliderValues[sliderIndex] = GUILayout.HorizontalSlider(this._sliderValues[sliderIndex], 0f, 100f);

                //スライダーの値
                GUILayout.Label(((int)this._sliderValues[sliderIndex]).ToString("#0"), this._labelValueStyle);

                GUILayout.EndHorizontal();

                //スライダーの値をBlendShapeに反映
                this.Face.SetBlendShapeWeight(defIndex, this._sliderValues[sliderIndex]);
            }
            GUILayout.EndArea();
        }

        private void Update()
        {
        }
    }
}