Raycast却忽视了自己

时间:2014-07-03 20:48:09

标签: c# unity3d

我想发送一个光线投射,但没有让它与我的播放器发生冲突。

我该怎么做?

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    void Update() {
        Vector3 fwd = transform.TransformDirection(Vector3.forward);
        if (Physics.Raycast(transform.position, fwd, 10))
            //hit something            
    }
}

5 个答案:

答案 0 :(得分:25)

您的问题有几种方法。

1)将你的光线投射到播放器

中 如果光线在其内部开始,

Raycast()将忽略对撞机。让我们说你的玩家是位置(0,0,0)的立方体,比例为(1,1,1)。来自(0,0,0)方向(1,0,0)的光线,即沿x轴的光线不会击中播放器。如果将光线的起始位置移动到(-2,0,0),光线将会击中播放器。

如果您的播放器由多个对撞机组成并且您想要将光线投射到不同的方向,这可能会变得复杂。你可以在脚下射击自己(从头部开始射线):)

2)使用图层

您可以将游戏对象分配给不同的图层。然后,您可以指定图层蒙版并告诉Raycast()您要击中的图层。

可以在manual中找到创建和分配图层的分步教程。如果您按照步骤操作并将第8层设置为播放器图层,则以下代码将忽略播放器图层中的所有对象。

// Bit shift the index of the layer (8) to get a bit mask
int layerMask = 1 << 8;

// This would cast rays only against colliders in layer 8, so we just inverse the mask.
layerMask = ~layerMask;

if (Physics.Raycast(transform.position, fwd, 10, layerMask)) {
    // hit something not in the player layer
}

3)获取与光线相交的所有对撞机

通过使用RaycastAll(),您将获得与光线相交的所有碰撞器的数组。然后你可以理清那些你不想要的东西。

RaycastHit[] allHits;
allHits = Physics.RaycastAll(transform.position, fwd, 10);
foreach (var hit in allHits)
{
    // now filter by tag or name
    if (!hit.transform.tag.equals("Player")) {
        // yeah, we didn't hit something tagged as "Player"
    }
}

答案 1 :(得分:7)

我最近遇到了这个问题。弄清楚这是一个痛苦,但这是一个简单的解决方案。

我发现如果你去编辑 - &gt;项目设置 - &gt; Physics2d并取消选中&#34; Raycasts Start In Colliders&#34;它解决了这个问题。

这使得你不必处理图层(我发现图层是一种非常不切实际的选择性光线投射方式)。它只是忽略了投射光线的游戏对象上的对撞机,所以你可以让多个玩家/敌人的预制件投射光线并互相击打,但不是自己。

答案 2 :(得分:2)

由于某种原因,你可以用比你评论更低的代表'回答',我会在这里发布这个来帮助别人,而不是像@Stefan Hoffmann给出的答案那样评论 这是他的选项列表中#1的扩展......在玩家对撞机中投射光线。

你会遇到层不能工作的情况,例如你的玩家可以“控制”各种物体和不同的时间,你只需要你的演员忽略当前控制的物体,例如图层交换存在问题,您需要光线仅忽略某些对象。

在这种情况下,您可以像往常一样投射光线然后测试它是否击中“玩家”对象...测试此方法取决于您的游戏,要么测试刚体,要么测试其他参考对撞机确定它是否属于玩家对象。

如果是这样,只需将你的ray.orgin更新为ray.point + [你的演员方向] *一些小的偏移量。

你在这里做的是沿着前一条射线所采用的相同路径从玩家的对撞机内投射第二条射线,因此这个光线投射会忽略这个对撞机。

如果您的玩家拥有多个/复合碰撞器,则可以多次执行此操作。请记住,这会增加总投射的成本,因为您投射多个光线基本上逐点指向直到您越过玩家对象。然而,这种方法确实解决了不能依赖于需要通过一些碰撞器投射射线的层的问题。

有用的提示这也可以用作沿着光线获得多个碰撞器的较慢但“有序”的方式,例如在每个碰撞点处,只需将一条新射线向前推,足以在前一个发现的对撞机内。 再慢一点,所以请记住,但它运作良好,如果谨慎使用和简单的结构,它不会比重建你的游戏的物理成本,以适应有时需要投射一些碰撞器。

答案 3 :(得分:0)

从Unity示例中获取此信息。 (http://docs.unity3d.com/ScriptReference/RaycastHit.html

void Update() {
    Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
    RaycastHit hit;
    if (Physics.Raycast(ray, out hit, 100))
        if(!hit.transform.gameObject.tag.equals("Player")){
            // Player NOT hit   
        }
    }
}

然后你需要做的就是给你的玩家&#34;玩家&#34;标签

希望这有帮助

答案 4 :(得分:-5)

您可以使用以下方式触发光线投射:

 if(Physics.Raycast(ray, out hit, distance))
    if(!hit.transform.name.equals("Player"))
       // Do your stuff.

确保播放器GameObject实际上名为播放器。