【问题标题】:Raycast only returns false, even when true expectedRaycast 仅返回 false,即使预期为 true
【发布时间】:2020-06-15 11:50:40
【问题描述】:

我有以下FollowingNPC 游戏对象,如果有直视,它应该跟随Player 对象:

这里是Player 对象:

BlockingLayerPlayer 层之间启用了物理碰撞:

FollowingNPC 附加了以下脚本,该脚本始终返回“未命中”结果:Raycast 始终为 false。这不是预期的输出,因为两个对象之间似乎有清晰的视图,并且可以毫无问题地绘制调试射线。

public class FollowingNPC : MonoBehaviour
{
    private Vector3 heading, direction;
    private float distance;

    void Update()
    {
        heading = GameObject.FindGameObjectWithTag("Player").transform.position - transform.position;
        distance = heading.magnitude;
        direction = heading / distance;

        RaycastHit hit;
        if (Physics.Raycast(transform.position, direction, out hit))
        {
            if (hit.transform== GameObject.FindGameObjectWithTag("Player").transform)
            {
                Debug.DrawRay(transform.position, direction * distance, Color.red);
                Debug.Log("Hit Player");
            }
            else
            {
                Debug.DrawRay(transform.position, direction * distance, Color.yellow);
                Debug.Log("Hit Wall");
            }

        }
        else
        {
            Debug.DrawRay(transform.position, direction * distance, Color.white);
            Debug.Log("Not Hit");
        }
    }
}

已解决:

正如derHugo 建议的那样,这里应该使用Physics2D.Raycast。这个函数不返回布尔值,所以这是对我有用的实现:

void Update()
{
    heading = GameObject.FindGameObjectWithTag("Player").transform.position - transform.position;
    RaycastHit2D hit = Physics2D.Raycast(transform.position, heading.normalized, LayerMask.GetMask("Player"));

    if (hit.collider != null)
        if (hit.transform == GameObject.FindGameObjectWithTag("Player").transform)
            Debug.Log("Hit Player");
        else
            Debug.Log("Hit Wall");
    else
        Debug.Log("Not Hit");
}

另外,重要的是要注意,即使有面具,Raycast 也会用FolloginNPC 的对撞机返回命中,所以我不得不禁用它。我将不得不进行一些调查或寻找解决方法。

【问题讨论】:

  • 您的意思是Raycastfalse?光线追踪用于闪电系统,与您所说的无关;)

标签: unity3d


【解决方案1】:

请注意,在 Unity 中,PhysicsPhysics2D 是完全独立且分开的 Physics 引擎!

  • 内置 3D 物理(Nvidia PhysX 引擎集成)
  • 内置 2D 物理(Box2D 引擎集成)

您有Rigidbody2DCollider2D,所以您更愿意使用Physics2D.Raycast

您还应该强烈避免在Update 中使用FindGameObjectWithTag,甚至更糟糕的是多次使用,因为它非常昂贵!而是执行一次并存储结果。

// If possible and best would be to already reference it via the Inspector
[SerilaizeField] private Transform player;

// As fallback get it ONCE on runtime
private void Awake()
{
    if(!player) player = GameObject.FindGameObjectWithTag("Player").transform;
}

void Update()
{
    // actually those wouldn't really need to be fields
    heading = player.position - transform.position;
    distance = heading.magnitude;
    // This line isn't really necessary
    // If something I would use 
    //direction = heading.normalized
    direction = heading / distance;

    var hit = Physics2D.Raycast(transform.position, direction);

    if (hit.collider)
    {
        if (hit.transform == player)
        {
            Debug.DrawRay(transform.position, direction * distance, Color.red);
            Debug.Log("Hit Player");
        }
        else
        {
            Debug.DrawRay(transform.position, direction * distance, Color.yellow);
            Debug.Log("Hit Wall");
        }
    }
    else
    {
        Debug.DrawRay(transform.position, direction * distance, Color.white);
        Debug.Log("Not Hit");
    }
}

稍后您还应该删除所有这些Debug.Log,因为在Update 中完成它们也相当昂贵!

【讨论】:

  • 这个答案并没有解决问题,但有助于找到正确的方向。我将使用更多信息编辑问题。
  • @Pepv 更新了答案;)您不应该将解决方案放入问题中;)
  • 谢谢!如您所见,我并不真正习惯 Stack Overflow ... 作为附加信息:射线与 FollowNPC 的对撞机发生碰撞,我为此找到的解决方案只是为此对象选择“忽略射线投射”层。我还尝试在 Raycast() 上使用蒙版,但没有运气。
猜你喜欢
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-01-14
  • 2015-08-11
  • 1970-01-01
相关资源
最近更新 更多