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

Unity中与特定对象碰撞无法减少生命值的问题修复求助

问题:Unity玩家生命值无法减少(无编译错误)

场景说明

AI发射的Bullet对象已启用isTrigger属性,尝试关闭该属性后问题仍未解决;添加Update()函数也无法让生命值更新减少。

失效代码片段

private void OnCollisionEnter(Collision collision)
{
    if (collision.gameObject.name == "Bullet")
    {
        TakeDamage(20);
        Debug.Log("Damaged!");

        if (currentHealth <= 0f)
        {
            SceneManager.LoadScene("You Lost!");
        }
    }
}

完整代码

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

public class PlayerHealth : MonoBehaviour
{
    public int maxHealth = 100;
    public int currentHealth;

    public HealthBar healthBar;

    void Start()
    {
        currentHealth = maxHealth;
        healthBar.SetMaxHealth(maxHealth);
    }

    private void OnCollisionStay(Collision collision)
    {
        if (collision.gameObject.name == "Bullet(Clone)")
        {
            TakeDamage(20);
            Debug.Log("Damaged!");

            if (currentHealth <= 0f)
            {
                SceneManager.LoadScene("You Lose!");
            }
        }
    }

    void TakeDamage(int damage)
    {
        currentHealth -= damage;

        healthBar.SetHealth(currentHealth);
    }
}

问题修复方案

1. 匹配碰撞/触发器事件类型

  • 若Bullet启用isTrigger:必须使用OnTriggerEnter/OnTriggerStay替代OnCollisionEnter/OnCollisionStay,触发器不会触发碰撞类事件。
  • 若关闭isTrigger:需确保Player和Bullet都有Collider组件,且至少一方带有非运动学的Rigidbody组件(否则无法触发碰撞事件)。

2. 替换对象名称判断为标签判断

用标签(Tag)替代名称判断更可靠,避免克隆对象名称差异导致匹配失败:

// 先给Bullet对象设置Tag为"Bullet"
if (collision.gameObject.CompareTag("Bullet"))

3. 避免重复扣血

OnCollisionStay会在碰撞持续的每一帧重复调用,导致一次碰撞扣多次血,建议改用单次触发事件,并销毁子弹:

// 若用触发器
private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Bullet"))
    {
        TakeDamage(20);
        Debug.Log("Damaged!");
        Destroy(other.gameObject); // 销毁子弹防止重复触发
        if (currentHealth <= 0)
        {
            SceneManager.LoadScene("You Lose!");
        }
    }
}

4. 优化生命值检查逻辑

将生命值检查移到TakeDamage函数内,确保每次扣血后都触发状态判断:

void TakeDamage(int damage)
{
    currentHealth -= damage;
    healthBar.SetHealth(currentHealth);
    
    if (currentHealth <= 0)
    {
        SceneManager.LoadScene("You Lose!");
    }
}

5. 检查组件引用与配置

  • 确认healthBar变量已在Inspector面板中正确赋值,避免SetHealth调用无效。
  • 检查Player对象的Collider组件是否启用,Bullet对象的Collider是否未被禁用。

内容的提问来源于stack exchange,提问作者Click To Restart Button

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 20:30:54