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

Onoty3D

Unityに関するメモとか

プロ生ちゃんのスパッツ・靴下・靴以外も切り替えられるようにする

プロ生ちゃん新モデルに含まれているプレハブで
PronamaChan_dynamic_base
という名前のものには、EquipmentsChangerというスクリプトがつけてあります。
このスクリプトは、靴下・靴・スパッツの表示切り替えが出来るスクリプトです。
f:id:onoty3d:20160927195758g:plain

ですが場合によってはもっとスポーティに見える画も作りたかったりするじゃないですか。
こんな。
f:id:onoty3d:20160927200136p:plain
なのでEquipmentsChangerをもう少し改良してスカート・時計の表示切り替えも出来るようにしてみました。
おまけでブルマモードも作ったよ。

ソースこちら。

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

namespace PronamaChan
{
    public class EquipmentsChanger2 : MonoBehaviour
    {
        public Material TransparentMaterial;
        public SkinnedMeshRenderer SkinnedMesh;

        public bool ShowSpats = false;
        public bool ShowSocks = true;
        public bool ShowShoes = true;
        public bool ShowSkirt = true;
        public bool ShowWatch = true;
        public bool ShowBuruma = false;

        [TooltipAttribute("太もも\nすね\nつま先\n靴下すね\n靴下つま先\nパンツ\nスパッツ\n\nスカート\nスカート裏\n時計\nの順でMaterialのIndexをセット")]
        public int[] MaterialIndexes = new[] { 1, 3, 2, 10, 9, 0, 5, 8, 11, 12, 26 };

        private Dictionary<MaterialIndexesKey, Material> _materialsDic;

        private enum MaterialIndexesKey
        {
            /// <summary>太もも</summary>
            Thigh,

            /// <summary>すね</summary>
            Shin,

            /// <summary>つま先</summary>
            Toe,

            /// <summary>靴下すね</summary>
            SocksShin,

            /// <summary>靴下つま先</summary>
            SocksToe,

            /// <summary>パンツ</summary>
            Pants,

            /// <summary>スパッツ</summary>
            Spats,

            /// <summary></summary>
            Shoes,

            /// <summary>スカート</summary>
            Skirt,

            /// <summary>スカート裏</summary>
            SkirtReverse,

            /// <summary>時計</summary>
            Watch
        }

        // Use this for initialization
        private void Start()
        {
            this.StoreMaterials();
            this.ChangeEquipments();
        }

        // Update is called once per frame
        private void Update()
        {
        }

        private void StoreMaterials()
        {
            this._materialsDic = new Dictionary<MaterialIndexesKey, Material>();
            var materials = this.SkinnedMesh.sharedMaterials;

            foreach (var item in Enum.GetValues(typeof(MaterialIndexesKey)).Cast<MaterialIndexesKey>().Select((x, i) => new { Index = i, Key = x }))
            {
                this._materialsDic[item.Key] = materials[this.MaterialIndexes[item.Index]];
            }

            //スパッツのRenderQuereを太もものそれより大きくしておく
            this._materialsDic[MaterialIndexesKey.Spats].renderQueue = this._materialsDic[MaterialIndexesKey.Thigh].renderQueue + 1;
        }

        private void OnValidate()
        {
            this.ChangeEquipments();
        }

        private void ChangeEquipments()
        {
            if (_materialsDic == null) return;

            var renderer = this.SkinnedMesh.GetComponent<Renderer>();
            var materials = renderer.sharedMaterials;

            if (this.ShowBuruma)
            {
                this.ChangeToOrigin(materials, MaterialIndexesKey.Pants);
                this.ChangeToOrigin(materials, MaterialIndexesKey.Thigh);
                this.ChangeToTransparent(materials, MaterialIndexesKey.Spats);

                //パンツのマテリアルをスパッツのものに置き換え
                materials[this.MaterialIndexes[(int)MaterialIndexesKey.Pants]] = this._materialsDic[MaterialIndexesKey.Spats];
            }
            else
            {
                //スパッツのマテリアルをパンツのものに置き換え
                materials[this.MaterialIndexes[(int)MaterialIndexesKey.Spats]] = this._materialsDic[MaterialIndexesKey.Pants];

                //スパッツの表示切り替えが有効なのは、ブルマ非表示の時のみ
                if (this.ShowSpats)
                {
                    this.ChangeToTransparent(materials, MaterialIndexesKey.Pants);
                    this.ChangeToTransparent(materials, MaterialIndexesKey.Thigh);
                    this.ChangeToOrigin(materials, MaterialIndexesKey.Spats);
                }
                else
                {
                    this.ChangeToOrigin(materials, MaterialIndexesKey.Pants);
                    this.ChangeToOrigin(materials, MaterialIndexesKey.Thigh);
                    this.ChangeToTransparent(materials, MaterialIndexesKey.Spats);
                }
            }

            if (this.ShowSocks)
            {
                this.ChangeToTransparent(materials, MaterialIndexesKey.Shin);
                this.ChangeToTransparent(materials, MaterialIndexesKey.Toe);
                this.ChangeToOrigin(materials, MaterialIndexesKey.SocksShin);

                if (this.ShowShoes)
                {
                    this.ChangeToTransparent(materials, MaterialIndexesKey.SocksToe);
                    this.ChangeToOrigin(materials, MaterialIndexesKey.Shoes);
                }
                else
                {
                    this.ChangeToOrigin(materials, MaterialIndexesKey.SocksToe);
                    this.ChangeToTransparent(materials, MaterialIndexesKey.Shoes);
                }
            }
            else
            {
                this.ChangeToOrigin(materials, MaterialIndexesKey.Shin);
                this.ChangeToTransparent(materials, MaterialIndexesKey.SocksShin);
                this.ChangeToTransparent(materials, MaterialIndexesKey.SocksToe);

                if (this.ShowShoes)
                {
                    this.ChangeToTransparent(materials, MaterialIndexesKey.Toe);
                    this.ChangeToOrigin(materials, MaterialIndexesKey.Shoes);
                }
                else
                {
                    this.ChangeToOrigin(materials, MaterialIndexesKey.Toe);
                    this.ChangeToTransparent(materials, MaterialIndexesKey.Shoes);
                }
            }

            if (this.ShowSkirt)
            {
                this.ChangeToOrigin(materials, MaterialIndexesKey.Skirt);
                this.ChangeToOrigin(materials, MaterialIndexesKey.SkirtReverse);
            }
            else
            {
                this.ChangeToTransparent(materials, MaterialIndexesKey.Skirt);
                this.ChangeToTransparent(materials, MaterialIndexesKey.SkirtReverse);
            }

            if (this.ShowWatch)
            {
                this.ChangeToOrigin(materials, MaterialIndexesKey.Watch);
            }
            else
            {
                this.ChangeToTransparent(materials, MaterialIndexesKey.Watch);
            }

            renderer.sharedMaterials = materials;
        }

        /// <summary>
        /// マテリアルを元に戻す
        /// </summary>
        /// <param name="materials"></param>
        /// <param name="key"></param>
        private void ChangeToOrigin(Material[] materials, MaterialIndexesKey key)
        {
            materials[this.MaterialIndexes[(int)key]] = this._materialsDic[key];
        }

        /// <summary>
        /// マテリアルを透過のものに置き換える
        /// </summary>
        /// <param name="materials"></param>
        /// <param name="key"></param>
        private void ChangeToTransparent(Material[] materials, MaterialIndexesKey key)
        {
            materials[this.MaterialIndexes[(int)key]] = this.TransparentMaterial;
        }
    }
}

これをプロ生ちゃんに適用させれば、スカート・時計の表示切り替えとパンツ・スパッツ・ブルマの表示切り替えができるようになります。
マテリアルのインデックスはTシャツモデルのものに併せているので、他モデルでも使いたい場合はEquipmentsChangerの設定値を参考にセットしてみてください。
SDモデルはスカートのマテリアルがひとつなので、同じインデックスを指定すればいいと思います(試してないけど)。
なおブルマ表示モードのときはスパッツ・パンツの切り替えが出来ない仕様になってるのでご注意ください。