Top.Mail.Ru
Ответы

Raycast в Unity3D

Я сделал скрипт, который при наведении на переключатель и нажатии левой кнопки мыши отслеживал коллайдер и включал свет, но я столкнулся с проблемой, что я могу нажать на сам переключатель сквозь стены и любые объекты. Такая же проблема у меня со всеми объектами на которых есть raycast, он тупо игнорирует препятствие и я могу подобрать или использовать предметы сквозь объекты, хелп


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

public class SOCKET : MonoBehaviour
{
public Light _light;
public GameObject _hand;
public GameObject soundSwitch;
private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

RaycastHit hit;

if (GetComponent<Collider>().Raycast(ray, out hit, 2f))
{
_hand.SetActive(true);
}
else
{
_hand.SetActive(false);
}


if (GetComponent<Collider>().Raycast(ray, out hit, 2f) && Input.GetMouseButtonDown(0))
{
if (_light.enabled == false)
{
_light.enabled = true;
soundSwitch.GetComponent<AudioSource>().Play(); ;
}
else if (_light.enabled == true)
{
_light.enabled = false;
soundSwitch.GetComponent<AudioSource>().Play();
}
}
}
}

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

Проблема заключается в том, что вы используете `Raycast` только на коллайдере объекта, игнорируя препятствия. Вместо этого, используйте `Physics.Raycast`, чтобы учитывать все объекты на пути луча. Исправленный код:

```csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SOCKET : MonoBehaviour
{
public Light _light;
public GameObject _hand;
public GameObject soundSwitch;

private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;

// Используйте Physics.Raycast вместо GetComponent<Collider>().Raycast
if (Physics.Raycast(ray, out hit, 2f))
{
if (hit.collider == GetComponent<Collider>())
{
_hand.SetActive(true);

if (Input.GetMouseButtonDown(0))
{
_light.enabled = !_light.enabled;
soundSwitch.GetComponent<AudioSource>().Play();
}
}
else
{
_hand.SetActive(false);
}
}
else
{
_hand.SetActive(false);
}
}
}
```

Теперь `Raycast` проверяет, не пересекается ли луч с другими объектами до вашего переключателя, и включение света срабатывает только при наведении непосредственно на него.

Аватар пользователя
11мес

Проблема, с которой вы столкнулись, связана с тем, что метод GetComponent<Collider>().Raycast не учитывает другие коллайдеры на пути луча. Вместо этого, вам нужно использовать метод Physics.Raycast, который позволяет учитывать все коллайдеры на пути луча и возвращает информацию о первом столкнувшемся коллайдере.

Вот как можно изменить ваш скрипт, чтобы использовать Physics.Raycast:

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
 using System.Collections; 
using System.Collections.Generic; 
using UnityEngine; 
 
public class SOCKET : MonoBehaviour 
{ 
    public Light _light; 
    public GameObject _hand; 
    public GameObject soundSwitch; 
 
    private void Update() 
    { 
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
        RaycastHit hit; 
 
        if (Physics.Raycast(ray, out hit, Mathf.Infinity)) 
        { 
            if (hit.collider.gameObject == gameObject) 
            { 
                _hand.SetActive(true); 
 
                if (Input.GetMouseButtonDown(0)) 
                { 
                    if (_light.enabled == false) 
                    { 
                        _light.enabled = true; 
                        soundSwitch.GetComponent<AudioSource>().Play(); 
                    } 
                    else if (_light.enabled == true) 
                    { 
                        _light.enabled = false; 
                        soundSwitch.GetComponent<AudioSource>().Play(); 
                    } 
                } 
            } 
            else 
            { 
                _hand.SetActive(false); 
            } 
        } 
        else 
        { 
            _hand.SetActive(false); 
        } 
    } 
} 

В этом коде:

Physics.Raycast(ray, out hit, Mathf.Infinity) используется для отправки луча и получения информации о первом столкнувшемся коллайдере. Mathf.Infinity указывает, что луч может проходить бесконечно далеко.

Проверяется, является ли столкнувшийся объект тем же объектом, к которому прикреплен скрипт (hit.collider.gameObject == gameObject).

Если объект совпадает, то активируется рука и обрабатывается нажатие кнопки мыши для включения/выключения света.

Таким образом, луч будет учитывать все коллайдеры на своем пути и не пройдет сквозь препятствия.