Как я могу использовать объекты сценариев для определения атрибутов вида животных, которые затем будут приняты другим классом монобихи-поведения? - PullRequest
0 голосов
/ 28 марта 2020

Я строю игру, в которой есть много разных видов животных и множество популяций разных видов. В этой упрощенной версии каждый вид определяется только его доминированием, размером и набором потребностей. Моя цель - уметь легко создавать новые виды с помощью инспектора Unity, и я делал это с помощью объектов сценариев:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Species : ScriptableObject
{
    [SerializeField] private List<Need> needs = default;
    [Range(0.0f, 10.0f)]
    [SerializeField] private float dominance = default;
    [Range(0.0f, 10.0f)]
    [SerializeField] private float size = default;
    // ... etc

    public float Dominance => dominance;
    public float Size => size;

    public float GetNeedSeverity(NeedType needType)
    {
        foreach (Need need in needs)
        {
            if (need.Type == needType)
            {
                return need.Severity;
            }
        }
        throw new System.ArgumentException($"Species does not have need {needType}");
    }
}

Это позволяет мне использовать инспектор для простого проектирования новых виды до времени выполнения. Тем не менее, должны быть «экземпляры» этого вида во время выполнения, которые являются популяциями. Чтобы сделать это, я создал класс популяции, в котором хранится ссылка на его вид:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Population : MonoBehaviour
{
    private Species species = default;

    public float Dominance => species.Dominance;
    public float Size => species.Size;
}

Способ, которым она реализована сейчас, состоит в том, что вместо того, чтобы класс популяции имел идентичные поля для вида и просто копировал все По данным из класса видов, класс популяции просто ссылается на класс видов и вместо этого извлекает из него информацию.

Является ли это правильным подходом?

Кажется, у обоих подходов есть проблемы. Если я скопирую все данные из класса видов в каждый класс популяции, во время выполнения будет много дублирующих данных и много, казалось бы, дублированного кода. Однако, когда я просто ссылаюсь на класс видов из класса популяции, а не копирую его данные, тогда мне также приходится выполнять множество функций в классе популяции, чтобы получить конкретные данные из класса видов. Кроме того, есть список потребностей, которые есть у каждого вида, и если какой-то другой класс должен собрать данные о конкретной потребности населения в c, функция будет неприятной. Ни один из подходов не кажется очень чистым.

Класс потребности:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum NeedType { Grass, Water, Pinecone } // and many more

public class Need : ScriptableObject
{
    [SerializeField] private NeedType type = default;
    [SerializeField] private float severity = default;

    public NeedType Type => type;
    public float Severity => severity;
    // ... etc
}

Один из этих способов лучше? Или есть лучший способ настроить классы?

Спасибо за любую помощь!

...