そういうのがいいブログ

アプリ個人開発 まるブログ

アプリ開発覚え書き

【Unity】All In 1 Sprite Shader でAndroidとiOSで動的に設定を切り替えられない時の対処法

要件

Unity2022.3.16f1
All In 1 Sprite Shader:3.7

はじめに

スプライトの見栄えを簡単に良くすることができるアセット
All In 1 Sprite Shader

こちらの設定を動的に変更した設定で実機確認をしたところ
AndroidiOSでは設定した内容が無視されました。(Unityエディター上では動く)

本記事は対処法のメモになります。

スクリプト例はUniTaskを使用しています。)

うまくいかなかった方法

シェーダーの設定をスクリプトから直接操作
→Unityエディター上では動くが、Andorid,iOSでは動かない
 エラーも何もなく無視されている様子

    private void Start()
    {
        spriteRenderer = gameObject.GetComponent<SpriteRenderer>();
    }

    public async void PlayDamageEffect()
    {
        // 発光処理
        spriteRenderer.material.EnableKeyword("GLOW_ON");
        spriteRenderer.material.SetFloat("_Glow", 0f);
        spriteRenderer.material.SetFloat("_GlowGlobal", 3.0f);

        // エフェクトを一定時間後に元に戻す
        await UniTask.Delay(TimeSpan.FromSeconds(0.04f));
        spriteRenderer.material.DisableKeyword("GLOW_ON");
    }

うまくいった方法

次の2ステップで実現できました。
1.Unity上で再現したいアニメーションを作成
2.作成したアニメーションをスクリプトから操作

1.Unity上で再現したいアニメーションを作成

良質な記事がネット上にたくさんありますので作成方法は省略します。

アセット製作者様の動画が参考になります。
youtu.be

2.作成したアニメーションをスクリプトから操作

以下のようなスクリプトでアニメーションを再生します。
攻撃を受けたときに1回だけ光らせたい場合のスクリプトになります。

    private Animator animator; // Animatorコンポーネント
    [SerializeField] private AnimationClip glowAnimationClip;//操作するアニメーションクリップの名前取得用
    private string glowAnimationClipName;  //操作するアニメーションクリップの名前

    private void Start()
    {        
        animator = gameObject.GetComponent<Animator>();
        animator.speed = 0;
        glowAnimationClipName = glowAnimationClip.name;
    }

    public async void PlayDamageEffect()
    {
        //アニメーションクリップの名前,対象のレイヤー -1でアクティブなレイヤーを指定,開始時間
        animator.Play(glowAnimationClipName, -1, 0f);
        animator.speed = 1; // 通常速度で再生

        // アニメーションの長さを取得
        float clipLength = GetAnimationClipLength(glowAnimationClipName);

        // アニメーション時間分待機
        await UniTask.Delay(TimeSpan.FromSeconds(clipLength));

        // アニメーションを再生することで初期状態に戻しアニメーション停止
        animator.Play(glowAnimationClipName, -1, 0f);
        animator.speed = 0; 
    }

    //アニメーションの時間を取得
    float GetAnimationClipLength(string clipName)
    {
        AnimationClip[] clips = animator.runtimeAnimatorController.animationClips;
        foreach (AnimationClip clip in clips)
        {
            if (clip.name == clipName)
                return clip.length;
        }
        return 0f;
    }

アニメーションのスクリプト操作についてはもっと良い方法があるはずです。

おわりに

All In 1 Sprite Shaderで動的に変更させたい場合は
アニメーションを使用する必要がある!

お伝えしたいのはこれだけです。
収穫がありましたら幸いです。

参考

All In 1 Sprite Shadeの使い方
kan-kikuchi.hatenablog.com


Unityフォーラム forum.unity.com