提问者:小点点

有什么方法可以阻止光线通过物体吗?


我正在制作一把格斗枪,如果图层是轻型的,它会将一个物体拉向玩家,如果图层是地面的,它会将玩家拉向物体

            int groundLayer_mask = LayerMask.GetMask("Ground");
            int lightWeightLayer_mask = LayerMask.GetMask("LightWeight");

            //Shoots a raycast, and only works if layer is Ground
            if (Physics.Raycast(Shoulder.transform.position, cam.transform.forward, out raycastHit, float.PositiveInfinity, groundLayer_mask))
            {
                //Hit Something
                debugHitpointTransform.position = raycastHit.point;
                hookshotPosition = raycastHit.point;
                hookShotSize = 0f;
                HookShotTransform.gameObject.SetActive(true);
                HookShotTransform.localScale = Vector3.zero;
                layerHit = 0;

                state = State.HookShotThrown;
            }
            //Shoots a raycast, and only works if layer is LightWeight
            else if (Physics.Raycast(Shoulder.transform.position, cam.transform.forward, out raycastHit, float.PositiveInfinity, lightWeightLayer_mask))
            {
                //Hit Something
                debugHitpointTransform.position = raycastHit.point;
                hookshotPosition = raycastHit.point;
                hookShotSize = 0f;
                HookShotTransform.gameObject.SetActive(true);
                HookShotTransform.localScale = Vector3.zero;
                layerHit = 1;

                state = State.HookShotThrown;
            }

但是如果我朝着一个有地面层的物体的方向看,即使有一个有轻型层的物体比有地面层的物体更近,它也会朝着有地面层的物体看,因为我首先有它的if语句。有没有办法让它不通过前面的对象,只是因为第一个在后面找,或者让它优先考虑前面的一个?


共1个答案

匿名用户

除了layerHit的值外,两个raycast案例基本上都做相同的事情。因此,无论哪种方式,这都是对资源的浪费;)

因此,为了提高效率并实现您想要的效果,只需在图层遮罩中包含两个图层,并对两个图层仅进行一次光线投射-

然后,您仍然可以检查在if块中实际击中了哪一层。

因此,我将在Inspector中公开可配置的字段

// Configure this via the Inspector
// it will be a drop-down from which you can select multiple entries
public LayerMask layers = LayerMask.GetMask("Ground", "LightWeight");

一般来说,我也会使用enum,以获得一些有意义的名称,例如。

public enum HitType
{
    None = -1,
    Ground,
    Lightweight
}

然后使用单个光线投射,如

int groundLayer_mask = LayerMask.NameToLayer("Ground");
int lightWeightLayer_mask = LayerMask.NameToLayer("LightWeight");

var hitType = HitType.None;

if (Physics.Raycast(Shoulder.transform.position, cam.transform.forward, out raycastHit, float.PositiveInfinity, layers))
{
    //Hit Something
    debugHitpointTransform.position = raycastHit.point;
    hookshotPosition = raycastHit.point;
    hookShotSize = 0f;
    HookShotTransform.gameObject.SetActive(true);
    HookShotTransform.localScale = Vector3.zero;

    if(raycastHit.collider.gameObject.layer == groundLayer_mask) hitType = HitType.Ground;
    else if(raycastHit.collider.gameObject.layer == lightWeightLayer_mask) hitType = HitType.Lightweight;

    state = State.HookShotThrown;
}