Unity C# 检测上面的所有游戏对象
Unity C# Detect all game objects above
我希望我的播放器检测第 8 层中的所有游戏对象。我找到了一个检测上面所有游戏对象的代码,但它只是在 x=0 线上检测,就像这些图中一样,
What It does
What I want
RaycastHit[] hitsUp = Physics.RaycastAll(transform.position, transform.up, distance);
RaycastHit[] hitsDown = Physics.RaycastAll(transform.position, -transform.up, distance);
foreach (RaycastHit hit in hitsUp)
{
if (hit.collider.gameObject.layer == 8)
{
Physics.IgnoreCollision(hit.collider, GetComponent<Collider>());
}
}
foreach (RaycastHit hit in hitsDown)
{
if (hit.collider.gameObject.layer == 8)
{
Physics.IgnoreCollision(hit.collider, GetComponent<Collider>(), false);
}
}
我该如何解决这个问题?感谢您的回复。
只需将图层蒙版滤镜添加到您的 Raycast 中即可。
int layerMask = 1 << 8; // - detects raycasts only on 8 layer
RaycastHit[] hitsUp = Physics2D.Raycast(transform.position, transform.up, distance, layerMask);
RaycastHit[] hitsDown = Physics.RaycastAll(transform.position, -transform.up, distance, layerMask);
foreach
不需要。
问题是你的 Raycast 只捕获玩家正上方的“命中”,因为它沿着一条直线。
您可以将所有游戏对象放在一个父对象中,然后遍历每个游戏对象,检查其层,然后检查它是在您的上方还是下方
类似这样的方法可行:
public Transform parent;
private Collider myCollider;
private void Start()
{
myCollider = GetComponent<Collider>();
}
private void DetectObjects()
{
//Loop through each object above/below
foreach (Transform child in parent)
{
GameObject childObj = child.gameObject;
if (childObj.layer == 8) //Is the object on the correct layer?
{
if (child.position.y > transform.position.y) Physics.IgnoreCollision(childObj.GetComponent<Collider>(), myCollider); //GameObjects above the player
else if (child.position.y < transform.position.y) Physics.IgnoreCollision(childObj.GetComponent<Collider>(), myCollider, false); //GameObjects below the player
}
}
}
此外,您应该尝试存储 Collider 组件而不是使用 GetComponent<>()
,因为它非常慢。
根据对象是否created/deleted,您也可以为它们存储碰撞器,这将大大提高代码的性能,例如:
public Transform parent;
private Collider myCollider;
private Collider[] objColliders;
private void Start()
{
myCollider = GetComponent<Collider>();
//If any gameObject is inactive it can also be grabbed by adding true as a paramater
objColliders = parent.GetComponentsInChildren<Collider>();
}
private void DetectObjects()
{
GameObject childObj;
//Loop through colliders
for (int i = 0; i < objColliders.Length; i++)
{
childObj = objColliders[i].gameObject; //Store as gameObject reference
if (childObj.layer == 8)
{
if (childObj.transform.position.y > transform.position.y) Physics.IgnoreCollision(objColliders[i], myCollider); //GameObjects above the player
else if (childObj.transform.position.y < transform.position.y) Physics.IgnoreCollision(objColliders[i], myCollider, false); //GameObjects below the player
}
}
}
我希望我的播放器检测第 8 层中的所有游戏对象。我找到了一个检测上面所有游戏对象的代码,但它只是在 x=0 线上检测,就像这些图中一样,
What It does
What I want
RaycastHit[] hitsUp = Physics.RaycastAll(transform.position, transform.up, distance);
RaycastHit[] hitsDown = Physics.RaycastAll(transform.position, -transform.up, distance);
foreach (RaycastHit hit in hitsUp)
{
if (hit.collider.gameObject.layer == 8)
{
Physics.IgnoreCollision(hit.collider, GetComponent<Collider>());
}
}
foreach (RaycastHit hit in hitsDown)
{
if (hit.collider.gameObject.layer == 8)
{
Physics.IgnoreCollision(hit.collider, GetComponent<Collider>(), false);
}
}
我该如何解决这个问题?感谢您的回复。
只需将图层蒙版滤镜添加到您的 Raycast 中即可。
int layerMask = 1 << 8; // - detects raycasts only on 8 layer
RaycastHit[] hitsUp = Physics2D.Raycast(transform.position, transform.up, distance, layerMask);
RaycastHit[] hitsDown = Physics.RaycastAll(transform.position, -transform.up, distance, layerMask);
foreach
不需要。
问题是你的 Raycast 只捕获玩家正上方的“命中”,因为它沿着一条直线。
您可以将所有游戏对象放在一个父对象中,然后遍历每个游戏对象,检查其层,然后检查它是在您的上方还是下方
类似这样的方法可行:
public Transform parent;
private Collider myCollider;
private void Start()
{
myCollider = GetComponent<Collider>();
}
private void DetectObjects()
{
//Loop through each object above/below
foreach (Transform child in parent)
{
GameObject childObj = child.gameObject;
if (childObj.layer == 8) //Is the object on the correct layer?
{
if (child.position.y > transform.position.y) Physics.IgnoreCollision(childObj.GetComponent<Collider>(), myCollider); //GameObjects above the player
else if (child.position.y < transform.position.y) Physics.IgnoreCollision(childObj.GetComponent<Collider>(), myCollider, false); //GameObjects below the player
}
}
}
此外,您应该尝试存储 Collider 组件而不是使用 GetComponent<>()
,因为它非常慢。
根据对象是否created/deleted,您也可以为它们存储碰撞器,这将大大提高代码的性能,例如:
public Transform parent;
private Collider myCollider;
private Collider[] objColliders;
private void Start()
{
myCollider = GetComponent<Collider>();
//If any gameObject is inactive it can also be grabbed by adding true as a paramater
objColliders = parent.GetComponentsInChildren<Collider>();
}
private void DetectObjects()
{
GameObject childObj;
//Loop through colliders
for (int i = 0; i < objColliders.Length; i++)
{
childObj = objColliders[i].gameObject; //Store as gameObject reference
if (childObj.layer == 8)
{
if (childObj.transform.position.y > transform.position.y) Physics.IgnoreCollision(objColliders[i], myCollider); //GameObjects above the player
else if (childObj.transform.position.y < transform.position.y) Physics.IgnoreCollision(objColliders[i], myCollider, false); //GameObjects below the player
}
}
}