使用 OnPointerDown() 时忽略某一层
Ignore a certain layer when using OnPointerDown()
在我的 2D 俯视游戏中,我有一个附加到 NPC 的脚本来控制玩家何时点击它们,开始对话。
然而,我决定设计这个的方式是我的播放器上有一个额外的碰撞器,叫做 InteractiveArea
,你只能与该区域内的 NPC 交互。在 Start
我添加:
Physics2D.IgnoreLayerCollision(LayerMask.NameToLayer("InteractiveArea"), LayerMask.NameToLayer("Player"));
确保它不会与我的播放器发生碰撞。
所以,我面临的问题是我的 MousePointer
选择了 InteractiveArea
对撞机,而不是 NPC,所以如果 NPC 在 InteractiveArea
我的方法中不会工作:
public void OnPointerDown(PointerEventData eventData)
{
if (npcManager.currentlyInteractable) //set to true when inside InteractiveArea
{
if (eventData.button == PointerEventData.InputButton.Right)
{
npcManager.Clicked();
}
}
}
有什么方法可以让 InteractiveArea
忽略我的 MousePointer
,就像我在开始时对我的播放器所做的那样?或者也许我使用 InteractiveArea
的整个系统设计不佳,我应该采取其他措施来控制它?这似乎是一个非常简洁的解决方案。
您已经找到了解决此问题的方法,但这不是执行此操作的最佳方法。所以我还是决定回答这个问题:
你不需要使用碰撞器来定义玩家的交互区域和npcManager.currentlyInteractable
的整个实现。
有不同的方法可以在不使用对撞机的情况下做到这一点:
1。检查距离
玩家和 NPC 之间的距离可以在这样互动之前检查:
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
float dist = Vector3.Distance(player.transform.position, transform.position)
if (distance < 2) // player is close enough
{
npcManager.Clicked();
}
}
}
2。检查 Radius
中的 Collider Bounds
Physics2D.OverlapCircleAll
可用于检测玩家对撞机是否与一定半径的圆重叠:
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
Vector2 center = new Vector2(transform.position.x, transform.position.z) // use y component depending on how you setup top-down view
float raduis = 2f;
Collider2D[] collidersInCircle = Physics2D.OverlapCircleAll(center, raduis);
foreach (var collider in collidersInCircle)
{
if(collider.CompareTag("Player")) // player must have appropriate tag
{
npcManager.Clicked();
break;
}
}
}
}
希望这对您有所帮助:)
在我的 2D 俯视游戏中,我有一个附加到 NPC 的脚本来控制玩家何时点击它们,开始对话。
然而,我决定设计这个的方式是我的播放器上有一个额外的碰撞器,叫做 InteractiveArea
,你只能与该区域内的 NPC 交互。在 Start
我添加:
Physics2D.IgnoreLayerCollision(LayerMask.NameToLayer("InteractiveArea"), LayerMask.NameToLayer("Player"));
确保它不会与我的播放器发生碰撞。
所以,我面临的问题是我的 MousePointer
选择了 InteractiveArea
对撞机,而不是 NPC,所以如果 NPC 在 InteractiveArea
我的方法中不会工作:
public void OnPointerDown(PointerEventData eventData)
{
if (npcManager.currentlyInteractable) //set to true when inside InteractiveArea
{
if (eventData.button == PointerEventData.InputButton.Right)
{
npcManager.Clicked();
}
}
}
有什么方法可以让 InteractiveArea
忽略我的 MousePointer
,就像我在开始时对我的播放器所做的那样?或者也许我使用 InteractiveArea
的整个系统设计不佳,我应该采取其他措施来控制它?这似乎是一个非常简洁的解决方案。
您已经找到了解决此问题的方法,但这不是执行此操作的最佳方法。所以我还是决定回答这个问题:
你不需要使用碰撞器来定义玩家的交互区域和npcManager.currentlyInteractable
的整个实现。
有不同的方法可以在不使用对撞机的情况下做到这一点:
1。检查距离
玩家和 NPC 之间的距离可以在这样互动之前检查:
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
float dist = Vector3.Distance(player.transform.position, transform.position)
if (distance < 2) // player is close enough
{
npcManager.Clicked();
}
}
}
2。检查 Radius
中的 Collider BoundsPhysics2D.OverlapCircleAll
可用于检测玩家对撞机是否与一定半径的圆重叠:
public void OnPointerDown(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
Vector2 center = new Vector2(transform.position.x, transform.position.z) // use y component depending on how you setup top-down view
float raduis = 2f;
Collider2D[] collidersInCircle = Physics2D.OverlapCircleAll(center, raduis);
foreach (var collider in collidersInCircle)
{
if(collider.CompareTag("Player")) // player must have appropriate tag
{
npcManager.Clicked();
break;
}
}
}
}
希望这对您有所帮助:)