Страница 1 из 1

Использование словаря делегатов

СообщениеДобавлено: 11 май 2019, 12:38
Woland
Всем привет!

В игре в определенный момент я создаю NPC, в зависимости от его типа (строка) я добавляю на него компоненты. Сначала я не парился и сделал так:
Синтаксис:
Используется csharp
if (type == "map")
        {
            this.gameObject.AddComponent<NPCMap>();
        }
        if (type == "toFight")
        {
            this.gameObject.AddComponent<NPCToFightScene>();
        }
        if (type == "oldFights")
        {
            this.gameObject.AddComponent<NPCToOldFights>();
        }



Потом мне это надоело, решил использовать словарь делегатов

Синтаксис:
Используется csharp
_addComponents =new Dictionary<string, AddComponentsDelegate>
        {
            { "map", this.AddMapComponent },
            { "toFight", this.AddToFightComponent },
            { "oldFights", this.AddOldFightsComponent },
        };
       
.......

       _addComponents[type]();
 


Все работает прекрасно. но в какой-то момент получилась ситуация, что для одного типа НПЦ мне надо добавлять 2 компонента

Синтаксис:
Используется csharp
 _addComponents = new Dictionary<string, AddComponentsDelegate>
        {
            { "map", this.AddMapComponent },
            { "toFight", this.AddToFightComponent },
            { "oldFights", this.AddOldFightsComponent },
            { "dialog", this.AddMoveToMainCharacterComponent },
            { "dialog", this.AddTalkToMainCharacterComponent },
        };


Так не работает, естественно, ключевое значение "dialog" повторяется. Можно методы AddMoveToMainCharacterComponent и AddTalkToMainCharacterComponent вызывать из другого метода, например, AddDialogComponents, но тогда теряется вся гибкость.

Как лучше это реализовать? Спасибо!

Re: Использование словаря делегатов

СообщениеДобавлено: 11 май 2019, 13:18
1max1
А если флагами добавлять?
Синтаксис:
Используется csharp
using UnityEngine;
using System;

[Flags]
enum Type
{
    Map       = 1,
    ToFight   = 2,
    OldFights = 4,
    Dialog    = 8
}

class Map       : MonoBehaviour { }
class ToFight   : MonoBehaviour { }
class OldFights : MonoBehaviour { }
class Dialog    : MonoBehaviour { }

class Test : MonoBehaviour
{
    void AddComponentForNPC(GameObject npc, Type type)
    {
        if (type.HasFlag(Type.Map))
            npc.AddComponent<Map>();

        if (type.HasFlag(Type.ToFight))
            npc.AddComponent<ToFight>();

        if (type.HasFlag(Type.OldFights))
            npc.AddComponent<OldFights>();

        if (type.HasFlag(Type.Dialog))
            npc.AddComponent<Dialog>();
    }

    void Start()
    {
        // Будут добавлены два компонента
        AddComponentForNPC(new GameObject(), Type.Dialog | Type.Map);
    }
}

Re: Использование словаря делегатов

СообщениеДобавлено: 11 май 2019, 13:53
Woland
Хз, по сути тут так же получается много if else. Я как раз ищу сейчас решение без if, поэтому и стал копать в сторону делегатов.

Re: Использование словаря делегатов

СообщениеДобавлено: 11 май 2019, 14:07
1max1
Что в этом плохого? У тебя же там их не пару сотен будет. Нет, ну можно и без if обойтись, только надо напрямую задавать имена компонентов:
Синтаксис:
Используется csharp
using UnityEngine;
using System;

class Map       : MonoBehaviour { }
class ToFight   : MonoBehaviour { }
class OldFights : MonoBehaviour { }
class Dialog    : MonoBehaviour { }

class Test : MonoBehaviour
{
    void AddComponentForNPC(GameObject npc, params Type[] types)
    {
        foreach (var type in types)
            npc.AddComponent(type);
    }

    void Start()
    {
        AddComponentForNPC(new GameObject(), typeof(Map), typeof(ToFight));
    }
}

Re: Использование словаря делегатов

СообщениеДобавлено: 11 май 2019, 14:08
AngryCat
Woland писал(а):Хз, по сути тут так же получается много if else. Я как раз ищу сейчас решение без if, поэтому и стал копать в сторону делегатов.

что тебе if сделали?

Re: Использование словаря делегатов

СообщениеДобавлено: 12 май 2019, 15:29
Woland
Да можно и с if все сделать) Я расцениваю это, как самообучение, узнаю для себя новые способы, кроме как все на ифах писать

Re: Использование словаря делегатов

СообщениеДобавлено: 12 май 2019, 18:29
AngryCat
Woland писал(а):Да можно и с if все сделать) Я расцениваю это, как самообучение, узнаю для себя новые способы, кроме как все на ифах писать
Раз для опыта, то можешь еще рефлексию копнуть, но много и часто я бы не рекомендовал ее использовать т.к она медленнее

Re: Использование словаря делегатов

СообщениеДобавлено: 12 май 2019, 18:57
~AvA~
Ну, если нужно добавлять по одному компоненту, то можно было бы такое провернуть:
Назвать компоненты типами, которые будут анализироваться.. ну там map и соответствующий тип NPCmap.

Тогда можно было бы совсем без ифов: gameObject.AddComponent("NPC" + type);
Правда метод добавления компонента по строке - депрекейтнули (

Re: Использование словаря делегатов

СообщениеДобавлено: 12 май 2019, 19:00
~AvA~
1max1 писал(а):Что в этом плохого? У тебя же там их не пару сотен будет. Нет, ну можно и без if обойтись, только надо напрямую задавать имена компонентов:
Синтаксис:
Используется csharp
using UnityEngine;
using System;

class Map       : MonoBehaviour { }
class ToFight   : MonoBehaviour { }
class OldFights : MonoBehaviour { }
class Dialog    : MonoBehaviour { }

class Test : MonoBehaviour
{
    void AddComponentForNPC(GameObject npc, params Type[] types)
    {
        foreach (var type in types)
            npc.AddComponent(type);
    }

    void Start()
    {
        AddComponentForNPC(new GameObject(), typeof(Map), typeof(ToFight));
    }
}

Такой вариант пишется проще, так как при создании GameObject можно сразу указать компоненты, чтобы добавились
Синтаксис:
Используется csharp
void Start()
    {
       var go = new GameObject("NPC", typeof(Map), typeof(ToFight));
    }
 

Но автору нужно добавлять компоненты к уже существующему объекту.. кажется)