求助各位大佬,关于协程
unity3d吧
全部回复
仅看楼主
level 5
BeWithU 楼主
问题描述:
我创建了一个Target的游戏物体,这个物体下面有四个隐藏的怪兽,我通过协程来让这四种怪兽中的随机一个生成和隐藏,以及被子弹打中后销毁并且重新生成的逻辑,怪物被子弹击中后的销毁时间是1f秒。
我让怪物生成用了一个ActiveTimer的协程,隐藏用了KillTimer,并且ActiveTimer最后调用了KillTimer,KillTimer的最后又调用了ActiveTimer,实现了怪物在1-5秒内生成,又在3-8秒后隐藏的效果。
在这个Target只有一个的时候,是没有问题的。当我把这个Target复制了几份的时候,发现怪物的销毁时间变化了,不再是1秒了。因此我怀疑是不是多个物体的协程冲突了,但是这几个物体都是复制出来的,按理说应该是独立的个体吧。
反正只有一个Target的时候,怪物的销毁时间是正常的,多个Target的时候就不正常了。
2024年12月01日 15点12分 1
level 5
BeWithU 楼主
下面是源代码,共6个.cs文件
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager instance { get; private set; }
public bool isPaused = true;
public GameObject Menu;
public GameObject[] targetGOs;
void Awake()
{
instance = this;
Pause();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Pause();
}
}
public void Pause()
{
isPaused = true;
Menu.SetActive(true);
Time.timeScale = 0;
Cursor.visible = true;
}
public void UnPause()
{
isPaused = false;
Menu.SetActive(false);
Time.timeScale = 1;
Cursor.visible = false;
}
public void NewGame()
{
//TargetManager.instance.RestartMonstersLoop();
//UnPause();
foreach (GameObject go in targetGOs)
{
go.GetComponent<TargetManager>().RestartMonstersLoop();
}
UIManager.instance.shootNum = 0;
UIManager.instance.score = 0;
UnPause();
}
}
-----------------------------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager : MonoBehaviour
{
public static UIManager instance { get; private set; }
public Text shootNumText;
public Text scoreText;
public int shootNum = 0;
public int score = 0;
void Awake()
{
instance = this;
}
void Update()
{
shootNumText.text = shootNum.ToString();
scoreText.text = score.ToString();
}
public void AddShootNum()
{
shootNum++;
}
public void AddScore()
{
score++;
}
}
-----------------------------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class MonsterManager : MonoBehaviour
{
private Animation anim;
public AnimationClip idleClip;
public AnimationClip dieClip;
void Start()
{
anim = GetComponent<Animation>();
}
private void OnCollisionEnter(Collision collision)
{
if (collision.collider.tag == "Bullet")
{
//销毁子弹
Destroy(collision.collider.gameObject);
//杀死怪物
anim.clip = dieClip;
anim.Play();
GetComponent<BoxCollider>().enabled = false;
StartCoroutine("KillMonster");
UIManager.instance.AddScore();
}
}
private void OnDisable()
{
anim.clip = idleClip;
}
IEnumerator KillMonster()
{
yield return new WaitForSeconds(0.8f);
TargetManager.instance.RestartMonstersLoop();
print("111");
}
}
-----------------------------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BulletManager : MonoBehaviour
{
void Start()
{
StartCoroutine("DestroySelf");
}
IEnumerator DestroySelf()
{
yield return new WaitForSeconds(2);
Destroy(gameObject);
}
}
-----------------------------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunManager : MonoBehaviour
{
private float maxXRotation = 120;
private float minXRotation = 0;
private float maxYRotation = 60;
private float minYRotation = 0;
private float shootTime = 0.1f;
private float shootTimer = 0;
public GameObject bullet;
public Transform firePosition;
//控制子弹发射频率
void Update()
{
if ( GameManager.instance.isPaused )
{
return;
}
shootTimer += Time.deltaTime;
if (shootTimer >= shootTime)
{
//TODO 可以是射击
if (Input.GetMouseButtonDown(0))
{
GameObject tempBullet = GameObject.Instantiate(bullet, firePosition.position, Quaternion.identity);
tempBullet.GetComponent<Rigidbody>().AddForce(transform.forward * 2000);
shootTimer = 0;
gameObject.GetComponent<Animation>().Play();
UIManager.instance.AddShootNum();
}
}
//控制枪口的旋转
float xPosPrecent = Input.mousePosition.x / Screen.width;
float yPosPrecent = Input.mousePosition.y / Screen.height;
float yAngel = Mathf.Clamp(xPosPrecent*maxXRotation, minXRotation, maxXRotation) - 60;
float xAngel = -Mathf.Clamp(yPosPrecent * maxYRotation, minYRotation, maxYRotation) + 15;
transform.eulerAngles = new Vector3(xAngel, yAngel,0);
}
}
-----------------------------------------------------------------------------------------------------
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TargetManager : MonoBehaviour
{
public static TargetManager instance { get; private set; }
public GameObject[] monsters;
private GameObject activeMonsters = null;
void Awake()
{
instance = this;
}
// Start is called before the first frame update
void Start()
{
foreach (GameObject monster in monsters)
{
monster.SetActive(false);
monster.GetComponent<BoxCollider>().enabled = false;
}
//ActiveMonsters();
StartCoroutine("ActiveTimer");
}
// Update is called once per frame
void Update()
{
}
public void ActiveMonsters()
{
int index = Random.Range(0, monsters.Length);
// print(index);
activeMonsters = monsters[index];
activeMonsters.SetActive(true);
activeMonsters.GetComponent<BoxCollider>().enabled = true ;
StartCoroutine("KillTimer");
}
IEnumerator ActiveTimer()
{
yield return new WaitForSeconds(Random.Range(1, 5));
ActiveMonsters();
}
private void KillMonsters()
{
if (activeMonsters != null)
{
activeMonsters.GetComponent<BoxCollider> ().enabled = false;
activeMonsters.SetActive (false);
activeMonsters = null;
}
StartCoroutine("ActiveTimer");
}
IEnumerator KillTimer()
{
yield return new WaitForSeconds (Random.Range(3, 8));
KillMonsters();
}
public void RestartMonstersLoop()
{
//yield return null;
StopAllCoroutines();
if (activeMonsters != null)
{
activeMonsters.SetActive(false);
activeMonsters = null;
}
StartCoroutine("ActiveTimer");
}
}
2024年12月01日 15点12分 2
level 7
就是target冲突,TargetManager.instance只能指向一个TargetManager实例,其它的TargetManager你无法访问,调用不了他们的restartmonsterloop
2024年12月02日 01点12分 3
@作死小助手 牛逼哥,果然我每个怪物单独获得targetManager的脚本组件,然后单独调用restartMonsterLoop方法就好了
2024年12月02日 11点12分
1