Unity中检测布尔值切换精确帧并触发函数(潜行游戏场景)
解决潜行游戏中捕捉玩家脱离敌人视线帧的方案
要精准捕捉玩家脱离敌人视线的瞬间并记录位置,核心思路是追踪玩家可见状态的帧间变化——当状态从"可见"切换到"不可见"的那一帧,立刻记录玩家位置。Unity没有直接内置这个功能,但通过简单的状态变量就能实现,以下是结合你现有代码的修改方案:
步骤1:新增状态追踪变量
在你的敌人脚本中添加两个变量,分别跟踪上一帧的可见状态和最后记录的玩家位置:
private bool wasPlayerVisibleLastFrame; // 记录上一帧玩家是否可见 private Vector3 lastSeenPlayerPosition; // 存储玩家最后被看到的位置
步骤2:提炼可见状态判断逻辑
把现有代码中分散的可见条件整合成一个统一的布尔值,方便后续帧间对比:
void Update() { // 先计算当前帧玩家是否可见 bool isPlayerVisibleCurrentFrame = false; // 检查是否有障碍物遮挡 bool hasObstruction = Physics.Raycast( headObj.position, (player.transform.position - headObj.position).normalized, Vector3.Distance(headObj.position, player.transform.position), obstructionLayer ); if (!hasObstruction) { // 可见条件:要么在主视野锥,要么在 peripheral 视野且未蹲伏/滑铲 isPlayerVisibleCurrentFrame = playerInVisionCone || (playerInPVisionCone && !isCrouched && !isSliding); }
步骤3:捕捉脱离视线的瞬间
对比当前帧和上一帧的可见状态,当从可见变为不可见时,记录玩家位置:
// 关键:检测从可见到不可见的帧切换 if (wasPlayerVisibleLastFrame && !isPlayerVisibleCurrentFrame) { // 记录玩家当前位置,这就是脱离视线的精确帧位置 lastSeenPlayerPosition = player.transform.position; // 这里可以直接触发敌人的搜索状态 // 例如:SwitchEnemyState(EnemyState.Search, lastSeenPlayerPosition); }
步骤4:重构Awareness逻辑(可选,优化代码可读性)
用统一的可见状态变量重构原有的警觉值增减逻辑:
// 处理警觉值变化 if (isPlayerVisibleCurrentFrame) { if (playerInVisionCone) { if (awareness < awarenessCombatThreshold) { awareness += Time.deltaTime * distanceAwarenessMultiplier; } } else if (playerInPVisionCone) { if (awareness < awarenessCombatThreshold) { awareness += Time.deltaTime * pVisionAwarenessMultiplier * distanceAwarenessMultiplier; } } } else { if (awareness > 0) { awareness -= Time.deltaTime * awarenessCooldownMultiplier; } }
步骤5:更新上一帧状态
在Update方法末尾更新上一帧的可见状态,供下一帧对比使用:
// 更新上一帧的可见状态,必须放在Update最后 wasPlayerVisibleLastFrame = isPlayerVisibleCurrentFrame; }
额外注意事项
- 确保
playerInVisionCone和playerInPVisionCone的计算逻辑在每帧都执行(比如在Update开头先计算这两个值,再运行上述视野逻辑) - 如果追求视觉上的精准度,建议在
Update中执行上述逻辑;如果依赖物理检测,可移至FixedUpdate,但需注意物理帧与渲染帧的差异 - 可以给位置记录加额外条件:比如只有当
awareness超过某个阈值(比如敌人已经注意到玩家)时才记录位置,避免误触发搜索
内容的提问来源于stack exchange,提问作者Lex Butcher
相关产品推荐
相关产品推荐

