質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

Q&A

解決済

1回答

2767閲覧

Unityにて設定した表情(BlendShape)を、任意のキーボード入力で切り替えたい

tkdoxsoxdg

総合スコア10

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

0グッド

0クリップ

投稿2018/11/02 20:29

Unityにて設定した表情を、任意のキーボード入力によって切り替える処理について皆さまの知見からご教示賜りたく質問させていただきました。
以下、詳細です。

開発環境
・Unity 2018.2.14f1
・Visual Studio 2017

実装案
以下の2つの案を出して、「①」で実装する方向で決定しました。
①モデリングで作成したBlendShapeを任意のキーボード入力で切り替える。
②作成したAnimationを任意のキーボード入力で切り替える。

Unityにて設定した内容
・SkinnedMeshRendererを対象のモデルに設定
・上記モデルに対してスクリプト作成(後述します)

実装したスクリプト

C#

1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4 5public class blenderShapeControll : MonoBehaviour { 6 public GameObject head; 7 public SkinnedMeshRenderer facialExpression; 8 public float weight; 9 public int angry; 10 public int sad; 11 12 13 // Use this for initialization 14 void Start() { 15 angry = facialExpression.sharedMesh.GetBlendShapeIndex("eye_angry"); 16 head = GameObject.Find("head"); 17 facialExpression = GetComponent<SkinnedMeshRenderer>(); 18 19 } 20 21 // Update is called once per frame 22 void Update() { 23 if (Input.GetKey(KeyCode.A)) 24 { 25 if(facialExpression.GetBlendShapeWeight(angry) <= 0) 26 { 27 weight = 100; 28 facialExpression.SetBlendShapeWeight(angry, weight); 29 } 30 } else { 31 weight = 0; 32 facialExpression.SetBlendShapeWeight(angry, weight); 33 } 34 } 35 36 }

実行結果
以下のエラーが出力されました。
Array index (-1) is out of bounds (size=17) UnityEngine.SkinnedMeshRenderer:SetBlendShapeWeight(Int32, Single) blenderShapeControll:Update() (at Assets/Scripts/blenderShapeControll.cs:32)

「angry」に入っているインデックスの値が「-1」で入っているために起こったエラーと認識しました。
上記以外に、適切な実装方法や作成方法についてのページについて皆さまの知見からご教示賜りさく思います。

不足している情報などありましたら、お知らせください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

Mesh.GetBlendShapeIndex - Unity スクリプトリファレンスによれば、ブレンドシェイプ名が見つからない場合に-1になるそうですね(「指定インデックスの BlendShape のインデックスを返します。」とありますが、正しくはブレンドシェイプ名からインデックスを得るメソッドということでしょう)。

下記のようなコードでブレンドシェイプ名を調べられるかと思いますが、「eye_angry」で合っていそうでしょうか?

C#

1 void Start() 2 { 3 angry = facialExpression.sharedMesh.GetBlendShapeIndex("eye_angry"); // ここと... 4 head = GameObject.Find("head"); 5 facialExpression = GetComponent<SkinnedMeshRenderer>(); // ここの順序はこれで正しいのでしょうか? 6 // 上記の順序では「インスペクタであらかじめセットしたレンダラーからeye_angryのインデックスを取得」してから 7 // 「facialExpressionをこのオブジェクトにアタッチされたレンダラーで上書き」しています 8 // angryを取得するコードはGetComponent<SkinnedMeshRenderer>より後の方が自然な気がするのですが... 9 10 // angry = facialExpression.sharedMesh.GetBlendShapeIndex("eye_angry"); 11 12 // メッシュが持つブレンドシェイプの名前をコンソールに出力してみる 13 var mesh = facialExpression.sharedMesh; 14 var shapeCount = mesh.blendShapeCount; 15 Debug.LogFormat("Mesh {0} has {1} shapes.", mesh.name, shapeCount); 16 for (var i = 0; i < shapeCount; i++) 17 { 18 Debug.LogFormat("\t{0}: {1}", i, mesh.GetBlendShapeName(i)); 19 } 20 }

コンソール

投稿2018/11/03 00:21

Bongo

総合スコア10807

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tkdoxsoxdg

2018/11/03 09:02 編集

ご回答ありがとうございます。 ご指摘いただきました内容から、ブレンドシェイプ名を確認したところ名前が間違っていました。 ブレンドシェイプ名を正しい名前にて、実行したところ該当するエラーは出力されませんでした。 ご教示ありがとうございます!! ※追記 ご教示いただいたスクリプトで、表情が変化することができました!! 本当にありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問