我目前正在制作Breakout风格的游戏,并且在玩5个或6个以上的球时有销毁积木的问题(没有实数会重现此bug,只有在有很多球时才会发生在玩)。有一个双和三重的球通电,因此球的数量可以在短时间内迅速增加。
在我的GameManager脚本中,我在场景开始时跟踪砖的初始数量,每当一个球与砖接触时就减去1。积木数量为零后,玩家获胜,游戏结束。该游戏只处理少量球,但是当涉及过多球时,该过程似乎会中断。
GameManager.cs的相关代码:
void Start()
{
livesText.text = "Lives: " + Lives;
numOfBalls = GameObject.FindGameObjectsWithTag("Ball").Length;
numOfBricks = GameObject.FindGameObjectsWithTag("Brick").Length;
//Debug.Log(numOfBalls);
}
public void UpdateBrickNumber()
{
numOfBricks--;
if(numOfBricks <= 0)
{
numOfBricks = 0;
GameOver();
}
}
void GameOver()
{
gameOver = true;
if(numOfBricks == 0)
{
WinPanel.SetActive(true);
}
else
{
GameOverPanel.SetActive(true);
}
}
...
处理冲突的球代码:
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.transform.CompareTag("Brick"))
{
Debug.Log("Brick Hit");
//Chance of powerup to spawn
int rand = Random.Range(1, 101);
//Chance of each power up
int rand2 = Random.Range(1, 101);
if (rand < 7)
{
if (rand2 >=1 && rand2<=20) {
Instantiate(SpeedBall, collision.transform.position, collision.transform.rotation);
//Debug.Log(" Speed Power Up Created ");
}
...
Rest of power ups
...
}
Transform newExplosion = Instantiate(explosion, collision.transform.position, collision.transform.rotation);
Destroy(newExplosion.gameObject, 2f);
gm.UpdateBrickNumber();
Destroy(collision.gameObject);
}
}
Debug日志确实显示击中了正确数量的积木,但我认为某些球在击中同一块积木之前就有机会被销毁。我如何确保在另一个球撞击砖块上的对撞机之前将砖块销毁?
答案 0 :(得分:2)
直觉,您在一帧中遇到多次碰撞,导致砖块数少于剩余砖块数,这应该解决:
void OnCollisionEnter2D(Collision2D collision)
{ //Check if the brick has already been processed
if (collision.transform.CompareTag("Brick") && collision.collider.enabled)
{
Debug.Log("Brick Hit");
//Chance of powerup to spawn
int rand = Random.Range(1, 101);
//Chance of each power up
int rand2 = Random.Range(1, 101);
if (rand < 7)
{
if (rand2 >=1 && rand2<=20) {
Instantiate(SpeedBall, collision.transform.position, collision.transform.rotation);
//Debug.Log(" Speed Power Up Created ");
}
...
Rest of power ups
...
}
Transform newExplosion = Instantiate(explosion, collision.transform.position, collision.transform.rotation);
Destroy(newExplosion.gameObject, 2f);
gm.UpdateBrickNumber();
//Mark the brick as hit already so other balls can't hit it!
collision.collider.enabled = false;
Destroy(collision.gameObject);
}
}
实际对象销毁总是会延迟到当前的Update循环之后,但始终会在渲染之前完成。
Destroy
不是即时的。它将在更新循环之后进行,这意味着如果两个球在同一帧中命中,则您的计数将减少两个,但只会破坏一块砖。
答案 1 :(得分:0)
快速简短答案
在C#和Java中,对象不会立即销毁,它们会被放入要删除的进程中,有时会立即发生,有时不会。
有时,其他对象仍然引用它们。解决方法是先删除那些引用。
name object_id principal_id schema_id parent_object_id type type_desc create_date modify_date is_ms_shipped is_published is_schema_published lob_data_space_id filestream_data_space_id max_column_id_used lock_on_bulk_load uses_ansi_nulls is_replicated has_replication_filter is_merge_published is_sync_tran_subscribed has_unchecked_assembly_data text_in_row_limit large_value_types_out_of_row is_tracked_by_cdc lock_escalation lock_escalation_desc is_filetable is_memory_optimized durability durability_desc temporal_type temporal_type_desc history_table_id is_remote_data_archive_enabled is_external
DL_CONLog 719055 NULL 1 0 U USER_TABLE 43:24.3 01:41.0 0 0 0 0 NULL 10 0 1 0 0 0 0 0 0 0 0 0 TABLE 0 0 0 SCHEMA_AND_DATA 0 NON_TEMPORAL_TABLE NULL 0 0
DL_TIMJobImportLinkBrokerToModule 771110 NULL 1 0 U USER_TABLE 45:12.1 45:20.7 0 0 0 1 NULL 64 0 1 0 0 0 0 0 0 0 0 0 TABLE 0 0 0 SCHEMA_AND_DATA 0 NON_TEMPORAL_TABLE NULL 0 0
干杯。