我们正在一些2D项目中工作。我们得到了一块棋盘,看起来像国际象棋棋盘(8x8),并且一些物体在此棋盘的上方产生,例如俄罗斯方块。 当物体到达棋盘底部或其他物体时,它将在所有棋盘上向四个方向进攻-向上,向下,向左和向右。
我有3个脚本,Spawn,Obj_Controller和Personal_Attack。 Spawn脚本附着在spawnzone空对象上,两个不同的脚本都附着在我们生成的objet上。对象具有标签-敌人,我用它来检测需要攻击的对象之间的差异,例如Spawnzone和Bonuses(仍然不是准备)。希望我提供有关项目的足够信息,所以让我们看一下代码。
在游戏开始时以及每次攻击结束后,我都会使用生成的对象
public class Spawn : MonoBehaviour
{
public GameObject[] objects;
Vector3 spotSpawn;
// Start is called before the first frame update
void Start()
{
spotSpawn = transform.position;
//Debug.Log(spotSpawn);
NewSpawn();
}
// Update is called once per frame
void Update()
{
}
public void NewSpawn()
{
int random_key = Random.Range(0,objects.Length - 1);
Instantiate(objects[random_key], spotSpawn, Quaternion.identity);
}
}
我用来使对象移动的Obj_Controller,并在时间到来时发起攻击
public class Obj_Controller : MonoBehaviour
{
public float speed; // speed (I still dont use this var)
[HideInInspector] public bool isMoved = true; // movement flag
[HideInInspector] public bool canSpawn = false; // spawn flag
[HideInInspector] public bool attack = false; // attack flag
bool LetFall = true; // falling flag
[HideInInspector] public Animator anim;
// Start is called before the first frame update
void Start()
{
}
private void OnEnable()
{
anim = GetComponent<Animator>();
//Debug.Log(transform.position);
}
// Update is called once per frame
void Update()
{
if (isMoved == true && canSpawn == false)
{
Collider2D[] hitDown = Physics2D.OverlapCircleAll(transform.position - new Vector3(0, 1, 0), 0.5f);
Collider2D[] hitLeft = Physics2D.OverlapCircleAll(transform.position - new Vector3(1, 0, 0), 0.5f);
Collider2D[] hitRight = Physics2D.OverlapCircleAll(transform.position + new Vector3(1, 0, 0), 0.5f);
if (hitDown.Length == 0)
{
//Check object can movew down in 1 cell
if (LetFall == true)
{
LetFall = false;
StartCoroutine(Down());
}
//Check object can move in left or right side
if (Input.GetKeyDown(KeyCode.LeftArrow) && hitLeft.Length == 0)
{
transform.position -= new Vector3(1,0,0);
}
else if (Input.GetKeyDown(KeyCode.RightArrow) && hitRight.Length == 0)
{
transform.position += new Vector3(1, 0, 0);
}
}
else
{
//Debug.Log(hitDown[0].name);
isMoved = false;
if(attack == false)
{
attack = true;
gameObject.SendMessage("Attack");
}
}
}
else if(canSpawn == true)
{
canSpawn = false;
GameObject spawner = GameObject.Find("SpawnZone");
Spawn spawn = spawner.GetComponent<Spawn>();
spawn.NewSpawn();
}
else
{
//Here will some functions, but later
}
}
IEnumerator Down()
{
transform.position -= new Vector3(0,1, 0);
yield return new WaitForSeconds(0.5f);
LetFall = true;
}
}
Personal_Attack是试图在4个方向上查找其他对象的脚本,每次攻击的长度等于木板的8个单元(每个步骤== 1,每个对象的transform.position ==单元的中心)。
public class Personal_Attack : MonoBehaviour
{
Obj_Controller objcontroller;
// Start is called before the first frame update
void OnEnable()
{
objcontroller = GetComponent<Obj_Controller>();
}
// Update is called once per frame
void Update()
{
}
void Attack()
{
//Attack up
for (int i = 1; i < 9; i++)
{
Collider2D[] hitTop = Physics2D.OverlapCircleAll(transform.position + new Vector3(0, i, 0), 0.5f);
foreach (Collider2D enemy in hitTop)
{
if (enemy.tag == "Enemy")
{
Debug.Log(enemy.transform.position);
Destroy(enemy.gameObject);
}
}
}
//Attack down
for (int i = 1; i < 9; i++)
{
Collider2D[] hitDown = Physics2D.OverlapCircleAll(transform.position - new Vector3(0, i, 0), 0.5f);
foreach (Collider2D enemy in hitDown)
{
if (enemy.tag == "Enemy")
{
Destroy(enemy.gameObject);
}
}
}
//Attack left
for (int i = 1; i < 9; i++)
{
Collider2D[] hitLeft = Physics2D.OverlapCircleAll(transform.position - new Vector3(i, 0, 0), 0.5f);
foreach (Collider2D enemy in hitLeft)
{
if (enemy.tag == "Enemy")
{
Destroy(enemy.gameObject);
}
}
}
//Attack right
for (int i = 1; i < 9; i++)
{
Collider2D[] hitRight = Physics2D.OverlapCircleAll(transform.position + new Vector3(i, 0, 0), 0.5f);
foreach (Collider2D enemy in hitRight)
{
if (enemy.tag == "Enemy")
{
Destroy(enemy.gameObject);
}
}
}
objcontroller.canSpawn = true;
}
}
因此,由于某种原因,在攻击对象销毁后,它不仅可以通过其攻击到达目标,而且也销毁自身,并且游戏停止(不生成任何事件,因为攻击者对象无法调用spawn函数,因为它已经被销毁了)。 _。)。我不明白我犯了什么错误。
答案 0 :(得分:1)
我看到它何时会发生的唯一方法是,如果您的攻击者对象也具有“敌人”标签。检查所有对象上的标签。
已更新:
因此,看来您在攻击者身上带有“敌人”标签,如果您确实出于某种原因需要在此处使用它,则可以通过以下方式简单地对其进行修复:
在带有“销毁”的循环中,您可以添加简单的检查是否是同一对象:
if (enemy.tag == "Enemy" && enemy.gameObject != gameObject)
{
Destroy(enemy.gameObject);
}
答案 1 :(得分:0)
看起来您的敌人对撞机足够大,可以延伸到相邻正方形的边界,并且在边界处可能会稍微重叠。我会将您的OverlapCircleAll
通话的半径缩小一小部分(例如Mathf.Epsilon
),以使正方形的边界不会被触及:
Collider2D[] hitTop = Physics2D.OverlapCircleAll(
transform.position + new Vector3(0, i, 0),
0.5f - Mathf.Epsilon);