使用带有 for 循环的 Raycasts 制作视野(使用 Unity C#)
Making Field of view using Raycasts With for loops (Using Unity C#)
代码:
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 创建视野。出于某种原因,光线投射会这样做:
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() 函数只是在其中一条光线投射击中敌人时将其旋转到玩家身上。
关于光线投射:
transform.Forward
在 world-space 坐标中,您可以向其中添加 world-space X 轴偏移的一部分。您想要的是添加 'local-space' X 轴的一部分。 transform.Right
是世界-space 本地-space 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);
}
}
}
代码:
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 创建视野。出于某种原因,光线投射会这样做: 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() 函数只是在其中一条光线投射击中敌人时将其旋转到玩家身上。
关于光线投射:
transform.Forward
在 world-space 坐标中,您可以向其中添加 world-space X 轴偏移的一部分。您想要的是添加 'local-space' X 轴的一部分。 transform.Right
是世界-space 本地-space 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);
}
}
}