如何在场景中实现“杀死”事件的意识
我一直在使用C#与Unity进行RPG游戏,并且在执行任务系统时,特别是杀死一定数量的敌人时,我发现在场景中有3个敌人,并成为任务的目标:杀死3个敌人。如果我在激活任务之前杀死他们,并且后来激活任务不会给我奖励(在这种情况下是经验)。我怎么能告诉敌人,如果任务发现我已经杀死了必要的敌人以获得任务,同样给我奖励呢?如何在场景中实现“杀死”事件的意识
这里两个需要的脚本,我认为:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class QuestObject : MonoBehaviour {
public int questNumber;
public QuestManager qManager;
public string startText;
public string endText;
public bool isItemQuest;
public string targetItem;
public bool isEnemyQuest;
public string targetEnemy;
public int enemiesToKill;
private int enemyKillCount;
private PlayerStats playerStats;
public int EXPToGive;
void Start() {
playerStats = FindObjectOfType <PlayerStats>();
}
void Update() {
if (isItemQuest) {
if (qManager.itemCollected == targetItem) {
qManager.itemCollected = null;
EndQuest();
}
}
if (isEnemyQuest) {
if (qManager.enemyKilled == targetEnemy) {
qManager.enemyKilled = null;
enemyKillCount++;
}
if (enemyKillCount >= enemiesToKill) {
EndQuest();
}
}
}
public void StartQuest(){
qManager.ShowQuestText (startText);
}
public void EndQuest(){
qManager.ShowQuestText (endText);
playerStats.AddEXP (EXPToGive);
qManager.questCompleted [questNumber] = true;
gameObject.SetActive (false);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyHealth : MonoBehaviour {
public int startingHealth;
public int currentHealth;
public GameObject damageBurst;
private PlayerStats playerStats;
public int EXPToGive;
public string enemyQuestName;
private QuestManager qManager;
void Start()
{
// Setting up the references.
//anim = GetComponent <Animator>();
//enemyAudio = GetComponent <AudioSource>();
//enemyMovement = GetComponent <EnemyMovement>();
//enemyAttacking = GetComponentInChildren <EnemyAttack>();
// Set the initial health of the player.
currentHealth = startingHealth;
playerStats = FindObjectOfType <PlayerStats>();
qManager = FindObjectOfType <QuestManager>();
}
void Update()
{
if (currentHealth <= 0) {
qManager.enemyKilled = enemyQuestName;
Destroy (gameObject);
playerStats.AddEXP (EXPToGive);
}
}
public void TakeDamage (int amountDamage)
{
// Reduce the current health by the damage amount.
currentHealth -= amountDamage;
Instantiate (damageBurst, transform.position, transform.rotation);
}
public void SetMaxHelth() {
currentHealth = startingHealth;
}
}
一个阿布罗奇是创建某种类型的“WorldManager”,其对每一个已被杀害敌人的。当开始一个任务时,这个任务可以检查WorldManagers的杀戮数量并将其添加到自己的数量中。
public void StartQuest(){
qManager.ShowQuestText (startText);
this.enemyKillCount += worldManager.GetKillCount();
}
在你的敌人职业中,你必须为你的worldManager添加杀戮。
void Update()
{
if (currentHealth <= 0) {
qManager.enemyKilled = enemyQuestName;
this.worldManager.AddKill(this)
Destroy (gameObject);
playerStats.AddEXP (EXPToGive);
}
}
备选:
让您QManager知道每一个场景杀死。 您可以通过多种方式实现此目的。 其中之一是传递你的EnemyObject作为你的Qmanager的参考,并且与上面提供的“WorldManager”一样,或者当敌人被杀时使用消息传递并触发一条消息来瞄准QManager。
备选方案2: 当敌人被杀死并在QManager/WorldManager上订阅时投掷一个事件。这样你就可以在每场比赛中重复使用你的敌人。从我的角度来看,静态依赖是邪恶的,但是互联网上有许多讨论和SO以及无处不在。
你可以采取几种方法。最直接的是使用静态。
静态的目的是为变量/方法属于类而不是类的实例。
就你而言,你希望每个敌人都有自己的健康,这不能是静态的。 你想要统计场景中有多少实例。所以静态很好。
public class Enemy:MonoBehaviour
{
private static int enemyCount = 0;
public static int EnemyCount {get{ return enemyCount;} }
public event Action<int> RaiseEnemyDeath;
public static void ResetEnemyCount(){
enemyCount = 0;
}
private int health;
public void Damage(int damage)
{
CheckForDamage(); // here you check that damage is not neg or too big...
this.health -= damage;
if(this.health <= 0)
{
OnDeath();
}
}
void OnActivate()
{
enemyCount++;
this.health = 20;
}
void OnDeath()
{
enemyCount--;
RaiseEnemyDeath(enemyCount); // Should check for nullity...
}
}
这个很简单。第一部分全部是静态的,与班级相关。第二部分与实例相关。如果你使用一群敌人,然后多次重复使用同一个实例,当你让敌人在场景中存活时(它可能已经在那里停留一段时间),就会调用OnActivate方法。然后当健康状况下降时,杀死敌人(那里没有所有必要的行动......)并触发事件。
使用公共静态属性,您可以知道GameManager的敌人数量是多少(敌人不应该影响游戏玩法,只会照顾敌人)。
public class GameManager:MonoBehaviour
{
void Start()
{
Enemy.RaiseEnemyDeath += Enemy_RaiseEnemyDeath;
}
void Enemy_RaiseEnemyDeath(int count)
{
if(count < 0){ // End of level }
// You can also access enemyCount
int count = Enemy.EnemyCount;
}
}
好点利用这个原理的是,敌人没有关于游戏管理的线索,可以在另一场比赛没有任何修改被重用。 GameManager是一个更高层次的实体并且知道它。
我喜欢使用事件的方式,但如果你不使用静态的话,我更喜欢那个解决方案。但有一个好的解决方案。 –
这里的静态实际上是合适的。敌人的数量与敌人级有关。你也可以通过一些更高层次的经理来实现。当您认为即使没有Enemy实例时仍然需要静态,您仍然可以检查EnemyCount的值。如果静态在这里是无效的,那么在一般编程中根本就没有理由。 – Everts
好的谢谢,但我不明白AddKill(this)在哪里发送这些信息,我在哪里添加AddKill。和GetKillCount()?而且我不知道如何去做敌人台你能帮我吗?我有两个分离类型的敌人哥布林和史莱姆。 – adrinator8