Я создал несколько небольших скриптов, чтобы следовать модульному шаблону в Unity.Однако для этих сценариев может потребоваться информация из других сценариев.Я делаю это, чтобы я мог повторно использовать сценарии в качестве компонентов для других объектов.Создание «основного» сценария, объединяющего эти сценарии, является плохой практикой или нарушением SRP?Есть ли лучший способ приблизиться к этому, что я должен рассмотреть?Может быть, события?
Допустим, у меня есть враг, и когда этот враг умирает, он бросает добычу и дает некоторый опыт.Я создал скрипт для опыта, добычи, смерти и здоровья.Каждый будет выполнять несколько функций.Я создал «главный» скрипт, который называется EnemyHandler, и этот скрипт решает, когда запускать каждый скрипт.Методы активируются из события Health, когда враг получает повреждения, и EnemyHandler является подписчиком этого события.
Другим вариантом было использование события OnHealthChanged и дополнительного события OnDeath и запуск каждого сценария, но я чувствую, что это сделает их более зависимыми.
Это мой код (каждый класс отличаетсясценарий)
class AnimalHandler : MonoBehaviour
{
private IHealth ihealth;
[SerializeField]
private ObjectDeath objectDeath;
[SerializeField]
private SmokeEffect smokeEffect;
[SerializeField]
private LootSpawner lootSpawner;
[SerializeField]
private ExperienceAdder experienceAdder;
[SerializeField]
private animalRange animalRangeScript;
void Start()
{
ihealth = gameObject.GetComponent<IHealth>();
ihealth.OnHealthChanged += WhenAnimalDies;
}
private void OnDisable()
{
ihealth.OnHealthChanged -= WhenAnimalDies;
}
public void WhenAnimalDies(float healthPercentage)
{
if (healthPercentage <= 0f)
{
objectDeath.Dead();
smokeEffect.ProduceSmoke();
lootSpawner.SpawnLoot();
experienceAdder.AddExperience();
}
}
}
class SmokeEffect : MonoBehaviour
{
[SerializeField]
private GameObject smoke;
public void ProduceSmoke()
{
Instantiate(smoke, transform.position, transform.rotation);
}
}
class LootSpawner : MonoBehaviour
{
//Lootbag when the animal dies
[SerializeField]
private GameObject lootbag;
public void SpawnLoot()
{
lootbag.gameObject.SetActive(true);
lootbag.transform.position = transform.position;
}
}
class Health : MonoBehaviour, IHealth
{
[SerializeField]
private int maxHealth;
private int currentHealth;
public int CurrentHealth{..}
public float CurrentHealthPercentage
{
get { return (float)CurrentHealth / (float)maxHealth; }
}
public event Action<float> OnHealthChanged = delegate { };
void Start()
{
CurrentHealth = maxHealth;
}
public void ChangeHealth(int healthChange)
{
if (CurrentHealth <= 0)
return;
CurrentHealth += healthChange; //Damage is a negative number
OnHealthChanged(CurrentHealthPercentage);
}
}