判断视野范围内是否存在障碍物

public Transform targetPos;

    private void FixedUpdate()
    {
        DrawCheckView(angle, redius);
        //DrawView()

        Vector3 newPos = (targetPos.position - transform.position).normalized;
        newPos = Quaternion.Euler(0, 30, 0) * newPos;
        transform.Translate(newPos * 0.1f);

    }

    public float TriangleArea(float v0x,float v0y,float v1x,float v1y,float v2x,float v2y)
    {
        //Vector2 a1 = new Vector2(v1x - v0x, v1y - v0x);
        //Vector2 a2 = new Vector2(v2x - v0x, v2y - v0y);
        //return Mathf.Abs((a1.x * a2.y - a1.y * a2.x) / 2f);

        //行列式
        return Mathf.Abs((v0x * v1y + v1x * v2y + v2x * v0y - v1x * v0y - v2x * v1y - v0x * v2y) / 2f);
    }
    
    //y=0;
    bool isINTriangle(Vector3 point,Vector3 v0,Vector3 v1,Vector3 v2)
    {
        float x = point.x;
        float y = point.z;

        float v0x = v0.x;
        float v0y = v0.z;

        float v1x = v1.x;
        float v1y = v1.z;

        float v2x = v2.x;
        float v2y = v2.z;

        //current view area
        float t = TriangleArea(v0x, v0y, v1x, v1y, v2x, v2y);
        //点在视野中分割后几部分三角形的面积和
        float a = TriangleArea(v0x, v0y, v1x, v1y, x, y) + TriangleArea(v0x, v0y, x, y, v2x, v2y) + TriangleArea(x, y, v1x, v1y, v2x, v2y);

        if (Mathf.Abs(t - a) <= 0.01f)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    
    void DrawCheckView(float angle,float r)
    {
        //中心位置
        Vector3 center = new Vector3(transform.position.x, 0, transform.position.z);
        //物体超前向量随着物体轴向旋转若干度(Quaternion.Euler(0,90,0)* Vector3.forward//Vector3.forward向量围绕Y轴旋转90度)
        Vector3 f0 = center + transform.rotation * Vector3.forward * r;
        Vector3 f1 = center + Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y - angle, transform.rotation.eulerAngles.z) * Vector3.forward * r;
        Vector3 f2 = center + Quaternion.Euler(transform.rotation.eulerAngles.x, transform.rotation.eulerAngles.y + angle, transform.rotation.eulerAngles.z) * Vector3.forward * r;

        //通过计算面积差来判断一个物体是否在视野中
        if (isINTriangle(targetPos.position, center, f1, f2))
        {
            Debug.Log("在视野范围内");
        }
        else
        {
            Debug.Log("不在视野范围内");
        }
        
        Debug.DrawLine(center, f0, Color.red);
        Debug.DrawLine(center, f1, Color.red);
        Debug.DrawLine(center, f2, Color.red);

        Debug.DrawLine(f1, f2, Color.red);
    }


    void DrawView()
    {
        //中心点位置
        Vector3 center = new Vector3(transform.position.x, 0, transform.position.z);
        //与目标物体之间的距离
        float distance = Vector3.Distance(targetPos.position, transform.position);

        //向左偏移30度
        Quaternion left = transform.rotation * Quaternion.AngleAxis(30, Vector3.down);
        //向右偏移30度
        Quaternion right = transform.rotation * Quaternion.AngleAxis(30, Vector3.up);

        //实际的视野长度
        Vector3 n = center + (Vector3.forward * distance);
        //实际的左视野边界点
        Vector3 leftPoint = left * n;
        //实际的右视野边界点
        Vector3 rightPoint = right * n;


        Debug.DrawLine(center, leftPoint, Color.red);
        Debug.DrawLine(center, rightPoint, Color.red);

        Debug.DrawLine(leftPoint, rightPoint, Color.red);
    }

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值