You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity角色被敌人击中后重复实例化问题求助

平台跳跃游戏角色被击中后重复实例化问题解决

问题描述

开发平台跳跃游戏时,角色被带有DamageDealer标签的敌人击中后会执行角色实例化操作,但添加动画代码后出现了角色被实例化两次的问题。

问题原因分析

  1. 碰撞触发多次:添加动画后,角色碰撞体可能随动画帧位移,与敌人碰撞体发生多次接触,导致OnCollisionEnter2D被重复调用。
  2. 无防重处理机制:未设置标记变量,无法阻止同一碰撞事件的重复逻辑执行。
  3. 对象销毁逻辑模糊:原代码中Destroy(player)容易混淆预制体与实例对象,若player绑定的是当前角色实例,销毁操作未及时终止后续可能的重复触发。

解决方案

1. 添加防重标记

新增布尔变量标记角色是否已被击中,避免重复执行实例化逻辑。

2. 修正销毁逻辑

销毁当前角色实例而非player变量(假设player为角色预制体),确保操作对象正确。

3. 优化标签检测

使用Unity推荐的CompareTag替代tag.Equals,提升性能并避免空引用风险。

修改后的代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class PlayerMove : MonoBehaviour
{
    public GameObject playerPrefab; // 重命名变量,明确为预制体
    private Rigidbody2D rb;
    private SpriteRenderer sprite;
    private BoxCollider2D coll;
    private Animator anim;
    private bool hasBeenHit = false; // 防重标记

    public float Speed;
    public float JumpForce;
    private float dirX = 0f;

    private float fJumpPressedRemember = 0f;
    private float fJumpPressedRememberTime = 0.2f;

    [SerializeField] private LayerMask jumpableGround;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        anim = GetComponent<Animator>();
        sprite = GetComponent<SpriteRenderer>();
        coll = GetComponent<BoxCollider2D>();
    }

    void Update()
    {
        dirX = Input.GetAxisRaw("Horizontal");
        rb.velocity = new Vector2(dirX * Speed, rb.velocity.y);

        fJumpPressedRemember -= Time.deltaTime;
        if (Input.GetButtonDown("Jump"))
        {
            fJumpPressedRemember = fJumpPressedRememberTime;
        }

        if ((fJumpPressedRemember > 0) && isGrounded())
        {
            fJumpPressedRemember = 0;
            rb.velocity = new Vector2(rb.velocity.x, JumpForce);
        }

        UpdateAnimation();
    }

    private bool isGrounded()
    {
        return Physics2D.BoxCast(coll.bounds.center, coll.bounds.size, 0f, Vector2.down, .1f, jumpableGround);
    }

    void OnCollisionEnter2D(Collision2D spikeCol)
    {
        if (hasBeenHit) return; // 已处理过碰撞则直接返回

        if (spikeCol.gameObject.CompareTag("DamageDealer"))
        {
            hasBeenHit = true; // 标记为已击中
            Instantiate(playerPrefab, new Vector3(-10, 1, 0), Quaternion.identity);
            Destroy(gameObject); // 销毁当前角色实例
        }

        if (spikeCol.gameObject.CompareTag("End"))
        {
            SceneManager.LoadScene("Level2", LoadSceneMode.Single);
        }
        
        if (spikeCol.gameObject.CompareTag("End2"))
        {
            SceneManager.LoadScene("Level1", LoadSceneMode.Single);
        }
    }

    private void UpdateAnimation()
    {
        if (dirX > 0f)
        {
            anim.SetBool("running", true);
            sprite.flipX = false;
        }
        else if (dirX < 0f)
        {
            anim.SetBool("running", true);
            sprite.flipX = true;
        }
        else
        {
            anim.SetBool("running", false);
        }
    }
}

额外提示

  • 若问题仍存在,可尝试将敌人碰撞体设置为Is Trigger,改用OnTriggerEnter2D检测接触,减少物理碰撞导致的多次触发。

内容的提问来源于stack exchange,提问作者DerpySmiley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 09:35:22