在Unity中,Raycast 2D跳弹?

问题描述 投票:1回答:1

我是Raycasting的新手,所以我可能会做错事,但我想向游戏对象所面对的方向发送一个射线广播,在它击中的第一个对象上反弹,并在消失前走一段短距离。

据我所知,Unity中没有内置的反射射线广播的功能,所以我一直在尝试在第一个射线广播击中的地方生成另一个射线广播,但我的运气并不好。以下是我目前的做法。

public Gameobject firePoint; // I have an object attached to my main object that I use as a point of origin

void DrawLazer()
{
    Vector2 origin = new Vector2(firePoint.transform.position.x, firePoint.transform.position.y);

        Vector2 direction = transform.TransformDirection(Vector2.up);

        RaycastHit2D hit = Physics2D.Raycast(origin, direction, 10f);
        Debug.DrawLine(origin, direction *10000, Color.black);
        if (hit)
        {
            Debug.Log("Hit: " + hit.collider.name);
            var whatWeHit = new Vector2(hit.transform.position.x, hit.transform.position.y);
            var offset = whatWeHit + hit.point;
            offset.y = 0;

            RaycastHit2D hit2 = Physics2D.Raycast(offset, Vector3.Reflect(direction, hit.normal) * -10000);

            if (hit2)
            {              
                Debug.DrawLine(offset, -Vector3.Reflect(direction, hit.normal) * -10000);
            }
        }
}

我在更新中调用DrawLaxer();。

Current Results

当前的脚本算是能够生成第二个射线广播,然而正如你所看到的,第一个射线广播在击中某个物体时仍然没有停止,更重要的是,虽然这个解决方案在击中水平面上的平面物体时效果不错。但如果它击中垂直或对角线平面上的物体时,它会在错误的轴上进行多次计算。

enter image description here

如果有任何帮助,我将非常感激

unity3d 2d game-physics raycasting
1个回答
0
投票

这里是一个完整的使用Vector2.Reflect和SphereCast的单行为例子。

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

public class ReflectionExample : MonoBehaviour
{

    public GameObject firePoint;

    // Start is called before the first frame update
    void Start()
    {

    }

    // Update is called once per frame
    void Update()
    {
        DrawPredictionDisplay();
    }


    private void DrawPredictionDisplay()
    {

        Vector2 origin = firePoint.transform.position; //unity has a built in type converter that converts vector3 to vector2 by dropping the z component

        Vector2 direction = firePoint.transform.up;

        float radius = 1.0f;

        RaycastHit2D distanceCheck = Physics2D.Raycast(origin, direction);

        RaycastHit2D hit = Physics2D.CircleCast(origin, radius, direction);


        Debug.DrawLine(origin, direction * 10000, UnityEngine.Color.black);
        DrawCircle(origin, 1.0f, UnityEngine.Color.black);

        if (hit)
        {

            origin = hit.point + (hit.normal * radius);
            direction = Vector2.Reflect(direction, hit.normal);

            hit = Physics2D.CircleCast(origin, radius, direction);

            Debug.DrawLine(origin, direction * 10000, UnityEngine.Color.blue);
            DrawCircle(origin, 1.0f, UnityEngine.Color.blue);
        }
    }


    private void DrawCircle(Vector2 center, float radius, UnityEngine.Color color)
    {
        Vector2 prevPoint = new Vector2(Mathf.Sin(0f), Mathf.Cos(0f));

        for (float t = 0.1f; t < 2 * Mathf.PI; t = t + 0.1f)
        {
            var nextPoint = new Vector2(Mathf.Sin(t), Mathf.Cos(t));

            Debug.DrawLine(center + prevPoint, center + nextPoint, color);

            prevPoint = nextPoint;
        }


    }
}
© www.soinside.com 2019 - 2024. All rights reserved.