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

Unity敌怪靠近玩家时丢失视野进入Idle状态问题求助

问题修复方案
  • 核心问题1:hasSeenPlayer参数为值传递,C#中值类型参数默认按值传递,函数内对该参数的修改仅作用于副本,不会同步到外部的HasSeenPLayer变量,导致if (distDif <= inRange && hasSeenPlayer)分支永远无法触发,因此不会输出I saw the player again日志,也不会自动转向玩家锁定视野。
  • 核心问题2:当前逻辑要求无论距离多近都需要满足视野角度条件才会返回true,当敌怪靠近玩家时若未及时转向,视野角度判断不通过,函数返回false就会触发Idle状态切换。

修复代码

首先修改PlayerPos类的FindPlayerPos方法,将hasSeenPlayer改为引用传递,同时优化近距离逻辑:

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

public class PlayerPos : MonoBehaviour
{
    // hasSeenPlayer参数增加ref关键字,改为引用传递
    public static bool FindPlayerPos(float inRange, GameObject playerPos, float inView, GameObject self, ref bool hasSeenPlayer)
    {
        float distDif = Vector3.Distance(playerPos.transform.position, self.transform.position);
        // 已经见过玩家且在攻击范围内,直接判定发现玩家,不需要卡视野限制
        if (distDif <= inRange && hasSeenPlayer)
        {
            self.transform.LookAt(playerPos.transform.position);
            Debug.Log("I saw the player again");
            return true;
        }

        // 第一次发现玩家的逻辑,需要同时满足距离、视野条件
        if (distDif <= inRange && PlayerIsInSight(inView, playerPos, self) && !hasSeenPlayer)
        {
            hasSeenPlayer = true;
            Debug.Log("I see player");
            return hasSeenPlayer;
        }
        // 不满足条件则判定丢失玩家,重置标记
        hasSeenPlayer = false;
        Debug.Log("I dont see player");
        return false;
    }

   
    public static bool PlayerIsInSight(float inView, GameObject playerPos, GameObject self)
    {
        Vector3 targetDir = playerPos.transform.position - self.transform.position;
        Vector3 forward = self.transform.forward;
        float angle = Vector3.SignedAngle(targetDir, forward, Vector3.up);
        float selfHeight = self.GetComponent<Collider>().bounds.size.y;

        if (angle <= inView && angle >= -inView && playerPos.transform.position.y <= self.transform.position.y + selfHeight/2 + selfHeight && playerPos.transform.position.y >= (self.transform.position.y - selfHeight) - selfHeight / 2)
        {
            return true;
        }
        return false;
    }
}

然后修改调用处代码,增加ref关键字匹配参数要求:

if (!PlayerPos.FindPlayerPos(AttackRange, playerPos, inView, self, ref HasSeenPLayer))
{
    // 原有切换Idle状态的逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 06:15:05