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
相关产品推荐
相关产品推荐

