我决定在我的项目中实现一个简单的消息系统。我使用的是这个:CSharpMessenger Extended(它使用静态方法实现)。
当我直接调用方法时,一切都正常,但当我使用消息系统广播消息时,却会在某些游戏对象上出现 NullReferenceException 异常。令我惊讶的是,添加下面这行代码
可能是什么问题呢?
以下是我广播消息的代码:
以下是我订阅事件并对其做出响应的步骤:
谢谢你!
当我直接调用方法时,一切都正常,但当我使用消息系统广播消息时,却会在某些游戏对象上出现 NullReferenceException 异常。令我惊讶的是,添加下面这行代码
if (_gameObject == null) return;
就解决了问题。然而,在每个出现异常的地方添加检查对象是否为空并不是一个选择。可能是什么问题呢?
以下是我广播消息的代码:
public class Head : MonoBehaviour {
public Snake snake;
void OnControllerColliderHit (ControllerColliderHit hit)
{
if ( hit.gameObject.GetComponent<Terrain>() )
return;
//This way everything was working without any surprises.
//snake.PropCollected( hit.gameObject.GetComponent<Prop>() );
//Using messaging system instead
if ( hit.gameObject.GetComponent<Prop>() )
Messenger<Prop>.Broadcast( "prop collected", hit.gameObject.GetComponent<Prop>() );
Destroy(hit.gameObject);
}
}
以下是我订阅事件并对其做出响应的步骤:
public class Snake : MonoBehaviour {
public GameObject headBlock;
public GameObject snakeBlocks;
int lastSnakeBlockId;
private GameObject FindBlockWithId( int _id )
{
if (!snakeBlocks) return null; //This line somehow solves the problem; However the object is 100% assigned in the editor.
foreach (Transform child in snakeBlocks.transform) {
if (child.gameObject.GetComponent<SnakeBlockScript>().blockId == _id)
{
return child.gameObject;
}
}
return headBlock;
}
void Awake()
{
//Set up message listeners
Messenger<Prop>.AddListener("prop collected", AddBlock);
}
public void AddBlock(Prop _prop)
{
GameObject lastBlock = FindBlockWithId(lastSnakeBlockId - 1);
if (!lastBlock) return;
//Some more code
//...
}
}
谢谢你!
Destroy(hit.gameObject);
会将引用设置为null,但不会从某个列表中删除该引用,比如监听器列表。 - Kevin Stricker