1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

UnityのAssetを名前で取得したかった件

Last updated at Posted at 2019-09-22

またアタッチが外れた:rage::rage::rage:

PlayOnMacで昔のRailloadTycoon2をやってるとしばしばPCごと落ちます。
それはまぁ良いです。
さっきは、一緒に立ち上げてたUnityも道連れにして落ちちゃいました。
その影響かアタッチが綺麗さっぱり外れてキレ散らかしそうになりました。
いくら気をつけてても、やっぱりアタッチが外れることがあります。人間だもの。

何が問題か

例えば、SpriteやPrefabをたくさん作ったら
ss.png
こんな感じでListでアタッチしていくことがあると思いますが、これをやめたい。
どれを引っ張りだすのかindexで指定するのも治安が良くない気がします。

この辺のアタッチをどうにかすればQoLが上がる気がします。

書いた

AutoAssetLoader.cs
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;



# if UNITY_EDITOR

using UnityEditor;

public class AutoAssetLoader<T> where T : UnityEngine.Object
{
    private readonly Dictionary<string, T> _assets = new Dictionary<string, T>();

    private string GetFilter()
    {
        if (typeof(T) == typeof(GameObject)) return "t:Prefab t:GameObject";
        else if (typeof(T) == typeof(Sprite)) return "t:Sprite";
        throw new Exception("とりあえずprefabとspriteのみ対応");
    }
    
    public AutoAssetLoader(string dir)
    {
        var assetPaths = AssetDatabase
            .FindAssets(GetFilter(), new string[] { "Assets/Editor/" + dir } )
            .Select(AssetDatabase.GUIDToAssetPath);

        foreach (var path in assetPaths)
        {
            var asset = AssetDatabase.LoadAssetAtPath<T>(path);
            _assets.Add(asset.name, asset);
        }
    }


    public T Get(string name)
    {
        var f = _assets.TryGetValue(name, out var o);
        return f ? o : null;
    }

    public IEnumerable<string> Names() => _assets.Keys;
}

# else

public class AutoAssetLoader<T> where T : UnityEngine.Object
{
    private readonly AssetBundle _assetBundle;
    private readonly Dictionary<string, T> _assets = new Dictionary<string, T>();

    public AutoAssetLoader(string path)
    {
        _assetBundle = AssetBundle.LoadFromFile("AssetBundleData/" + path);

    }


    public T Get(string name)
    {
        var f = _assets.TryGetValue(name, out var asset);
        if (f) return asset;
        asset = _assetBundle.LoadAsset<T>(name);
        _assets.Add(name, asset);
        return asset;
    }

    public IEnumerable<string> Names() => _assetBundle.GetAllAssetNames().Select(str=>
        {
            var from = str.LastIndexOf("/", StringComparison.Ordinal) + "/".Length;
            var to = str.LastIndexOf(".", StringComparison.Ordinal);
            var len = to < from ? (str.Length - from) : (to - from);
            return str.Substring(from, len);
        });
}


# endif

ディレクトリ内のprefabやらspriteやらを全て読み込みます。
AssetDatabaseはUnityEditor名前空間内、つまりビルド時は使えないので、
プリプロセッサディレクティブで切り替えます。

開発時はEditorフォルダ内にPrefabやSpriteを置きます。
リリース時はちゃんとAssetBundleを作って
ルートディレクトリ直下のAssetBundleData内に置きます。

UnityProject/
├ Assets/
│└ Editor/
│ ├ Prefabs/
│ └ Sprites/
└ AssetBundleData/

使い方

usage.cs
        AutoAssetLoader<GameObject> prefabs = new AutoAssetLoader<GameObject>("Prefabs");
        foreach (var name in prefabs.Names())
        {
            Instantiate(prefabs.Get(name));
        }
        
        
        AutoAssetLoader<Sprite> sprites = new AutoAssetLoader<Sprite>("Sprites");
        image.sprite = sprites.Get("Cat");

追記

2019/9/22
AssetDatabaseがビルド時に使えないのに気づいて、AssetBundleと切り替えるようにしました。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?