Timeline形式でスキルエディターを実現する方法

今回の主な話題：Timeline形式でスキルエディターを実現する方法、AddressableがGroup Nameを介してGroupのKeyを取得する方法、UnityでSpriteがSprite PackerにあるUV値を取得する方法、UnityEditorでAnimatorControllerのすべての状態名を取得する方法、UnityはUGUIのMaskにどのような処理をしますか？

---
###Editor
Q：プロジェクトはTimelineの形でスキルエディターを実現する必要がありますが、Timelineの形式はどうやって実現できますか？スキルエディター全体に何か参照できるものありますか？

①
> Timelineの使用方法と伝統的なスキルエディターの実現方法を学び、それらを組み合わせる方法を検討することをお勧めします。

②
>公式のTimeline相関を参照でき、2017年のUniteにも関連トピックがありました。
https://assetstore.unity.com/packages/essentials/default-playables-95266

③
>FIRST、Timelineの形はどのように実現されますか？
いくつかのUnityプラグインを参照できます。
https://assetstore.unity.com/packages/tools/animation/cinematic-sequencer-slate-56558
>
このSLATEをお勧めします。拡張する方が便利です。
https://assetstore.unity.com/packages/tools/animation/flux-18440
>
SECOND、スキルエディターのアイデア。
>
上記のTimelineフレームワークがあったら、残った仕事はTimelineに基づいて様々タイプのフレームを開発することです。例えば、再生特殊効果フレーム、アニメーションフレームやヒットポイントフレームなどです。
>
特殊効果の例をあげます。
>
1、スキル特殊効果は、いくつかのパラメーターにすぎません。特殊効果名、オフセット情報、フックポイントなどです。
2、次に、このキーフレームを執行する時に具体的な執行方法を表示するビジネスコードを実現する必要があります。例えば、フレームに配置された特殊効果パラメーターによりこの効果をロードすること、オフセット情報とフックポイントパラメーターが設定する特殊効果のTransform。
3、フレームの長さは、この特殊効果のライフサイクルです。フレームが執行終了すると、フレームの破棄作業は必要です。

---
###Addressable
Q：Addressableは、Group Nameを介してこのGroupにあるKeyを取得できますか？

ホットアップデートをゲームの始める時に置いました。更新のプロセスは大体このように：ロードインターフェイスを作成し（アセットはAddressableに独立のGroupであり、しばらくstartGroupと呼びます）、そしてCatalogに更新があるかどうかを確認し、すべてのKey値を手に入れてアセットをダウンロードします。

このプロセスに問題はありません。しかし、更新中にネットワークが中断されると、Addressableは更新リストのアセットメモリを全部解放し、すべてのKeyを使用してダウンロードを行ったローディングインターフェイスアセットが失います（黒くなる）。

テスト後、startGroupにあるKeyを手動で除外したら、この問題はなくなります。だからGroup Nameを介してどうやってこのGroupのKeyを取得できますか？または、よりいい更新方案ありませんか？

①
>内部関数があります。
>
```ruby:
internal bool GetResourceLocations(object key, Type type, out IList<IResourceLocation> locations)
```
具体的な実現を参照できます。これもGetDownloadSizeAsyncのような関数が内部にコールしたものです。
資源の失い問題については、情報が足りなくて判断できません。

②
>startGroupにあるアセットのLabelをすべて「start」に設定し、Lableを介してLocationリストを取得し、そしてこのリストのKey値を合計リストから除外することができます。
>
```ruby:
public static List<string> GetAllKeys(string labelName)
{
    var t = Addressables.ResourceLocators;
    List<string> keys = new List<string>();
    foreach (var location in  t)
    {
        if (!(location is ResourceLocationMap)) continue;
        ResourceLocationMap locationMap = location as ResourceLocationMap;
        locationMap.Locate(labelName, typeof(object), out var startLocationList);
        foreach (var info in locationMap.Locations)
        {
            if(info.Value.Count == 0) continue;
            string str = info.Value[0].PrimaryKey;
            bool isHas = false;
            foreach (var startLocation in startLocationList)
            {
                if(startLocation.PrimaryKey == str)
                {
                    isHas = true;
                    break;
                }
            }
            if (isHas) continue;
            string key = info.Key.ToString();
            if (int.TryParse(key, out var num))
            {
                continue;
            }
            if (!keys.Contains(key))
            {
                keys.Add(key);
            }
        }
    }
    /*foreach (var locator in t)
    {
        foreach (var key in locator.Keys)
        {
            int value = 0;
            string str = key.ToString();
            if (!int.TryParse(str, out value))
            {
                keys.Add(str);
            }
        }
    }*/
    return keys;
}
```

---
###Texture
Q：Sprite Packerのアトラスを使用しています。実行時にどうやってSpriteのあるアトラスのUV値を取得できますか？
>この方式でできます。
>
```ruby:
Sprites.DataUtility.GetOuterUV(activeSprite)
```

---
###Animation
Q：AnimatorControllerはUnityEditorの下に配置されていますが、すべての状態名を取得するにはどうすればよいですか？
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/bd3e0244-d662-22b0-7c73-cbe30d90d799.png)

>これを参照できます。
https://stackoverflow.com/questions/41709325/retrieve-all-animator-states-and-set-them-manually-in-code
さらに、Unity5.2以降のAnimatorControllerは常にEditor命名空間の下にあります。
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653855/df3f9971-2161-a1b8-6a38-cbd2635c5cb6.png)

---
###UGUI
Q：ある原因で、UGUIのMaskコンポーネントを逆コンパイルし、コードをコピーして、テストのために名前を変更しました。
しかし、コピーされたMaskは無効であることがわかりました。
オリジナルなMaskはコンポーネントのマテリアルを変更することでクリッピングを実現すると、それは自身とすべての子ノードのマテリアルを変更します。コピーされたMaskは、自分のマテリアルのみを変更し、子ノードにはまったく影響しません。
UnityはどのようにMaskをすべての子ノードマテリアルを影響させますか？

①
>Maskコンポーネントは、コンポーネントに通知し、カット情報を識別するクラスです。コンポーネントをオンにすると、子ノード内のすべてのTextとImage（これらのコンポーネントはMaskableGraphicから継承されます）にカット計算を開始するように通知し、 MaskableGraphicは、親ノードで最も近いものを見つけます。Maskコンポーネントはカット情報を取得するため、単にMaskをコピーするだけでは意味がありません。

②
>MaskableGraphicのコードによると、親ノードではなく、現在のノードのMaskコンポーネントのみが検出されます。 ソフトクリッピング用のAlphaMaskコンポーネントを作成しましたが、親ノードがMaskにぶら下がっている場合、このコンポーネントは異常であることがわかりました。 調査の結果、Maskが資料を置き換え、元の資料の情報を失ったことが判明しました。
>
次に、Maskの実現を参照してAlphaMaskを調整します。 プロジェクトには多くの動的ノードがあるため、主な目的は子ノードのマテリアルを置き換えることです。次に、各動的ノードに独自のコードをコールしてマテリアルを置き換える必要があります。
>
最後に、MaskabelGraphicは、GetComponentInParentを直接使用する代わりに、MaskUtilities.GetStencilDepthをコールすることにより、親ノードMaskの情報を取得することがわかりました。

---
UWA Technologyは、モバイル/VRなど様々なゲーム開発者向け、**パフォーマンス分析**と**最適化ソリューション**及び**コンサルティングサービス**を提供している会社でございます。

今なら、UWA GOTローカルツールが**15日間に無償試用**できます！！
よければ、ぜひ！

UWA公式サイト：https://jp.uwa4d.com
UWA GOT OnlineレポートDemo：https://jp.uwa4d.com/u/got/demo.html
UWA公式ブログ：https://blog.jp.uwa4d.com