Physics2D.Raycast работает с некоторыми объектами, но не работает с другими - PullRequest
1 голос
/ 01 августа 2020

Итак, я пытаюсь сделать клон Super Mario Bros для практики. Я создавал мир 1-1. Все работало отлично: я мог двигаться, враги могли двигаться и быть убитыми, а блоки можно было взаимодействовать, как и ожидалось. Но в то время я использовал коллайдеры, и они вызывали некоторые проблемы здесь и там, также я не мог найти способ заставить врагов двигаться в противоположном направлении, когда они сталкиваются с коллайдером. Я посмотрел на некоторых других людей и увидел, что они используют raycasting. Потом решил попробовать сам. Не было проблем с вражеским скриптом.

Enemy Script

private void RayCast()
{
    // Getting the max distance by using the size of the collider and creating the ray itself
    float rayMaxDistance = GetComponent<BoxCollider2D>().bounds.size.x/2;
    Ray2D ray = new Ray2D(transform.position, Vector2.right);
    
    // This way ray will be casted in the direction the enemy goes.
    if (rb.velocity.x > 0)
    {
        RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, rayMaxDistance);

        if (hit.collider != null)
        {
            if (hit.collider.gameObject.tag != "Player")
            {
                // Moving in the opposite direction
                rb.velocity = Vector2.zero;
                rb.AddForce(-movementVector, ForceMode2D.Impulse);
            }
        }
        //Debug.DrawRay(ray.origin, ray.direction, Color.red);
        
    }
    // This way ray will be casted in the direction the enemy goes.
    else if (rb.velocity.x < 0)
    {
        ray.direction = Vector3.left;
        RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, rayMaxDistance);

        if (hit.collider != null)
        {
            if (hit.collider.gameObject.tag != "Player")
            {
                // Moving in the opposite direction
                rb.velocity = Vector2.zero;
                rb.AddForce(movementVector, ForceMode2D.Impulse);
            }
        }
        //Debug.DrawRay(ray.origin, ray.direction, Color.red);

Он работал, как и предполагалось, но когда я попытался использовать его на Марио, это не помогло. t работает как-то.

Часть в сценарии персонажа. (Он не завершен, потому что он даже не работает сейчас)

private void ActivateLuckyBlock()
{
    float maxRayDistance = GetComponent<BoxCollider2D>().bounds.size.y/2;
    Ray2D ray = new Ray2D(transform.position, Vector2.up);

    RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, maxRayDistance);

    if (hit.collider != null)
    {
        Debug.Log("There is something");  
    }
}
  • Этот код выводит «Что-то есть», даже если над плеером ничего нет. Значит, он никогда не возвращает null, это должно означать, что он что-то попадает каждый раз, верно? .
  • Я протестировал несколько расстояний, включая бесконечное.
  • Также проверил, есть ли в сцене что-нибудь, чего я не видел в первую очередь, но не мог найти.
  • Я пробовал вызывать метод как в Update, так и в FixedUpdate; ни один из них не работал должным образом.
  • Происхождение и направление луча также работает при тестировании с помощью Debug.DrawRay ().

Я просматривал inte rnet на предмет любых своего рода ответ, но ничего не мог найти об этом. Я не знаю, что делаю не так. Это даже не полная реализация, просто хотелось потестить. Тем не менее, это не работает. Пожалуйста, помогите мне, прежде чем я go сойду с ума.

1 Ответ

1 голос
/ 01 августа 2020

Источник луча должен быть центром границ и попробуйте добавить немного дополнительного места для maxRayDistance, (bounds.extents равно bounds.size / 2: документация по границам. extension )

float maxRayDistance = GetComponent<BoxCollider2D>().bounds.extents.y + 0.001f;
Ray2D ray = new Ray2D(GetComponent<BoxCollider2D>().bounds.center, Vector2.up);

Попробуйте изменить Debug.Log, это позволит вам узнать, какое имя объекта поражает луч:

Debug.Log("Raycast hit:" + hit.collider.name);

Если вы по-прежнему возникают проблемы, создайте переменную publi c layerMask, создайте и добавьте слой для объекта, который вы хотите преобразовать, по адресу:

RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, maxRayDistance, layerMask);

Вызовите функцию через Update или Fixed Update:

Это должно выглядеть примерно так:

public LayerMask luckyBlockMask;
    void Update()
    {
        ActivateLuckyBlock();
    }
    private void ActivateLuckyBlock()
    {
        float maxRayDistance = GetComponent<BoxCollider2D>().bounds.extents.y + 0.001f;
        Ray2D ray = new Ray2D(GetComponent<BoxCollider2D>().bounds.center, Vector2.up);

        RaycastHit2D hit = Physics2D.Raycast(ray.origin, ray.direction, maxRayDistance,
        luckyBlockMask);

        if (hit.collider != null)
        {
            Debug.Log("Raycast hit:" + hit.collider.name);
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...