Используйте класс как переменную - PullRequest
0 голосов
/ 23 сентября 2019

поэтому у меня есть класс InstalledObjects, и все объекты, такие как стены, двери и т. Д., Будут наследоваться от этого.Теперь я хотел бы создать экземпляр GameObject в методе и попросить в методе установить InstalledObject, который может быть Стеной или Дверью, поскольку они оба наследуются от InstalledObject.

Моя проблема в том, что я могу сохранитьв переменной скрипт.

Во-первых, этот метод называется

public void CreateBasicWall()
{
     buildHandler.installedObject = new Wall();
}

, который хранится здесь:

public InstalledObject installedObject;

И, наконец, вызывается здесь

BuildTile(t, buildModeTile);

И делает это:

void Build(Tile tile, InstalledObject installedObject)
{
    if(installedObject == null)
    {
        Debug.LogError("No se va a construir nada");
        return;
    }
    GameObject go = new GameObject();
    go.AddComponent<installedObject>();

}

Игнорировать плитку.Он не позволит мне добавить установленный объект, так как это переменная, а не тип.

Я помню, что класс Wall наследует от InstalledObject, и я хотел бы иметь его как var, чтобы я мог повторно использовать код, но любой другойРешение приветствуется.

Ответы [ 2 ]

3 голосов
/ 23 сентября 2019

Как уже говорилось, использование динамических переменных для универсального метода (AddComponent<T>) невозможно напрямую, только возможно с использованием отражение , но я бы не рекомендовал его, особенно есливы новичок в c #.


Предполагая, что InstalledObject имеет тип MonoBehaviour, поскольку вы пытаетесь использовать его для AddComponent, ваш код в любом случае неверен!

Нельзя использовать new Wall() для класса типа MonoBehaviour .. его можно создать только с помощью AddComponent<ClassName>() или, альтернативно, перегрузку, принимающую тип AddComponent(typeof(ClassName))

Так что вместо этого вы можете не хранить «экземпляр» (как сказано, вы не можете использовать new в любом случае), вы можете хранить только соответствующий тип

public Type typeToInstall;

, а затемпередайте его как

public void CreateBasicWall()
{
     buildHandler.typeToInstall = typeof(Wall);
}

void Build(Tile tile, Type typeToInstall)
{
    if(typeToInstall == null)
    {
        Debug.LogError("No se va a construir nada");
        return;
    }

    GameObject go = new GameObject().AddComponent(typeToInstall);

    // or even a bit shorter
    //new GameObject("New GameObject", typeToInstall);
}

Вы также можете сделать этот метод универсальным сам по себе и ограничение передало тип в Component (родительский класс всего, что выможно прикрепить к GameObject) просто чтобы быть уверенным.Передача в любом другом типе уже вызовет ошибку компилятора.Тогда вы также можете использовать AddComponent<T> снова

void Build<T>(Tile tile, T typeToInstall) where T : Component // or maybe even InstalledObject ;)
{
    if(typeToInstall == null)
    {
        Debug.LogError("No se va a construir nada");
        return;
    }

    new GameObject().AddComponent<T>();

    // or still use
    //new GameObject("New GameObject", typeof(T));
}
0 голосов
/ 23 сентября 2019

Есть несколько способов сделать это, однако если вы хотите сохранить свою текущую архитектуру, вам нужны виртуальные или абстрактные функции.

Каждый класс знает свой собственный тип, однако функции, которые вы вызываете, зависят от него.тип переменной, содержащей класс, если это не абстрактная или виртуальная функция.

Я бы предложил прочитать this .

Вот один из способов сделать это:

void Build(Tile tile, InstalledObject installedObject)
{
    Assert.IsNotNull(installedObject,
        "No se va a construir nada");

    GameObject go = new GameObject();
    installedObject.AddSelfToGameObject(go);
}

и в вашем Build.cs

public abstract class Build
{
    [...]
    public abstract void AddSelfToGameObject(GameObject go);
}

public class Building:Build
{
    [...]
    public override void AddSelfToGameObject(GameObject go)
    {
        go.AddComponent<BuildingScript>();
    }
}

abstract в классе Build необходимо только в том случае, если вы никогда не создаете только класс Build, толькодетский класс Build.Вы можете удалить abstract в классе и заменить его в функции на virtual.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...