使用Raycasts和for循环制作视场(使用Unity C#)

时间:2019-01-09 02:43:23

标签: c# for-loop unity3d raycasting fieldofview

代码:

        void IdleState ()
    {
    RaycastHit hit;

    for (float i = -ViewWidth; i < ViewWidth; i++)
        { 
            float Iterater = i/20;
            if (Physics.Raycast(transform.position, transform.forward + new Vector3(Iterater,0,0), out hit, ViewRange))
             {
                Debug.DrawRay(transform.position,(transform.forward + new Vector3(Iterater,0,0)).normalized * ViewRange, Color.red);
                if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Player"))
                 {
                    FoundPlayer(hit.transform);
                 }
             }
        }

}

问题:在Unity中,我试图通过绘制带有for循环的多个射线广播来为敌方AI创建视野。由于某些原因,射线广播会这样做: that gif

几天来我一直在尝试解决此问题,请帮忙!

如果需要,还可以使用FoundPlayer()函数:

void FoundPlayer  (Transform DetectedObject)
    { 
        float step = TurnSpeed * Time.deltaTime;
        Vector3 Direc = DetectedObject.position - transform.position;
        Vector3 RotMath = Vector3.RotateTowards(transform.forward, Direc,step,0.0f);
        transform.rotation = Quaternion.LookRotation(RotMath);
        Vector3 CurrentRot = transform.eulerAngles;
        transform.rotation = Quaternion.Euler(0,CurrentRot.y,0);
    }

当其中一个射线投射击中敌人时,FoundPlayer()函数会将敌人旋转到玩家身上。

1 个答案:

答案 0 :(得分:2)

关于Raycast:

transform.Forward在世界空间坐标中,向其中添加世界空间X轴偏移量的一部分。您想要添加一些“局部空间” X轴。 transform.Right是局部空间X轴的世界空间转换。试试:

var rayDirection = (transform.Forward + (Vector3.Scale(transform.Right, new Vector3(Iterater, 0, 0))).normalized;

关于视野:

如果您要做的只是检查FOV中有哪些物体,请开始查找球体内的所有物体,然后将这些物体过滤到transform.forward合适的角度之内:

float ViewRange = 10;
float hHalfFov = 45; // Horizontal Half-Field of View (Degrees)
float vHalfFov = 45; // Vertical Half-Field of View (Degrees)

void IdleState() {

    // Find all colliders within ViewRange
    var hits = Physics.OverlapSphere(transform.position, ViewRange);

    foreach (var hit in hits) {
        if ( hit.gameObject == this.gameObject ) continue; // don't hit self

        // Check FOV
        var direction = (transform.position - hit.transform.position);
        var hDirn = Vector3.ProjectOnPlane(direction, transform.up).normalized; // Project onto transform-relative XY plane to check hFov
        var vDirn = Vector3.ProjectOnPlane(direction, transform.right).normalized; // Project onto transform-relative YZ plane to check vFov

        var hOffset = Vector3.Dot(hDirn, transform.forward) * Mathf.Rad2Deg; // Calculate horizontal angular offset in Degrees
        var vOffset = Vector3.Dot(vDirn, transform.forward) * Mathf.Rad2Deg; // Calculate vertical angular offset in Degrees

        if (hOffset > hHalfFov || vOffset > vHalfFov) continue; // Outside of FOV

        Debug.DrawLine(transform.position, hit.transform.position, Color.red);

        if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Player")) {
            FoundPlayer(hit.transform);
        }
    }
}