使用光线投射防止破折号穿过墙壁

Posted

技术标签:

【中文标题】使用光线投射防止破折号穿过墙壁【英文标题】:Preventing dash from going through walls using raycast 【发布时间】:2021-08-05 10:35:28 【问题描述】:

目前,我想在统一的 2D 游戏中为玩家制作冲刺。我正在使用玩家左右两侧的游戏对象来使用光线投射来检查某个区域与墙壁的距离。如果它离墙太近,我需要它只冲刺那个距离(到墙)而不是整个距离(在墙后面/穿过墙)。

这是我在玩家运动中冲刺的代码(DashCheckLeft 距离玩家 -0.5)(DashCheckRight 距离玩家 0.5):

    public float dashDistance = 3f;
    float distance;
    public Transform DashCheckLeft;
    public Transform DashCheckRight;

 private void Update() 
        if(Input.GetKeyDown(KeyCode.LeftShift)) 
            Debug.Log("Dashed");
            Dash();

 private void FixedUpdate()        
        RaycastHit2D hitLeft = Physics2D.Raycast(DashCheckLeft.position, Vector2.left, -dashDistance);
        RaycastHit2D hitRight = Physics2D.Raycast(DashCheckRight.position, Vector2.right, dashDistance);
        if(hitLeft.collider != null) 
            distance = Mathf.Abs(hitLeft.point.x - transform.position.x);
        
        else if(hitRight.collider != null) 
            distance = Mathf.Abs(hitRight.point.x - transform.position.x);
        
        else 
            distance = dashDistance;
        
    
 private void Dash() 
        rb.position = new Vector2(rb.position.x + distance, rb.position.y);
        

现在的问题是,显然我只是在缩短玩家和 DashChecks (0.5f) 之间的距离,而不是预期的 3f,我相信这可能是因为光线投射以某种方式击中了玩家的对撞机,但是将我的播放器更改为“Ignore Raycast”层会使其掉到地板上,也不能解决问题。

【问题讨论】:

【参考方案1】:

我解决了这个问题,并找到了答案。基本上,您的光线投射也检测到了玩家的对撞机。有一个简单的解决方法。您应该只将第四个参数添加到您的光线投射中。第四个参数是一个LayerMask。 LayerMask 就像一个标签,但您可以同时打开多个。这就是我将代码更改为的内容(我也做了一些额外的调整):

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour

    Rigidbody2D rb;
    public float dashDistance = 3f;
    public LayerMask floor;
    float distance;

    private void Start()
    
        rb = GetComponent<Rigidbody2D>();
    

    private void Update()
    
        if (Input.GetKeyDown(KeyCode.LeftShift))
        
            RaycastHit2D left = Physics2D.Raycast(transform.position, -transform.right, dashDistance, floor);
            RaycastHit2D right = Physics2D.Raycast(transform.position, transform.right, dashDistance, floor);
            if (left.collider != null)
            
                print("left");
                distance = Mathf.Abs(left.point.x - transform.position.x);
                distance = -distance;
            
            else if (right.collider != null)
            
                print("right");
                distance = Mathf.Abs(right.point.x - transform.position.x);
            
            else
            
                distance = dashDistance;
            
            print(distance);

            Debug.Log("Dashed");
            Dash();
        
        void Dash()
        
            rb.position = new Vector2(rb.position.x + distance, rb.position.y);
        
    

(当我说“世界对象”时,我指的是构成地形的对象。例如地面或树木)您应该通过单击世界对象来添加一个新图层。然后,您应该查看检查器的顶部,然后单击“图层Default”下拉菜单,然后单击“添加图层...”按钮。然后在该列表上写一个新名称。返回世界游戏对象,然后单击相同的下拉菜单,然后选择您想要的世界层。您应该确保所有世界对象都具有同一层。回到播放器对象,在检查器中,将“地板”变量设置为与世界相同的图层。如果这没有意义,这里有一个link 说明如何设置图层。

【讨论】:

要么接受答案,要么关闭问题,向其他开发人员发出信号,表明问题已解决。

以上是关于使用光线投射防止破折号穿过墙壁的主要内容,如果未能解决你的问题,请参考以下文章

用于游戏开发和其他目的的光线投射教程

用于游戏开发和其他目的的光线投射教程

有啥办法可以阻止光线投射穿过物体?

Java 游戏引擎:光线投射的墙壁是空心的、破碎的,看起来像粪便

如何防止刚体穿过其他对撞机

VRay材质基础