Top.Mail.Ru
Ответы

Исправление кода на C# для Unity. Physics Raycasting

У меня есть скрипт в Юнити, который служит для открытия двери при помощи анимаций. Проблема такая: луч, при помощи которого я открываю дверь проходит сквозь объекты. Подскажите пожалуйста, как это можно исправить.


Код:
using System.Collections;
using UnityEngine;

public class Opener : MonoBehaviour
{
[SerializeField] private Animator anim;
[SerializeField] private LayerMask Layer;
[SerializeField] private float distance;
[SerializeField] private GameObject cam;
bool open=false;
void Start()
{
anim = GetComponent<Animator>();
}

void Update()
{
RaycastHit hit;
Ray ray = new Ray(cam.transform.position, cam.transform.forward);
if (Physics.Raycast(ray, out hit, distance, Layer))
{
if(Input.GetMouseButtonDown(0) && open==false)
{
anim.SetBool("is_open",true);
open = true;
}
else if(Input.GetMouseButtonDown(0) && open==true)
{
anim.SetBool("is_open",false);
open = false;
}
}
}
}

По дате
По рейтингу
Аватар пользователя
Новичок
2мес

Проблема в том, что ты не проверяешь, что именно попало под луч.

12345678
 if (Physics.Raycast(ray, out hit, distance, Layer)) 
{
    // Проверь, что hit.collider принадлежит нужному объекту
    if (hit.collider.gameObject == gameObject) // или более сложное условие
    {
        // Дальше твой код с анимацией
    }
} 



Еще вариант - используй Physics.RaycastAll и перебирай все попавшие объекты, выбирая ближайший с нужным Layer.

Удаленный ответ Ответ удалён
Аватар пользователя
Мастер
2мес

вот чо выдал передовой ии: Проблема в том, что ваш луч проходит сквозь другие объекты из-за неправильной настройки LayerMask. Вот исправленный код с пояснениями:


1234567891011121314151617181920212223242526272829
 using UnityEngine; 
 
public class Opener : MonoBehaviour  
{  
    [SerializeField] private Animator anim;  
    [SerializeField] private LayerMask interactableLayer; // Переименовал для ясности 
    [SerializeField] private float distance = 3f; // Добавил значение по умолчанию 
    [SerializeField] private Camera cam; // Лучше использовать тип Camera 
     
    private bool isOpen = false;  
 
    void Update()  
    {  
        Ray ray = new Ray(cam.transform.position, cam.transform.forward); 
         
        if (Physics.Raycast(ray, out RaycastHit hit, distance, interactableLayer)) 
        { 
            // Проверяем, что попали именно в этот объект 
            if (hit.collider.gameObject == gameObject)  
            { 
                if (Input.GetMouseButtonDown(0)) 
                { 
                    isOpen = !isOpen; 
                    anim.SetBool("is_open", isOpen); 
                } 
            } 
        } 
    } 
} 


Ключевые исправления:

Проверка hit.collider.gameObject == gameObject - убеждаемся, что луч попал именно в нашу дверь

interactableLayer должен включать только слой, на котором находится дверь

Упрощена логика открытия/закрытия (используется переключение состояния)

Настройки в Unity:

Выделите дверь в сцене

В инспекторе задайте ей отдельный слой (например, "Door")

В компоненте скрипта выберите этот слой в поле interactableLayer

Теперь луч будет реагировать только на саму дверь и не будет проходить сквозь другие объекты.