kenjizenki

すみません、ちょっとうまくいかなかったので相談させていただきます。

Unity上で現在反映されているSkin名一覧を取得する方法について伺いたく思います。

SnapCrab_NoName_2021-12-4_23-39-57_No-00.png

Spineのサンプルのきせかえ女の子がいますが、こちらで例えると、
上着、スカート、帽子などでスキンが変わっているかと思いますが、その反映されているSkin名の一覧を取得したいと思っています。

スクリプトでもそれ以外の方法でもよいのですが、ご意見いただけますと幸いです。
添付ファイルを見るにはパーミッションが必要です
アバター
kenjizenki
  • 記事: 67

Misaki

ご返信が遅くなってしまい申し訳ありません!

ご質問の件ですが、複数のスキンを組み合わせる場合、組み合わせたスキンを適用した後で現在スケルトンに当てられているスキン名を直接取得しても、元々何のスキンを組み合わせているのかを取得することは出来ません。
そのため、まず最初に各部位ごとのスキン用にstringを宣言しておき、それらを使用してスキンを組み合わせるような構成にして、各スキンのstringの値を取得することで現在の組み合わせがどうなっているかを確認するのが一般的かと思います。
つまり、ベースとなるのはspine-unityランタイムに含まれているサンプルスクリプトScripts/Mix and Match Character Customize/MixAndMatchSkinsExample.csと同じ構成です。

MixAndMatchSkinsExample.csのように、最初に
[SpineSkin] public string baseSkin = "skin-base";
[SpineSkin] public string eyelidsSkin = "eyelids/girly";
のように各パーツごとのスキン名を代入するstring変数を宣言して、
スキンの組み合わせの変更を行いたい時は各stringに新しい値を代入した後、
以下のようなメソッドでキャラクターのスキンを更新します。
void UpdateCharacterSkin () {
var skeleton = skeletonAnimation.Skeleton;
var skeletonData = skeleton.Data;
characterSkin = new Skin("character-base");
characterSkin.AddSkin(skeletonData.FindSkin(baseSkin));
characterSkin.AddSkin(skeletonData.FindSkin(eyelidsSkin));
skeleton.SetSkin(characterSkin);
skeleton.SetSlotsToSetupPose();
}
このような構成にした上で、上の例でいうところのbaseSkineyelidsSkinの値を取得して現在のスキンがどんな組み合わせになっているかを取得するようにしていただくのが良いと思います。

MixAndMatchSkinsExample.csでは、着せ替え機能などでより管理しやすい、string配列を使う例も紹介されていますので詳しくは実際のスクリプトをご覧ください。

上記回答が参考になれば幸いです。
アバター
Misaki

Misaki
  • 記事: 340

kenjizenki

ありがとうございます。
上記でいただきました、設定するスキン名を保存しておく方法で対応しようと思います。

また、少し別件になってしまうのですが、現在
①衣装変更用のアニメーションをさせ、Spine内に実装したエフェクトでキャラクターを隠す
②アニメーション内でイベントを飛ばす。
③イベントを受け取った瞬間に例で頂いたようなスクリプトでスキンを変更
④Spine内に実装したエフェクトをはずすとキャラクターのスキン変更が終わっている

というものを作っているのですが、スキンを反映させようとする際に
skeleton.SetSlotsToSetupPose();
をすると「Spine内に実装したエフェクト」が1Fだけ外れてしまうようです。
こちら、防ぐ方法などございますでしょうか……
アバター
kenjizenki
  • 記事: 67

Harald

コードの結果が1フレーム遅れてしまう場合は、複数のスクリプトの単一のUnity Update()サイクルでコードが遅れてしまっているという問題が発生している可能性があります。 SetSlotsToSetupPose()を呼び出した後に skeletonAnimation.Update(0)を呼び出していますか?

もし私があなたの問題の説明を誤解してしまっている場合はその旨をお知らせください。
-----
If you see results of your code one frame too late, it might likely be the problem that your code is called too late in a single Unity Update() cycle of multiple scripts. Are you calling skeletonAnimation.Update(0) after calling SetSlotsToSetupPose()?

Please let me know in case I misunderstood your problem description.

---

再現用のUnityプロジェクトをお送りいただきありがとうございました。

問題は、SetSlotsToSetupPoseの後に SkeletonAnimation.Update(0) の呼び出しが抜けていることだけです。
Anim.skeleton.SetSlotsToSetupPose();
Anim.Update(0);
投稿を見逃したか、機械翻訳が悪かったのかと思いますが、これはこのフォーラム投稿の上の方で私が提案したものです。
-----
Thanks for sending the reproduction Unity project.

The problem is just that there is a missing call to SkeletonAnimation.Update(0) after SetSlotsToSetupPose:
Anim.skeleton.SetSlotsToSetupPose();
Anim.Update(0);
This is what I suggested on the forum posting above, perhaps you missed the post or it was badly machine-translated.
アバター
Harald

Harri
  • 記事: 3611

kenjizenki

失礼しました!
頂いた内容の
Anim.Update(0);
を入れたところ正常に動きました!
勘違いしてしまい、お手数をおかけしました。
ありがとうございました!

I beg your pardon!
I'm sorry about the content you gave me
Update(0);
and it worked fine!
I'm sorry for my mistake and I apologize for the trouble.
Thank you very much!
アバター
kenjizenki
  • 記事: 67

Harald

謝る必要はありません。私たちのメッセージは誤解を招きやすかったと思われます。問題が解決してよかったです。
No need to apologize, we are sure our message was easy to misunderstand. Thanks for getting back to us, glad the problem could be resolved.
アバター
Harald

Harri
  • 記事: 3611


Return to 日本のSpine ユーザー