Jump to content

Как реализовать в инспекторе компонента динамическую подстановку значений параметра


photo

Recommended Posts

Posted

Здравствуйте! 
Решаю в ПО след. задачу. Имеется на сцене огромное количество 3D-объектов. При нажатии на каждый из них, я должен получать нужную информацию об объекте. Для этих целей я вешаю на каждый объект класс-компонент, который содержит 2 поля - TagName и TagGroupName, значения которых задаются в виде enum из отдельного файла:

public enum TagGroupName
{
    Null,
    group1,
    group2,
    group3,
}

public enum TagName
{
    Null,
    Name1,
    Name2,
    Name3,
}

Каждый TagName принадлежит к своему TagGroupName, т.е. набор TagName относится к своему TagGroupName. Я пытаюсь сделать так, чтобы при выборе TagGroupName у меня в инспекторе компонента менялся набор TagName. Я изучил один из демо-примеров ComponentParameters.cs в котором приводятся всевозможные варианты форм задания параметров у компонента для отображения в инспекторе. Увидел, что имеется такое:

// you can use ParameterSwitch attribute to set the int variable as the index of one of the items
[ParameterSwitch(Items = "switch_item_0,switch_item_1,switch_item_2")]
public int switchVariable = 1;

Т.е. если я буду подставлять в Items строку с набором своих TagName, то смогу осуществить задуманное. 

Для этого я сделал вспомогательный класс:

using System;
using System.Collections.Generic;
using System.Linq;

// Класс для хранения соответствия между группами и тегами
public static class TagMapping
{
    private static Dictionary<TagGroupName, List<TagName>> _groupToTagsMap;
    
    static TagMapping()
    {
        InitializeMapping();
    }
    
    // Метод инициализации словаря _groupToTagsMap данными о соответствии TagGroupName и TagName
    private static void InitializeMapping()
    {
        _groupToTagsMap = new Dictionary<TagGroupName, List<TagName>>();
        
        _groupToTagsMap[TagGroupName.group1] = new List<TagName>
        {
            TagName.name1,
        };
		
		_groupToTagsMap[TagGroupName.group2] = new List<TagName>
        {
            TagName.name2,
        };
		
		_groupToTagsMap[TagGroupName.group3] = new List<TagName>
        {
            TagName.name3,
        };
        
        
    }
    
    // Возвращает список тегов для указанной группы.
    public static List<TagName> GetTagsForGroup(TagGroupName group)
    {
        if (_groupToTagsMap.TryGetValue(group, out var tags))
            return tags;
        return new List<TagName>();
    }
    
    // Возвращает строку тегов через запятую для указанной группы.
    public static string GetTagsStringForGroup(TagGroupName group)
    {
        var tags = GetTagsForGroup(group);
        if (tags.Count == 0)
            return string.Empty;

        return string.Join(",", tags.Select(t => t.ToString()));
    }
}

Далее в своем классе-компоненте пытаюсь его использовать:

using System;
using System.Collections;
using System.Collections.Generic;
using Unigine;

[Component(PropertyGuid = "8bb23df56618b6d01ed71bef3cd3988286a37df9")]
public class MarkerParameter : Component
{

    public TagGroupName objectGroup = TagGroupName.Null;
    
	[ParameterSwitch(ItemsFunc = nameof(GetTagNamesForSelectedGroup))]
    public TagName objectTag = TagName.Null;
    
    private string GetTagNamesForSelectedGroup()
    {
        if (objectGroup == TagGroupName.Null)
            return string.Empty;
            
        return TagMapping.GetTagsStringForGroup(objectGroup);
    }
}

Вот здесь далее я застрял... здесь видимо нужна дальше связка c AppEditorLogic.cs, возможно мой TagMapping вообще сделать наследуемым от EditorLogic...Может есть пример, который я не увидел или обсуждали на форуме (поиск не дал результатов)

×
×
  • Create New...