LoginSignup
1

More than 5 years have passed since last update.

自作ObjectID OnGUI検索機能

Last updated at Posted at 2017-08-01

自作Objectsを検索する機能

目的

  • ゲーム内ステータスを持つオブジェクトを便利に管理するため

基本理念

  • ゲーム内カスタムデータを持つオブジェクトに一意性のIDを待たせる
  • GameObjectsManagerでそれらのオブジェクトを管理する
  • Debug OnGUIでHelperを作成

実装手順

  1. ObjectsBaseData.cs作成
 public class ObjectBaseData : MonoBehaviour
{
   public long _id;
   public OBJ_TYPE _type = OBJ_TYPE.type1;
}

2.作成したものを、検索対象となるオブジェクトにつける

public class ObjectClass : ObjectBaseData
{
}

3.GameObjectsManagerを作成

//linq追加
using System.Linq;
public enum OBJ_TYPE
{
 type1,
 type2,
}
public class GameObjectsManager : MonoBehaviour
{
  private static GameObjectsManager _instance = null;//シングルトンにしようか。
  private static long _indx = 0;
  private static Dictionary<long , ObjectBaseData> _objDic = new ...
  void SetInstance(GameObjectsManager mgr)
  {
   _instance = mgr;
  }
  void GameObjectsManager Get()
  {
   return _instance;
  }
  void Awake()
  {
    SetInstance(this);
    _objDic.Clear();//一応初期化しとく
  }
  public long RigisterObject(ObjectBaseData objData)
  {
    while(objDic.ContainsKey(_indx)
    {
     _indx++;
    }
    objDic.Add(indx,_objData);
    return _indx;
  }
  public ObjectBaseData GetObjectByID(long id)
  {
    //検索要素一個なので、Dictionaryのデフォルト機能の方が速い気がする。
    if(objDic.ContainsKey(id))
    {
       return objDic[id];
    }
    return null;
  }
 //////////////////////////////////////////////
 //もちろん、enumでObjectTypeを追加したりは自由です。例えば、Linqを使って
 public List<ObjectBaseData> GetObjectByType(OBJ_TYPE t)
 {
   return objList.Where(v => v.value._type == t).Select(r => r.value).ToList();
 }
}

完成したら、Scene上のSystemManagerレベルオブジェクトに追加する。
4. ObjectClassを修正する

 void Awake()
 {
   _id = GameObjectsManager.Get(). RigisterObject(this);
 }

を追加する。
5. OnGUIを書こう!

  //using省略
  public class DebugSearch : EditorWindow
  {
    [MenuItem("Debug/DebugSearch", true)]
    static bool CheckWnd(){return true;}
    [MenuItem("Debug/DebugSearch")]
    static void OpenObjectsSearcher()
    {EditorWindow.GetWindow< DebugSearch >("DebugSearch");}

    List<ObjectBaseData> objList = new ...
    Vector2 scrPos = Vector2.Zero;
    public OBJ_TYPE op;
    public long id;

    void OnGUI()
    {
      GUILayout.BeginVertical("box");
      {
       GUILayout.BeginHorizontal();
       {
           op = (ObjectType)EditorGUILayout.EnumPopup("Select by Type:", op);
           if (GUILayout.Button("Search!", GUILayout.Width(50)))
           {
                    SearchByType();
           }
        }   
       GUILayout.EndHorizontal();   
       GUILayout.BeginHorizontal();
       {
         GUILayout.Label("Search by ID:");
         id = int.Parse(EditorGUILayout.TextArea(id.ToString(),GUILayout.Width(50.0f)));
         if (GUILayout.Button("Search!", GUILayout.Width(50)))// && isSearchFinished)
         {
           SearchById();
         }
       }
       GUILayout.EndHorizontal();
      UpdateList();
      }
      GUILayout.EndVertical();
    }
    void SearchByType()
    {
        objList.Clear();
        objList = GameObjectsManager.Get(). GetObjectByType(op);
    }
    void SearchById()
    {
        objList.Clear();
        var obj = GameObjectsManager.GetInstance(). GetObjectByID(id);
        if (obj != null)
        {
            objList.Add(obj);
        }
    }
    void UpdateShow()//Listの更新
    {
        if (objList == null || objList.Count <= 0) { return; }
        scrollPosition = GUILayout.BeginScrollView(scrollPosition);
        foreach (var obj in objList)
        {
            GUILayout.BeginHorizontal();
            {
                if (obj == null) continue;
                GUILayout.Label(obj._id.ToString(), GUILayout.Width(40.0f));
                EditorGUILayout.ObjectField(obj, typeof(ObjectBaseData), true);
            }
            GUILayout.EndHorizontal();
        }
        GUILayout.EndScrollView();
    }
  }

もちろん、この部分はエラーがなければ、上のMenu欄にDebugが出るので、ほっとけば大丈夫。

補足

  • _objDic にはもちろん、該当オブジェクトが消された場合の対応が必要である。例えば、UnRigisterを実装し、Ojbectが破棄されるときに実行する。
  • managerの書き方は人それぞれ、普通はシングルトンの親クラスで書くが、ここでは割愛する。
  • ここで記載しているソースは、本人実装手順と一例を説明するために、大まかに書いたものである。そのため、そのまま使用すると、動作する保証は全くない。参考まで・

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