Не видит RayCast из другого скрипта

Программирование на Юнити.

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 13:39

samana писал(а):А в _Pistol точно есть все эти свойства - Hit, point?


Синтаксис:
Используется csharp
 public void _Decal()
    {
        Vector3 Direction = RaySpawn.TransformDirection(Vector3.forward + new Vector3(Random.Range(-Spread, Spread), Random.Range(-Spread, Spread), 0));
        Ray ray = new Ray(RaySpawn.position, Direction);
        if (Physics.Raycast(ray, out Hit, 200F))
        {
            if (Hit.collider)
            {
                GameObject dec = Instantiate(DecalPrefab);
                dec.transform.position = Hit.point + Hit.normal * 0.019f;
                dec.transform.rotation = Quaternion.LookRotation(-Hit.normal);
                dec.transform.SetParent(Hit.transform);

                if (Hit.collider.tag == "Sweep")
                {
                    DecalScript = dec.GetComponent<Decal>();
                    DecalScript._Decal();

                }
            }
        }
 
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение samana 05 фев 2017, 14:05

8-} Я совершенно запутался в последовательности выполнения вашего кода, а имена переменных и методов: Decal, _Decal и __Decal запутывают ещё больше @-)

Наверно вам нужно расставить Debug.Log-ов во всех подозрительных местах и проверять значения переменных, чтобы выяснить - имеют ли они те данные, которые вы ожидаете.

p.s.Очень советую вам тщательно выбирать имена, чтобы глядя на код было как можно понятнее - что он делает. Например если вам нужен метод, который делает декаль, то лучше назовите его makeDecal (сделатьДекаль) или createDecal (создатьДекаль).
Если переменная должна хранить GameObject, то имя __Decal не очень подходит, тем более что у вас есть класс с похожим именем. Поэтому лучше назвать например DecalGO, по крайней мере будет понятно, что она хранит какой-то GameObject.
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Не видит RayCast из другого скрипта

Сообщение seaman 05 фев 2017, 14:13

Совет.
Создавать обе декали в одном скрипте - в пистоле. Т.е. вместо этих двух строчек вставить тело _Decal из скрипта Decal (с поправками, естественно)
Синтаксис:
Используется csharp
DecalScript = dec.GetComponent<Decal>();
DecalScript._Decal();

А на декали вообще скриптов не надо.
seaman
Адепт
 
Сообщения: 8352
Зарегистрирован: 24 янв 2011, 12:32
Откуда: Самара

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 14:25

samana писал(а):8-} Я совершенно запутался в последовательности выполнения вашего кода, а имена переменных и методов: Decal, _Decal и __Decal запутывают ещё больше @-)

Наверно вам нужно расставить Debug.Log-ов во всех подозрительных местах и проверять значения переменных, чтобы выяснить - имеют ли они те данные, которые вы ожидаете.

p.s.Очень советую вам тщательно выбирать имена, чтобы глядя на код было как можно понятнее - что он делает. Например если вам нужен метод, который делает декаль, то лучше назовите его makeDecal (сделатьДекаль) или createDecal (создатьДекаль).
Если переменная должна хранить GameObject, то имя __Decal не очень подходит, тем более что у вас есть класс с похожим именем. Поэтому лучше назвать например DecalGO, по крайней мере будет понятно, что она хранит какой-то GameObject.


Переименовал -
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Decal : MonoBehaviour
{
    public Pistol _Pistol;
    public GameObject DecalGO;
    void Start()
    {
        DecalGO = gameObject;
    }
    void Update()
    {

    }

    public void makeDecal()
    {
        RaycastHit Hit_2;

        Ray ray_decal = new Ray(_Pistol.Hit.point + _Pistol.ray.direction * 5, -gameObject.transform.forward);
        Debug.DrawRay(_Pistol.Hit.point, _Pistol.ray.direction * 5, Color.green, 10);
        Debug.Log(_Pistol.Hit.point);
        if (Physics.Raycast(ray_decal, out Hit_2, 3))
        {
            GameObject dec_2 = Instantiate(DecalGO);
            dec_2.transform.position = Hit_2.point + Hit_2.normal * 0.019f;
            dec_2.transform.rotation = Quaternion.LookRotation(-Hit_2.normal);
            dec_2.transform.SetParent(Hit_2.transform);
        }
    }
}
 


Вот данные _Pistol.Hit.point -
Изображение
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 14:45

50VAJJ писал(а):
samana писал(а):8-} Я совершенно запутался в последовательности выполнения вашего кода, а имена переменных и методов: Decal, _Decal и __Decal запутывают ещё больше @-)

Наверно вам нужно расставить Debug.Log-ов во всех подозрительных местах и проверять значения переменных, чтобы выяснить - имеют ли они те данные, которые вы ожидаете.

p.s.Очень советую вам тщательно выбирать имена, чтобы глядя на код было как можно понятнее - что он делает. Например если вам нужен метод, который делает декаль, то лучше назовите его makeDecal (сделатьДекаль) или createDecal (создатьДекаль).
Если переменная должна хранить GameObject, то имя __Decal не очень подходит, тем более что у вас есть класс с похожим именем. Поэтому лучше назвать например DecalGO, по крайней мере будет понятно, что она хранит какой-то GameObject.


Переименовал -
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Decal : MonoBehaviour
{
    public Pistol _Pistol;
    public GameObject DecalGO;
    void Start()
    {
        DecalGO = gameObject;
    }
    void Update()
    {

    }

    public void makeDecal()
    {
        RaycastHit Hit_2;

        Ray ray_decal = new Ray(_Pistol.Hit.point + _Pistol.ray.direction * 5, -gameObject.transform.forward);
        Debug.DrawRay(_Pistol.Hit.point, _Pistol.ray.direction * 5, Color.green, 10);
        Debug.Log(_Pistol.Hit.point);
        if (Physics.Raycast(ray_decal, out Hit_2, 3))
        {
            GameObject dec_2 = Instantiate(DecalGO);
            dec_2.transform.position = Hit_2.point + Hit_2.normal * 0.019f;
            dec_2.transform.rotation = Quaternion.LookRotation(-Hit_2.normal);
            dec_2.transform.SetParent(Hit_2.transform);
        }
    }
}
 


Вот данные _Pistol.Hit.point -
Изображение


Синтаксис:
Используется csharp
public void makeDecal()
    {
        RaycastHit Hit_2;

        Ray ray_decal = new Ray(_Pistol.Hit.point + _Pistol.ray.direction * 5, -gameObject.transform.forward);
        Debug.DrawRay(_Pistol.Hit.point, _Pistol.ray.direction * 5, Color.green, 10);
        if (Physics.Raycast(ray_decal, out Hit_2, 3))
        {
            Debug.Log("true"); // не выводит
            GameObject dec_2 = Instantiate(DecalGO);
            dec_2.transform.position = Hit_2.point + Hit_2.normal * 0.019f;
            dec_2.transform.rotation = Quaternion.LookRotation(-Hit_2.normal);
            dec_2.transform.SetParent(Hit_2.transform);
        }
    }
 


Условие if не происходит
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение samana 05 фев 2017, 15:01

50VAJJ писал(а):Условие if не происходит


Может луч запускается в неправильном направлении или изнутри объекта? А сам луч рисуется правильно?
Попробуйте вместо
Синтаксис:
Используется csharp
-gameObject.transform.forward

установить обратное направление луча
Синтаксис:
Используется csharp
-_Pistol.ray.direction
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 15:09

samana писал(а):
50VAJJ писал(а):Условие if не происходит


Может луч запускается в неправильном направлении или изнутри объекта? А сам луч рисуется правильно?
Попробуйте вместо
Синтаксис:
Используется csharp
-gameObject.transform.forward

установить обратное направление луча
Синтаксис:
Используется csharp
-_Pistol.ray.direction


Неа, и так не работает.
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение samana 05 фев 2017, 15:27

Синтаксис:
Используется csharp
Ray ray_decal = new Ray(_Pistol.Hit.point + _Pistol.ray.direction * 5, -gameObject.transform.forward);

А вы точно уверены в длине луча? Дело в том, что -gameObject.transform.forward создаёт луч с длиной 1, а не бесконечный луч. Может луч просто не достаёт до объекта? Просто попробуйте сделать луч длиннее, умножив его на 10 например.

p.s. кажется я ошибся)
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Не видит RayCast из другого скрипта

Сообщение samana 05 фев 2017, 16:38

Не знаю, поможет ли вам такой пример разобраться, но вдруг поможет.
Код ниже нужно повесить на пистолет. Этот код пускает луч из пистолета на 10 метров по оси Z пистолета и рисует красную и зелёную сферы с обоих сторон соприкосновения луча с любым объектом.

Для проверки лучше создайте новую сцену. Создайте куб - это будет пистолет и несколько любых других объектов по которым пистолет будет стрелять. Повесьте скрипт на пистолет и покрутите его, чтобы направить луч на объекты. Этот скрипт работает в Edit режиме, то-есть не нужно нажимать Play чтобы протестировать.

Синтаксис:
Используется csharp
using UnityEngine;


[ExecuteInEditMode]
public class Pistol : MonoBehaviour
{
    // сюда запомним точки соприкосновения лучей с обоих сторон у объекта
    private Vector3 _frontPointGreen;
    private Vector3 _backPointRed;

    // флаг, который означает что луч столкнулся
    private bool _hitFront;
   
    void Update()
    {
        // создаём луч из центра объекта вдоль его оси Z и рисуем его красным цветом на расстояние 10
        Ray pistolRay = new Ray(transform.position, transform.forward);
        Debug.DrawRay(pistolRay.origin, pistolRay.direction * 10, Color.red);

        // запускаем луч
        RaycastHit hit;
        if (Physics.Raycast(pistolRay, out hit, 10))
        {
            // если луч столкнулся с каким-то объектом, то рисуем зелёный луч до точки соприкосновения
            Debug.DrawRay(pistolRay.origin, pistolRay.direction * hit.distance, Color.green);
            _frontPointGreen = hit.point; // запоминаем точку соприкосновения спереди
            _hitFront = true;

            // запускаем обратный луч, который начинается с конца предыдушего луча
            Ray backRay = new Ray(pistolRay.origin + pistolRay.direction * 10, -pistolRay.direction);
            if (Physics.Raycast(backRay, out hit, 10))
            {
                _backPointRed = hit.point; // запоминаем точку  соприкосновения сзади
            }
        }
        else
        {
            _hitFront = false;
        }
    }

    // для отладки рисуем сферы в местах соприкосновения
    private void OnDrawGizmos()
    {
        if (_hitFront)
        {
            Gizmos.color = Color.green;
            Gizmos.DrawSphere(_frontPointGreen, 0.2f);

            Gizmos.color = Color.red;
            Gizmos.DrawSphere(_backPointRed, 0.2f);
        }
    }
}
 


Изображение
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 16:58

samana писал(а):Не знаю, поможет ли вам такой пример разобраться, но вдруг поможет.
Код ниже нужно повесить на пистолет. Этот код пускает луч из пистолета на 10 метров по оси Z пистолета и рисует красную и зелёную сферы с обоих сторон соприкосновения луча с любым объектом.

Для проверки лучше создайте новую сцену. Создайте куб - это будет пистолет и несколько любых других объектов по которым пистолет будет стрелять. Повесьте скрипт на пистолет и покрутите его, чтобы направить луч на объекты. Этот скрипт работает в Edit режиме, то-есть не нужно нажимать Play чтобы протестировать.

Синтаксис:
Используется csharp
using UnityEngine;


[ExecuteInEditMode]
public class Pistol : MonoBehaviour
{
    // сюда запомним точки соприкосновения лучей с обоих сторон у объекта
    private Vector3 _frontPointGreen;
    private Vector3 _backPointRed;

    // флаг, который означает что луч столкнулся
    private bool _hitFront;
   
    void Update()
    {
        // создаём луч из центра объекта вдоль его оси Z и рисуем его красным цветом на расстояние 10
        Ray pistolRay = new Ray(transform.position, transform.forward);
        Debug.DrawRay(pistolRay.origin, pistolRay.direction * 10, Color.red);

        // запускаем луч
        RaycastHit hit;
        if (Physics.Raycast(pistolRay, out hit, 10))
        {
            // если луч столкнулся с каким-то объектом, то рисуем зелёный луч до точки соприкосновения
            Debug.DrawRay(pistolRay.origin, pistolRay.direction * hit.distance, Color.green);
            _frontPointGreen = hit.point; // запоминаем точку соприкосновения спереди
            _hitFront = true;

            // запускаем обратный луч, который начинается с конца предыдушего луча
            Ray backRay = new Ray(pistolRay.origin + pistolRay.direction * 10, -pistolRay.direction);
            if (Physics.Raycast(backRay, out hit, 10))
            {
                _backPointRed = hit.point; // запоминаем точку  соприкосновения сзади
            }
        }
        else
        {
            _hitFront = false;
        }
    }

    // для отладки рисуем сферы в местах соприкосновения
    private void OnDrawGizmos()
    {
        if (_hitFront)
        {
            Gizmos.color = Color.green;
            Gizmos.DrawSphere(_frontPointGreen, 0.2f);

            Gizmos.color = Color.red;
            Gizmos.DrawSphere(_backPointRed, 0.2f);
        }
    }
}
 


Изображение

Можете прочитать ЛС?
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 19:09

samana писал(а):Не знаю, поможет ли вам такой пример разобраться, но вдруг поможет.
Код ниже нужно повесить на пистолет. Этот код пускает луч из пистолета на 10 метров по оси Z пистолета и рисует красную и зелёную сферы с обоих сторон соприкосновения луча с любым объектом.

Для проверки лучше создайте новую сцену. Создайте куб - это будет пистолет и несколько любых других объектов по которым пистолет будет стрелять. Повесьте скрипт на пистолет и покрутите его, чтобы направить луч на объекты. Этот скрипт работает в Edit режиме, то-есть не нужно нажимать Play чтобы протестировать.

Синтаксис:
Используется csharp
using UnityEngine;


[ExecuteInEditMode]
public class Pistol : MonoBehaviour
{
    // сюда запомним точки соприкосновения лучей с обоих сторон у объекта
    private Vector3 _frontPointGreen;
    private Vector3 _backPointRed;

    // флаг, который означает что луч столкнулся
    private bool _hitFront;
   
    void Update()
    {
        // создаём луч из центра объекта вдоль его оси Z и рисуем его красным цветом на расстояние 10
        Ray pistolRay = new Ray(transform.position, transform.forward);
        Debug.DrawRay(pistolRay.origin, pistolRay.direction * 10, Color.red);

        // запускаем луч
        RaycastHit hit;
        if (Physics.Raycast(pistolRay, out hit, 10))
        {
            // если луч столкнулся с каким-то объектом, то рисуем зелёный луч до точки соприкосновения
            Debug.DrawRay(pistolRay.origin, pistolRay.direction * hit.distance, Color.green);
            _frontPointGreen = hit.point; // запоминаем точку соприкосновения спереди
            _hitFront = true;

            // запускаем обратный луч, который начинается с конца предыдушего луча
            Ray backRay = new Ray(pistolRay.origin + pistolRay.direction * 10, -pistolRay.direction);
            if (Physics.Raycast(backRay, out hit, 10))
            {
                _backPointRed = hit.point; // запоминаем точку  соприкосновения сзади
            }
        }
        else
        {
            _hitFront = false;
        }
    }

    // для отладки рисуем сферы в местах соприкосновения
    private void OnDrawGizmos()
    {
        if (_hitFront)
        {
            Gizmos.color = Color.green;
            Gizmos.DrawSphere(_frontPointGreen, 0.2f);

            Gizmos.color = Color.red;
            Gizmos.DrawSphere(_backPointRed, 0.2f);
        }
    }
}
 


Изображение


Вот что я сделал -
Синтаксис:
Используется csharp
using UnityEngine;


[ExecuteInEditMode]
public class PistolTest : MonoBehaviour
{
    // сюда запомним точки соприкосновения лучей с обоих сторон у объекта
    private Vector3 _frontPointGreen;
    public Vector3 _backPointRed;
    public Decal DecalScript;
    public GameObject DecalGO;
    // флаг, который означает что луч столкнулся
    private bool _hitFront;
    public Ray backRay;

    void Update()
    {
        // создаём луч из центра объекта вдоль его оси Z и рисуем его красным цветом на расстояние 10
        Ray pistolRay = new Ray(transform.position, transform.forward);
        Debug.DrawRay(pistolRay.origin, pistolRay.direction * 10, Color.red);

        // запускаем луч
        RaycastHit hit;
        if (Physics.Raycast(pistolRay, out hit, 10))
        {
            // если луч столкнулся с каким-то объектом, то рисуем зелёный луч до точки соприкосновения
            Debug.DrawRay(pistolRay.origin, pistolRay.direction * hit.distance, Color.green);
            _frontPointGreen = hit.point; // запоминаем точку соприкосновения спереди
            _hitFront = true;
            if (hit.collider)
            {
                GameObject dec = Instantiate(DecalGO);
                dec.transform.position = hit.point + hit.normal * 0.019f;
                dec.transform.rotation = Quaternion.LookRotation(-hit.normal);
                dec.transform.SetParent(hit.transform);

                if (hit.collider.tag == "Sweep")
                {
                    DecalScript = dec.GetComponent<Decal>();
                    DecalScript.makeDecal();

                }
            }
            // запускаем обратный луч, который начинается с конца предыдушего луча
            Ray backRay = new Ray(pistolRay.origin + pistolRay.direction * 10, -pistolRay.direction);
            if (Physics.Raycast(backRay, out hit, 10))
            {
                _backPointRed = hit.point; // запоминаем точку  соприкосновения сзади
            }
        }
        else
        {
            _hitFront = false;
        }
    }

    // для отладки рисуем сферы в местах соприкосновения
    private void OnDrawGizmos()
    {
        if (_hitFront)
        {
            Gizmos.color = Color.green;
            Gizmos.DrawSphere(_frontPointGreen, 0.2f);

            Gizmos.color = Color.red;
            Gizmos.DrawSphere(_backPointRed, 0.2f);
        }
    }
}
 

И декаль -
Синтаксис:
Используется csharp
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Decal : MonoBehaviour
{
    public Pistol _Pistol;
    public PistolTest PistolTest;
    public GameObject DecalGO;
    void Start()
    {
        DecalGO = gameObject;
    }
    void Update()
    {

    }

    public void makeDecal()
    {
        RaycastHit Hit;

        Ray ray_decal = PistolTest.backRay;

        if(Physics.Raycast(PistolTest.backRay, out Hit, 3))
        {
            Debug.Log("true"); // не выводит
            GameObject dec_2 = Instantiate(DecalGO);
            dec_2.transform.position = PistolTest._backPointRed + Hit.normal * 0.019f;
            dec_2.transform.rotation = Quaternion.LookRotation(-Hit.normal);
            dec_2.transform.SetParent(Hit.transform);
        }

        /*
        RaycastHit Hit_2;

        Ray ray_decal = new Ray(_Pistol.Hit.point + _Pistol.ray.direction * 5, -gameObject.transform.forward * 10);
        Debug.DrawRay(_Pistol.Hit.point, _Pistol.ray.direction * 5, Color.green, 10);
        if (Physics.Raycast(ray_decal, out Hit_2, 3))
        {
            Debug.Log("true"); // не выводит
            GameObject dec_2 = Instantiate(DecalGO);
            dec_2.transform.position = Hit_2.point + Hit_2.normal * 0.019f;
            dec_2.transform.rotation = Quaternion.LookRotation(-Hit_2.normal);
            dec_2.transform.SetParent(Hit_2.transform);
        }
        */

    }
}
 

ошибок нет но декали не создаются на обратной стороне объекта
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение samana 05 фев 2017, 19:24

Вы вызываете метод DecalScript.makeDecal() раньше, чем запускаете обратный луч. К тому же ваш луч public Ray backRay не имеет значения, потому что вы в методе makeDecal создаёте новую локальную переменную луча Ray backRay = ..., а не используете переменную класса (public Ray backRay).
Аватара пользователя
samana
Адепт
 
Сообщения: 4738
Зарегистрирован: 21 фев 2015, 13:00
Откуда: Днепропетровск

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 19:43

samana писал(а):Вы вызываете метод DecalScript.makeDecal() раньше, чем запускаете обратный луч. К тому же ваш луч public Ray backRay не имеет значения, потому что вы в методе makeDecal создаёте новую локальную переменную луча Ray backRay = ..., а не используете переменную класса (public Ray backRay).


Может забить на RayCast и делать физическую пулю? Как вы считаете, это будет разумно если карты будут примерно как Counter Strike?
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Re: Не видит RayCast из другого скрипта

Сообщение 50VAJJ 05 фев 2017, 19:45

samana писал(а):Вы вызываете метод DecalScript.makeDecal() раньше, чем запускаете обратный луч. К тому же ваш луч public Ray backRay не имеет значения, потому что вы в методе makeDecal создаёте новую локальную переменную луча Ray backRay = ..., а не используете переменную класса (public Ray backRay).


Все исправил, но не работает.
50VAJJ
UNIт
 
Сообщения: 102
Зарегистрирован: 26 дек 2015, 23:44

Пред.

Вернуться в Скрипты

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex [Bot] и гости: 5