C# 实例化的敌人对其身后的每一个敌人输出双倍伤害
所以我在做一个FPS生存游戏。我制作了一个GameManager脚本,用于处理游戏中的敌人繁殖部分。我的敌人攻击脚本处理敌人的攻击。问题是,当第一个敌人产卵时,我只受到1点伤害(如攻击伤害中所述),但当第二个敌人产卵时,即使我只进入1个敌人的攻击范围,我也会受到2点伤害(攻击伤害*2)。 以下是我所有的敌人脚本: EnemyAttack.cs: 和PlayerHealth.cs:C# 实例化的敌人对其身后的每一个敌人输出双倍伤害,c#,unity3d,artificial-intelligence,unityscript,C#,Unity3d,Artificial Intelligence,Unityscript,所以我在做一个FPS生存游戏。我制作了一个GameManager脚本,用于处理游戏中的敌人繁殖部分。我的敌人攻击脚本处理敌人的攻击。问题是,当第一个敌人产卵时,我只受到1点伤害(如攻击伤害中所述),但当第二个敌人产卵时,即使我只进入1个敌人的攻击范围,我也会受到2点伤害(攻击伤害*2)。 以下是我所有的敌人脚本: EnemyAttack.cs: 和PlayerHealth.cs: 使用UnityEngine; 使用UnityEngine.UI; 使用系统集合; 公共级玩家健康:单一行为{ 公共转
使用UnityEngine;
使用UnityEngine.UI;
使用系统集合;
公共级玩家健康:单一行为{
公共转换播放器;
公共静态浮动健康=100;
公共静态浮点maxHealth=100;
//用于初始化
无效开始(){
GameObject.FindGameObjectWithTag(“HealthPoints”).GetComponent().text=“HEALTH:”+HEALTH;
}
//每帧调用一次更新
无效更新(){
如果(健康您的脚本有一些问题
我认为你不明白什么是静态变量
静态变量在类的所有实例中共享它的值
不应该是静态的
PlayerMovement.isEnemyAttacking
这也不应该是静态的
现在,只要有1个ennemy满足“攻击”条件,您就可以设置和读取单个静态变量,从而导致所有ennemy受到攻击。相反,您应该让变量属于每个ennemy实例,而不是使变量处于静态状态
基本上,你只需要理解什么是静态变量。一旦你知道了,你就会明白为什么你的逻辑不起作用
编辑:解决方案
玩家健康脚本。将此脚本附加到场景中的玩家游戏对象
using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
public static float Health;
public static float maxHealth = 100;
private Text healthText;
void Start()
{
healthText = GameObject.FindGameObjectWithTag("HealthPoints").GetComponent<Text>();
//Make it full 100% health on start
Health = maxHealth;
RefreshHealthBar();
}
public void TakeDamage(float damage)
{
Health -= damage;
RefreshHealthBar();
if (Health <= 0)
Die();
}
public void Die()
{
Health = 0;
RefreshHealthBar();
//TODO: Your code
}
void RefreshHealthBar()
{
healthText.text = "HEALTH: " + Health;
}
}
使用UnityEngine;
使用UnityEngine.UI;
公共级玩家健康:单一行为
{
公共卫生;
公共静态浮点maxHealth=100;
私人文本;
void Start()
{
healthText=GameObject.FindGameObjectWithTag(“HealthPoints”).GetComponent();
//开始时使其完全100%健康
健康=最大健康;
RefreshHealthBar();
}
公共财产损失(浮动损失)
{
健康-=损害;
RefreshHealthBar();
如果(健康您的脚本有一些问题
我认为你不明白什么是静态变量
静态变量在类的所有实例中共享它的值
不应该是静态的
PlayerMovement.isEnemyAttacking
这也不应该是静态的
现在,只要有1个ennemy满足“攻击”条件,您就可以设置和读取单个静态变量,从而导致所有ennemy受到攻击。相反,您应该让变量属于每个ennemy实例,而不是使变量处于静态状态
基本上,你只需要理解什么是静态变量。一旦你知道了,你就会明白为什么你的逻辑不起作用
编辑:解决方案
玩家健康脚本。将此脚本附加到场景中的玩家游戏对象
using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
public static float Health;
public static float maxHealth = 100;
private Text healthText;
void Start()
{
healthText = GameObject.FindGameObjectWithTag("HealthPoints").GetComponent<Text>();
//Make it full 100% health on start
Health = maxHealth;
RefreshHealthBar();
}
public void TakeDamage(float damage)
{
Health -= damage;
RefreshHealthBar();
if (Health <= 0)
Die();
}
public void Die()
{
Health = 0;
RefreshHealthBar();
//TODO: Your code
}
void RefreshHealthBar()
{
healthText.text = "HEALTH: " + Health;
}
}
使用UnityEngine;
使用UnityEngine.UI;
公共级玩家健康:单一行为
{
公共卫生;
公共静态浮点maxHealth=100;
私人文本;
void Start()
{
healthText=GameObject.FindGameObjectWithTag(“HealthPoints”).GetComponent();
//开始时使其完全100%健康
健康=最大健康;
RefreshHealthBar();
}
公共财产损失(浮动损失)
{
健康-=损害;
RefreshHealthBar();
if(Health)我也发生了类似的情况,这是由于脚本错误地添加到另一个对象上造成的。您能否检查“EnemyAttack”脚本是否意外地附加到另一个对象上,如您的相机或其他东西?您在这里可能会更幸运()@我检查了DavidHague,只连接到我的MeleeEquare预制。我也发生了类似的事情,这是由于脚本错误地添加到另一个对象上造成的。你能检查一下“EnemyAttack”脚本是否意外连接到另一个对象上,比如你的相机或其他东西吗?你在这里可能会更幸运()@DavidHague我查过了,只附在我的MeleeEquator预制板上。谢谢你告诉我我搞砸了,但请原谅我现在问这个问题:我将公共静态bool inSight
更改为公共静态bool isenemytacking
和公共静态bool isenemytacking=false
更改为公共静态bool isenemytacking=false代码>现在我无法检查另一个脚本中的布尔值。例如,如果(EnemySight.inSight==true)
与isEnemyAttacking相同,我就无法再检查了。我得到一个错误Assets/\u Scripts/EnemyAttack.cs(24,35):错误CS0120:访问非静态成员'PlayerMovement.IsenemyTacking'需要对象引用,因为您需要对ennemy的此特定实例进行引用。我会将此添加到示例中。@JoRouss您也可以从Update()中选择退出“FindGameObjectWithTag”,如果可以的话:)@Mark我将在修复当前问题后执行此操作:)我知道我为你做了很大一部分工作。我只希望你能从中学习。不仅仅是复制粘贴。如果你对我写的代码有疑问,我很乐意回答。谢谢你告诉我我有多糟糕,但请原谅我现在问这个问题:我将公共静态bool inSight
更改为公共boolinSight
和public static bool isenemyatcking=false
到public bool isenemyatcking=false
现在我无法检查另一个脚本中的bool。例如,如果(EnemySight.inSight==true)
与isenemyatcking相同,我就无法再检查了。我得到一个错误资产/_Scripts/EnemyAttack.cs(24,35):错误CS0120:访问非静态成员'PlayerMovement.IsenemyTack'需要对象引用
public static bool inSight;
PlayerMovement.isEnemyAttacking
using UnityEngine;
using UnityEngine.UI;
public class PlayerHealth : MonoBehaviour
{
public static float Health;
public static float maxHealth = 100;
private Text healthText;
void Start()
{
healthText = GameObject.FindGameObjectWithTag("HealthPoints").GetComponent<Text>();
//Make it full 100% health on start
Health = maxHealth;
RefreshHealthBar();
}
public void TakeDamage(float damage)
{
Health -= damage;
RefreshHealthBar();
if (Health <= 0)
Die();
}
public void Die()
{
Health = 0;
RefreshHealthBar();
//TODO: Your code
}
void RefreshHealthBar()
{
healthText.text = "HEALTH: " + Health;
}
}
using System.Collections;
using UnityEngine;
public class EnnemyAI : MonoBehaviour
{
public float AttackDamage = 1.0f;
public float AttackSpeed = 1.0f;
public float AttackRange = 1.0f;
private bool isPlayerInSight;
private GameObject target;
private NavMeshAgent agent;
// Use this for initialization
void Start ()
{
target = GameObject.FindGameObjectWithTag("Player");
agent = GetComponent<NavMeshAgent>();
StartCoroutine(AttackLoop());
}
// Update is called once per frame
void Update ()
{
if (isPlayerInSight)
{
agent.destination = target.transform.position;
}
}
IEnumerator AttackLoop()
{
while (true)
{
//I don't know your attacking logic, so lets say they can attack in a 1 unit range
while (Vector3.Distance(target.transform.position, this.transform.position) <= AttackRange)
{
Attack();
yield return new WaitForSeconds(AttackSpeed);
}
yield return 0;
}
}
void Attack()
{
target.GetComponent<PlayerHealth>().TakeDamage(AttackDamage);
}
void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Player")
{
isPlayerInSight = true;
}
}
void OnTriggerExit(Collider other)
{
if (other.gameObject.tag == "Player")
{
isPlayerInSight = false;
}
}
}