无法分配 "Death" 因为它是一个方法组
Cannot assign "Death" because its a method group
我最近开始学习c#,但是我遇到了一个错误,希望你们中的一些人能够帮助我。我们正在 Unity5 中开发一款游戏,当玩家的生命值达到 0 时,布娃娃功能将启动,但不幸的是我不能称之为死亡,因为它是一个方法组......有什么想法吗?干杯。这是代码(我将其注释掉,以便我可以在 Unity 中进入播放模式,因为错误不允许我进入第 47 行和第 53 行):
using UnityEngine;
using System.Collections;
public class EnemyAI_Basic : MonoBehaviour
{
private EnemyAI_Basic enemyAI_Basic;
Animator controller;
float health;
Animator anim;
bool Alive = true;
public bool Dead = false;
int pointValue = 5;
private Collider myCollider;
private Rigidbody myRigidbody;
CapsuleCollider capsuleCollider;
void Start()
{
controller = GetComponentInParent<Animator>();
health = 40;
capsuleCollider = GetComponent<CapsuleCollider>();
anim = GetComponent<Animator>();
}
void Update()
{
if (!Dead)
{
anim.SetTrigger("Alive");
}
}
void Death()
{
Dead = true;
Alive = false;
capsuleCollider.isTrigger = true;
anim.SetTrigger("Dead");
Destroy(gameObject, 4f);
}
void OnEnable()
{
SetInitialReferences();
enemyAI_Basic.Death += ActivateRagdoll;
}
void OnDisable()
{
enemyAI_Basic.Death -= ActivateRagdoll;
}
void SetInitialReferences()
{
enemyAI_Basic = transform.root.GetComponent<EnemyAI_Basic>();
if (GetComponent<Collider>() != null)
{
myCollider = GetComponent<Collider>();
}
if (GetComponent<Rigidbody>() != null)
{
myRigidbody = GetComponent<Rigidbody>();
}
}
void ActivateRagdoll()
{
if (myRigidbody != null)
{
myRigidbody.isKinematic = false;
myRigidbody.useGravity = true;
}
if (myCollider != null)
{
myCollider.isTrigger = false;
myCollider.enabled = true;
}
}
}
我明白你的问题了。
在这种情况下,您将死亡方法视为委托,但事实并非如此。您只能将方法注册到委托或事件,不能将方法注册到方法组。
对于您的情况,有几种方法可以解决此问题。
第一个解决方案,也是迄今为止最简单的解决方案,在 Death 函数中调用 ActivateRagdoll,如下所示:
void Death()
{
Dead = true;
Alive = false;
capsuleCollider.isTrigger = true;
anim.SetTrigger("Dead");
ActivateRagdoll();
Destroy(gameObject, 4f);
}
然后删除:
enemyAI_Basic.Death += ActivateRagdoll;
和
enemyAI_Basic.Death -= ActivateRagdoll;
来自 OnEnable 和 OnDisable 方法,应该可以消除所有编译器错误。
现在,为了使用这个方法,你所要做的就是从代码中的某个地方调用它。根据你杀死 Ai 的方式,你可以考虑制作那个方法 public,或者在你的更新循环中有一些死亡逻辑,
if(health <= 0)
{
Death();
enabled = false; //disable the component so the update loop doesn't repeat the death procedure multiple times, Unity might not be pleased.
}
另一种方式,也是您尝试这样做的方式,是创建一个 类 可以订阅方法的事件。这个事件将调用所有订阅的方法,为它们提供一种通知方式,无论何时发生有趣的事情,比如本例中的 Ai 死亡。这对于不需要经常检查 Ai 的死亡状态的外部 类 很有用,毕竟,如果 Ai 的健康状况良好,他们可能不会关心它。他们只需要知道,艾确实死了。事件是这种情况的理想选择。
要举办活动,您需要这样做:
public class EnemyAI_Basic : MonoBehaviour
{
//your other variables
public delegate void EnemyDies(); //declare the method types that can be registered to the event
public event EnemyDies onEnemyDeath; //declare event, using the delegate for the method type
//other methods here
private void OnEnable()
{
//must be the same method type as the event, the compiler will let you know if it isn't
onEnemyDeath += Death;
onEnemyDeath += ActivateRagdoll;
}
private void OnDisable()
{
onEnemyDeath -= Death;
onEnemyDeath -= ActivateRagdoll;
}
//other things here
//doesn't have to be public, just in case you want a bullet to kill the enemy
public void KillAi()
{
//checking for null basically says: is anybody registered? If not, nothing to invoke.
//It will get upset if you try and invoke an event without any registered methods, hence the check.
if(onEnemyDeath != null)
{
onEnemyDeath();
}
}
void Death()
{
Dead = true;
Alive = false;
capsuleCollider.isTrigger = true;
anim.SetTrigger("Dead");
//ActivateRagdoll(); You don't have to manually call this now, invoking the event will call it for you.
//Registration order is important, me thinks. Experiment :)
Destroy(gameObject, 4f);
}
}
还有其他几种方法可以安装这样的系统,但是,在您的情况下,这可能就是您所追求的。
一些阅读:
事件:https://www.codeproject.com/Articles/11541/The-Simplest-C-Events-Example-Imaginable
https://www.tutorialspoint.com/csharp/csharp_events.htm
代表:https://msdn.microsoft.com/en-us/library/ms173171.aspx
方法组:What is a method group in C#?
希望这对您有所帮助。
我最近开始学习c#,但是我遇到了一个错误,希望你们中的一些人能够帮助我。我们正在 Unity5 中开发一款游戏,当玩家的生命值达到 0 时,布娃娃功能将启动,但不幸的是我不能称之为死亡,因为它是一个方法组......有什么想法吗?干杯。这是代码(我将其注释掉,以便我可以在 Unity 中进入播放模式,因为错误不允许我进入第 47 行和第 53 行):
using UnityEngine;
using System.Collections;
public class EnemyAI_Basic : MonoBehaviour
{
private EnemyAI_Basic enemyAI_Basic;
Animator controller;
float health;
Animator anim;
bool Alive = true;
public bool Dead = false;
int pointValue = 5;
private Collider myCollider;
private Rigidbody myRigidbody;
CapsuleCollider capsuleCollider;
void Start()
{
controller = GetComponentInParent<Animator>();
health = 40;
capsuleCollider = GetComponent<CapsuleCollider>();
anim = GetComponent<Animator>();
}
void Update()
{
if (!Dead)
{
anim.SetTrigger("Alive");
}
}
void Death()
{
Dead = true;
Alive = false;
capsuleCollider.isTrigger = true;
anim.SetTrigger("Dead");
Destroy(gameObject, 4f);
}
void OnEnable()
{
SetInitialReferences();
enemyAI_Basic.Death += ActivateRagdoll;
}
void OnDisable()
{
enemyAI_Basic.Death -= ActivateRagdoll;
}
void SetInitialReferences()
{
enemyAI_Basic = transform.root.GetComponent<EnemyAI_Basic>();
if (GetComponent<Collider>() != null)
{
myCollider = GetComponent<Collider>();
}
if (GetComponent<Rigidbody>() != null)
{
myRigidbody = GetComponent<Rigidbody>();
}
}
void ActivateRagdoll()
{
if (myRigidbody != null)
{
myRigidbody.isKinematic = false;
myRigidbody.useGravity = true;
}
if (myCollider != null)
{
myCollider.isTrigger = false;
myCollider.enabled = true;
}
}
}
我明白你的问题了。 在这种情况下,您将死亡方法视为委托,但事实并非如此。您只能将方法注册到委托或事件,不能将方法注册到方法组。 对于您的情况,有几种方法可以解决此问题。
第一个解决方案,也是迄今为止最简单的解决方案,在 Death 函数中调用 ActivateRagdoll,如下所示:
void Death()
{
Dead = true;
Alive = false;
capsuleCollider.isTrigger = true;
anim.SetTrigger("Dead");
ActivateRagdoll();
Destroy(gameObject, 4f);
}
然后删除:
enemyAI_Basic.Death += ActivateRagdoll;
和
enemyAI_Basic.Death -= ActivateRagdoll;
来自 OnEnable 和 OnDisable 方法,应该可以消除所有编译器错误。 现在,为了使用这个方法,你所要做的就是从代码中的某个地方调用它。根据你杀死 Ai 的方式,你可以考虑制作那个方法 public,或者在你的更新循环中有一些死亡逻辑,
if(health <= 0)
{
Death();
enabled = false; //disable the component so the update loop doesn't repeat the death procedure multiple times, Unity might not be pleased.
}
另一种方式,也是您尝试这样做的方式,是创建一个 类 可以订阅方法的事件。这个事件将调用所有订阅的方法,为它们提供一种通知方式,无论何时发生有趣的事情,比如本例中的 Ai 死亡。这对于不需要经常检查 Ai 的死亡状态的外部 类 很有用,毕竟,如果 Ai 的健康状况良好,他们可能不会关心它。他们只需要知道,艾确实死了。事件是这种情况的理想选择。
要举办活动,您需要这样做:
public class EnemyAI_Basic : MonoBehaviour
{
//your other variables
public delegate void EnemyDies(); //declare the method types that can be registered to the event
public event EnemyDies onEnemyDeath; //declare event, using the delegate for the method type
//other methods here
private void OnEnable()
{
//must be the same method type as the event, the compiler will let you know if it isn't
onEnemyDeath += Death;
onEnemyDeath += ActivateRagdoll;
}
private void OnDisable()
{
onEnemyDeath -= Death;
onEnemyDeath -= ActivateRagdoll;
}
//other things here
//doesn't have to be public, just in case you want a bullet to kill the enemy
public void KillAi()
{
//checking for null basically says: is anybody registered? If not, nothing to invoke.
//It will get upset if you try and invoke an event without any registered methods, hence the check.
if(onEnemyDeath != null)
{
onEnemyDeath();
}
}
void Death()
{
Dead = true;
Alive = false;
capsuleCollider.isTrigger = true;
anim.SetTrigger("Dead");
//ActivateRagdoll(); You don't have to manually call this now, invoking the event will call it for you.
//Registration order is important, me thinks. Experiment :)
Destroy(gameObject, 4f);
}
}
还有其他几种方法可以安装这样的系统,但是,在您的情况下,这可能就是您所追求的。
一些阅读:
事件:https://www.codeproject.com/Articles/11541/The-Simplest-C-Events-Example-Imaginable https://www.tutorialspoint.com/csharp/csharp_events.htm
代表:https://msdn.microsoft.com/en-us/library/ms173171.aspx
方法组:What is a method group in C#?
希望这对您有所帮助。