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

Unity中如何创建无敌增益道具?跑酷游戏开发新手求助

解决跑酷游戏无敌增益道具问题

你的原脚本存在两个核心问题:一是Physics.IgnoreCollision的用法错误(该方法需要传入两个具体的碰撞体参数,而非批量传入所有碰撞体);二是没有通过状态标记或精准碰撞控制来实现玩家的无敌逻辑。结合你障碍物都是isTrigger且标记为Obstacles的设定,这里提供两种可靠的实现方案:

方案一:状态标记法(更推荐,逻辑灵活)

这种方式通过给玩家添加「无敌状态」标记,在障碍物的触发逻辑中判断是否执行死亡操作,不会影响玩家与其他物体的正常碰撞(比如地面、道具)。

步骤1:修改玩家脚本

在玩家的核心控制脚本(比如PlayerController)中添加无敌状态变量,并修改死亡触发逻辑:

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public bool isInvincible = false; // 无敌状态标记

    // 假设你原本的死亡方法是这个
    public void Die()
    {
        if (!isInvincible) // 仅当非无敌时触发死亡
        {
            // 这里写你的死亡逻辑,比如播放动画、游戏结束
            Debug.Log("玩家死亡");
        }
    }
}

步骤2:修改障碍物脚本(如果有的话)

如果障碍物有自己的触发脚本,确保碰到玩家时只在玩家非无敌时调用死亡:

using UnityEngine;

public class Obstacle : MonoBehaviour
{
    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            PlayerController player = other.GetComponent<PlayerController>();
            if (player != null)
            {
                player.Die(); // 调用玩家的死亡方法,由玩家自身判断是否执行
            }
        }
    }
}

步骤3:修改PowerUp脚本

让道具捡取后给玩家设置无敌状态,持续指定时间后取消:

using System.Collections;
using UnityEngine;

public class PowerUp : MonoBehaviour
{
    public float duracion = 5f;

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            StartCoroutine(Pickup(other.GetComponent<PlayerController>()));
        }
    }

    private IEnumerator Pickup(PlayerController player)
    {
        Destroy(gameObject); // 销毁道具
        player.isInvincible = true; // 开启无敌

        // 可以在这里加一些特效提示,比如播放无敌动画、音效
        Debug.Log("玩家进入无敌状态");

        yield return new WaitForSeconds(duracion);

        player.isInvincible = false; // 关闭无敌
        Debug.Log("无敌状态结束");
    }
}

方案二:碰撞忽略法(直接控制玩家与障碍物的碰撞)

如果你更倾向于用物理引擎直接屏蔽碰撞,可以通过循环设置玩家与所有障碍物的碰撞忽略,时间到后恢复:

修改后的PowerUp脚本

using System.Collections;
using UnityEngine;

public class PowerUp : MonoBehaviour
{
    public float duracion = 5f;
    private Collider playerCollider;
    private Collider[] obstacleColliders;

    private void OnTriggerEnter(Collider other)
    {
        if (other.CompareTag("Player"))
        {
            playerCollider = other;
            // 获取所有标记为Obstacles的碰撞体
            obstacleColliders = GameObject.FindGameObjectsWithTag("Obstacles").GetComponent<Collider>();
            StartCoroutine(Pickup());
        }
    }

    private IEnumerator Pickup()
    {
        Destroy(gameObject);

        // 循环设置玩家与每个障碍物忽略碰撞
        foreach (var obstacleCol in obstacleColliders)
        {
            if (obstacleCol != null)
            {
                Physics.IgnoreCollision(playerCollider, obstacleCol, true);
            }
        }

        yield return new WaitForSeconds(duracion);

        // 时间到后恢复碰撞
        foreach (var obstacleCol in obstacleColliders)
        {
            if (obstacleCol != null)
            {
                Physics.IgnoreCollision(playerCollider, obstacleCol, false);
            }
        }
    }
}

注意:这种方法需要确保所有障碍物都正确标记Obstacles标签,且如果有动态生成的障碍物,需要额外处理(比如在生成时重新获取碰撞体列表)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 22:15:15