■Unity開発メモ用のWiki◎現在扱っていること・Unity全般・MMDからUnityへの変換してインポート・MMDの仕様把握・BlenderでMMDモデルのカスタム

目次


一時メモ

体位の翻訳だけならもっとスマートな方法がある

場所が変わるモーションはまとめた方が良い

デバッグ用意に追加体位は先頭に*マークをつける?

体位メニューの並び替え

後でする
→タグでソートする

実際のGOLマクロ

  • ソートされない場合、メニューをもう一度開閉すれば行う
  • VRはまだ未対応→対応

↓ご自由にお使いください(GitHubの使い方を覚えたらそちらで管理するかも?)

VR対応

修正箇所:1:GUIのヒエラルキー(パス)がVRだと少し違うので「Canvas/」を削除
修正前
GameObject.Find("Canvas/ActionSubMenu/Mouth/Viewport/MouthCategory");
  ↓
修正後
GameObject.Find("ActionSubMenu/Mouth/Viewport/MouthCategory");
修正箇所:2:現在のシーンの判定部にVR時のHシーンを追加
修正前
if (GetLoadSceneName() == "H")
  ↓
修正後
if (GetLoadSceneName() == "H" || GetLoadSceneName() == "VRHScene")

仕様



独自に番号を振る
挿入の場合
0:正常位
1:バック
2:騎乗位
3:立位
4:イス
5:机
6:壁際
7:その他(平面・その他)
8:特殊H
9:本編でノットフォーミーな体位

奉仕・手足の場合
0:手コキ
1:足コキ
2:素股
3:その他
9:ノットフォーミー


green
yellow
cyan
white
 
grey

テキストメッシュプロ関連

Visual Studioでテキストメッシュプロを使う場合
Unityから「Unity.TextMeshPro.dll」をコピーし参照追加すること
using TMPro;
文字の色を変更する
                    var ho = children_Sounyu[i].GetComponent<TextMeshProUGUI>();
                    ho.text = "0:カニ挟み正常位";
                    ho.color = Color.white;

文字の左寄せ
                    var ho = children_Sounyu[i].GetComponent<TextMeshProUGUI>();
                    ho.text = "0正常位";
                    ho.alignment = TextAlignmentOptions.Left;

スクロールメニュー関連

ScrollView
参考:【Unity】ScrollViewの使い方、スクリプトからテキスト一覧表示の設定をする:https://www.chuken-engineer.com/entry/2019/11/12/1...
参考:【Unity】ScrollViewを理解したい(※随時追記予定):https://taidanahibi.com/unity/unity-scrollview/



Unityの以下の機能を使っている
  • Scroll Rect(≒ScrollView?)
→スクロール機能関連
  • Vertical Layout Group
→uGUIの自動レイアウト
子オブジェクトを縦方向に自動で整列させる機能です。
【Child Control Size】は子要素のサイズを制御する設定
【Child Force Expand】は子要素を引き延ばす設定
今回はどちらも【Width】のみ有効とする

  • ContentSizeFitter
→UIの横幅と縦の高さをコンテンツのサイズを自動調整してくれる
Contentの子要素を推奨サイズに合わせて自動的に設定
今回は縦方向で合わせるので【Vertical Fit】を【Preferred Size】に設定

ソート関連

参考
【Unity】子オブジェクトを取得する4つの方法:https://zenn.dev/daichi_gamedev/articles/b901ca3a1...
[Unity] ヒエラルキーのGameObjectの順序をスクリプトから取得・操作する:https://ftvoid.com/blog/post/864
[Unity] ヒエラルキー上のGameObjectのソート:https://ftvoid.com/blog/post/869

注意点
  • メニューが閉じられた時にリストを初期化する?
  • 「挿入」と各種「奉仕」で取得する子階層のGameObjectの位置が違うので注意する

//メニューのソート
void Translate_SEX_sotr()
{
        // 子階層のGameObject取得
        var hoge_childCount = GameObject.Find("Canvas/ActionSubMenu/Sonyu/Viewport/SonyuCategory");

        if (Translate_SEX_Flag == true) { }
        //奉仕・手足の場合
        if (Translate_houshoA_Flag == true)
        {
            hoge_childCount = GameObject.Find("Canvas/ActionSubMenu/Hand/Viewport/HandCategory");
        }
        //奉仕・口の場合
        if (Translate_houshoB_Flag == true)
        {
            hoge_childCount = GameObject.Find("Canvas/ActionSubMenu/Mouth/Viewport/MouthCategory");
        }
        //奉仕・胸の場合
        if (Translate_houshoC_Flag == true)
        {
            hoge_childCount = GameObject.Find("Canvas/ActionSubMenu/Breast/Viewport/BreastCategory");
        }

    var childCount = hoge_childCount.transform.childCount;
    UnityEngine.Debug.Log("childCount::" + childCount);

    //子のオブジェクトを取得し「Text」コンポーネントのTextを取得?
    GetChildren(this.gameObject);
    GetChildren(hoge_childCount.gameObject);

    // ソート結果順にGameObjectの順序を反映
    foreach (var obj in objList)
    {
        //今回はオブジェクトの親の親を操作する
        var par_obj = obj.parent.parent;
		//指定のインデックスに Transform を移動させる
        par_obj.SetSiblingIndex(childCount - 1);

    }
}

//子オブジェクトの全て(子の子の子のオブジェクトとかも)を取得する
void GetChildren(GameObject obj)
{
    Transform children = obj.GetComponentInChildren<Transform>();

    //子要素がいなければ終了
    if (children.childCount == 0)
    {
        return;
    }

    foreach (Transform ob in children)
    {
        //孫の場合の処理
        var chi_obj1_txt = ob.GetComponent<TextMeshProUGUI>();
        if (chi_obj1_txt != null)
        {
            //リストへの追加処理
            objList.Add(ob);
            //リストのソート→ラムダ式→文字列の比較
            objList.Sort((obj1, obj2) => string.Compare(obj1.GetComponent<TextMeshProUGUI>().text, obj2.GetComponent<TextMeshProUGUI>().text));
        }

        GetChildren(ob.gameObject);
    }
}

メインの制御関連

    // 挿入の子オブジェクト達を入れる配列
    Transform[] children_Sounyu;
    // 奉仕→手/足の子オブジェクト達を入れる配列
    Transform[] children_Houshi_hand;
    // 奉仕→口の子オブジェクト達を入れる配列
    Transform[] children_Mouth;
    // 奉仕→胸の子オブジェクト達を入れる配列
    Transform[] children_Breast;

    //ソート用のリスト
    List<Transform> objList = new List<Transform>();

    //翻訳判定用のフラグ
    bool Translate_SEX_Flag = false;
    bool Translate_houshoA_Flag = false;
    bool Translate_houshoB_Flag = false;
    bool Translate_houshoC_Flag = false;

    //TextAsset csvFile; // CSVファイル
    List<string[]> csvDatas = new List<string[]>(); // CSVの中身を入れるリスト;

    void Update()
    {
        //このマクロではメニューを遷移したら、その都度翻訳されているかチャックし逐次翻訳する必要がある
        //挿入アイコンが押したかのチェック

        //Hシーンの時のみ処理する
        if (GetLoadSceneName() == "H")
        {

            //----------------------------
            //挿入メニューの翻訳・ここから
            //挿入メニューのオブジェクトを取得
            var a_sounyu = GameObject.Find("SonyuCategory");
            //ヌルチェック
            if (a_sounyu != null)
            {
                //挿入メニューが開かれてかつ未翻訳の場合のみ実行する
                if (a_sounyu.activeSelf == true)
                {
                    //未翻訳の場合のみ実行する
                    if (Translate_SEX_Flag == false)
                    {
                        //翻訳フラグON
                        Translate_SEX_Flag = true;
                        //挿入メニューの翻訳
                        Sounyu_Translate();
                        //挿入メニューのソート処理
                        Translate_SEX_sotr();
                    }
                }
            }
            //挿入メニューが閉じられたら翻訳フラグをOFFにする
            if (a_sounyu == null)
            {
                Translate_SEX_Flag = false;
                objList = new List<Transform>();
            }
            //挿入メニューの翻訳・ここまで
            //----------------------------

            //----------------------------
            //奉仕→手・足メニューの翻訳・ここから
            //奉仕→手・足メニューのオブジェクトを取得
            var a_houshiA = GameObject.Find("HandCategory");
            //ヌルチェック
            if (a_houshiA != null)
            {
                //メニューが開かれてかつ未翻訳の場合のみ実行する
                if (a_houshiA.activeSelf == true)
                {
                    //未翻訳の場合のみ実行する
                    if (Translate_houshoA_Flag == false)
                    {
                        //翻訳フラグON
                        Translate_houshoA_Flag = true;
                        //奉仕→手・足メニューの翻訳
                        Houshi_Hand_Translate();
                        //奉仕→手・足メニューのソート処理
                        Translate_SEX_sotr();
                    }
                }
            }
            //メニューが閉じられたら翻訳フラグをOFFにする
            if (a_houshiA == null)
            {
                Translate_houshoA_Flag = false;
                objList = new List<Transform>();
            }
            //奉仕→手・足メニューの翻訳・ここまで
            //----------------------------

            //----------------------------
            //奉仕→口メニューの翻訳・ここから
            //奉仕→口メニューのオブジェクトを取得
            var a_houshiB = GameObject.Find("MouthCategory");
            //ヌルチェック
            if (a_houshiB != null)
            {
                //メニューが開かれてかつ未翻訳の場合のみ実行する
                if (a_houshiB.activeSelf == true)
                {
                    //未翻訳の場合のみ実行する
                    if (Translate_houshoB_Flag == false)
                    {
                        //翻訳フラグON
                        Translate_houshoB_Flag = true;
                        //口メニューの翻訳
                        Houshi_mouth_Translate();
                        //メニューのソート処理
                        Translate_SEX_sotr();
                    }
                }
            }
            //メニューが閉じられたら翻訳フラグをOFFにする
            if (a_houshiB == null)
            {
                Translate_houshoB_Flag = false;
                objList = new List<Transform>();
            }
            //奉仕→口メニューの翻訳・ここまで
            //----------------------------

            //----------------------------
            //奉仕→胸メニューの翻訳・ここから
            //奉仕→胸メニューのオブジェクトを取得
            var a_houshiC = GameObject.Find("BreastCategory");
            //ヌルチェック
            if (a_houshiC != null)
            {
                //メニューが開かれてかつ未翻訳の場合のみ実行する
                if (a_houshiC.activeSelf == true)
                {
                    //未翻訳の場合のみ実行する
                    if (Translate_houshoC_Flag == false)
                    {
                        //翻訳フラグON
                        Translate_houshoC_Flag = true;
                        //胸メニューの翻訳
                        Houshi_Breast_Translate();
                        //メニューのソート処理
                        Translate_SEX_sotr();
                    }
                }
            }
            //メニューが閉じられたら翻訳フラグをOFFにする
            if (a_houshiC == null)
            {
                Translate_houshoC_Flag = false;
                objList = new List<Transform>();
            }
            //奉仕→胸メニューの翻訳・ここまで
            //----------------------------

        }
    }

翻訳関連

体位「Amazon」の場合
  • Canvas→ActionSubMenu→Sonyu→Viewport→SonyuCategory→MainManuNode(Clone)→ScrollMask→TextMeshPro Text→→
→→コンポーネント「TextMeshProUGUI」→プライベート変数「text」
    • 「Canvas→ActionSubMenu→Sonyu→Viewport→SonyuCategory」までは「active」かチェックした方が良い?
    • 「MainManuNode(Clone)」は動的に作られている?
    • 「text」と原訳が一致するかチェックする?


挿入や奉仕のメニュー(TextMeshProUGUI)がある場所
        //奉仕・手足の場合(HandCategory)
        //Canvas→ActionSubMenu→Hand→Viewport→HandCategory→MainManuNode(Clone)→ScrollMask→TextMeshPro Text→→
        //→→コンポーネント「TextMeshProUGUI」→プライベート変数「text」
        var parent = GameObject.Find("Canvas/ActionSubMenu/Hand/Viewport/HandCategory");

        //奉仕・口の場合(MouthCategory)
        //Canvas→ActionSubMenu→Mouth→Viewport→MouthCategory→MainManuNode(Clone)→ScrollMask→TextMeshPro Text→→
        //→→コンポーネント「TextMeshProUGUI」→プライベート変数「text」
        var parent = GameObject.Find("Canvas/ActionSubMenu/Mouth/Viewport/MouthCategory");

        //奉仕・胸の場合(BreastCategory)
        //Canvas→ActionSubMenu→Breast→Viewport→BreastCategory→MainManuNode(Clone)→ScrollMask→TextMeshPro Text→→
        //→→コンポーネント「TextMeshProUGUI」→プライベート変数「text」
        var parent = GameObject.Find("Canvas/ActionSubMenu/Breast/Viewport/BreastCategory");

        //挿入の場合(SonyuCategory)
        //Canvas→ActionSubMenu→Sonyu→Viewport→SonyuCategory→MainManuNode(Clone)→ScrollMask→TextMeshPro Text→→
        //→→コンポーネント「TextMeshProUGUI」→プライベート変数「text」
        var parent = GameObject.Find("Canvas/ActionSubMenu/Sonyu/Viewport/SonyuCategory");

テキストメッシュプロの書き換え設定の箇所はスプレッドシートで記述・管理・連結してコピペしている
→筆者の力量的にCSVやXMLでの制御は……
    //奉仕→胸メニューの翻訳
    void Houshi_Breast_Translate()
    {
        var parent = GameObject.Find("Canvas/ActionSubMenu/Breast/Viewport/BreastCategory");

        //目標のオブジェクトがアクティブでヌルでない場合
        if (parent != null)
        {
            // 子オブジェクト達を入れる配列の初期化
            children_Breast = new Transform[parent.transform.childCount];

            for (int i = 0; i < parent.transform.childCount; i++)
            {
                // GetChild()で子オブジェクトを取得
                children_Breast[i] = parent.transform.GetChild(i);
                children_Breast[i] = children_Breast[i].Find("ScrollMask/TextMeshPro Text");

                //テキストメッシュプロのコンポーネントを取得
                string[] text01;
                text01 = new string[parent.transform.childCount];
                text01[i] = children_Breast[i].GetComponent<TextMeshProUGUI>().text;

                //ゴリ押しで羅列していく
                if (text01[i] == "Grabbed Boobs Fuck") { children_Breast[i].GetComponent<TextMeshProUGUI>().text = "またがりパイズリ"; }
                if (text01[i] == "Lying Grabbed Boobs Fuck") { children_Breast[i].GetComponent<TextMeshProUGUI>().text = "馬乗りパイズリ"; }

            }
        }
    }

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu

【メニュー編集】

スカイリム関連

スカイリム関連


Menu

【メニュー編集】

スクリプト関連

フリーエリア

管理人/副管理人のみ編集できます