我创建了多个小脚本来遵循Unity中的模块化模式。但是,此脚本可能需要其他脚本的信息。我这样做是为了可以将脚本作为其他对象的组件重用。是否正在创建将这些脚本归类为不良做法或违反SRP的“主”脚本?有没有更好的方法可以解决这个问题?可能有活动吗?
比方说我有一个敌人,当那个敌人死亡时,它将掉落一些战利品并提供一些经验。我为体验,战利品,死亡和健康创建了一个脚本。每个将具有几个功能。我创建了一个名为EnemyHandler的“主”脚本,该脚本决定何时启动每个脚本。每当敌人受到伤害时,就会从运行状况事件中激活该方法,并且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);
}
}
答案 0 :(得分:0)
SRP(单一责任原则)规定,班级应自行管理。就您的代码而言,您的类是进行自我管理。当敌人死亡时,它会产生影响:烟雾,动画,战利品掉落,经验等等。这样,处理...这些效果的类就会传递到您的敌人类中,并且当敌人死亡时,它会说:“哦,现在死了,嘿,死后的东西,做您的事。”
如果这违反了SRP,则任何类都无法调用任何其他类上的方法。敌人的责任是生成战利品。它不知道它的种类,发生的方式或其他任何细节,只是知道它有一个战利品,而死后其责任是打电话给loot.spawn()
。
答案 1 :(得分:0)
它被称为神物
https://en.wikipedia.org/wiki/God_object
我建议不要执行此操作,因为该对象了解太多,而我建议使用依赖注入(DI)
(此外,如果将God Object用作Singleton,您将在应用程序中到处都有它,假设您要重命名它,而没有IDE帮助,则必须转到每个文件并执行该操作,凝聚力高)
https://www.codementor.io/mrfojo/c-with-dependency-injection-k2qfxbb8q