OnCollisionEnter() не всегда срабатывает.

Общие вопросы о Unity3D

OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 02 июл 2009, 23:25

Собственно проблема:

Есть скрипт стрельбы:
Код: Выделить всё
using UnityEngine;
using System.Collections;

public class shoot : MonoBehaviour {

   Transform Tar_rot;
   GameObject Obj;
   GameObject Bullet;
   int speed;
   float waitTime;
   float curTime;
      
   // Use this for initialization
   void Start () {
      speed=1000;
      waitTime=0.2f;
      curTime=0;
      Tar_rot = GameObject.Find("Main Camera").transform;
      Obj = GameObject.Find("bullet");
      }
   
   // Update is called once per frame
   void Update () {
      if (Input.GetMouseButtonDown(0)) {
            curTime=0;
            GameObject Bullet = (GameObject) Instantiate(Obj, Tar_rot.position, Tar_rot.rotation);
            Bullet.rigidbody.velocity = Tar_rot.TransformDirection(0, 0, speed);
         }
      if (Input.GetMouseButton(0) ) {
            if (curTime<waitTime) {
               curTime=curTime+Time.deltaTime;
            }
            else {
               curTime=0;
               GameObject Bullet = (GameObject) Instantiate(Obj, Tar_rot.position, Tar_rot.rotation);
               Bullet.rigidbody.velocity = Tar_rot.TransformDirection(0, 0, speed);
            }
      }
   }
}

Он висит на оружии.

Есть скрипт убиения пуль:
Код: Выделить всё
using UnityEngine;
using System.Collections;

public class collisions : MonoBehaviour {
   
   void OnCollisionEnter(Collision Info) {
      if (transform.gameObject.name!="bullet") 
         Destroy(transform.gameObject);
      }
   
   void Start () {
   }
   
   // Update is called once per frame
   void FixedUpdate () {
      if  ((transform.position.y<-100)||(transform.position.y>160)||(transform.position.x>1000)||(transform.position.x<-1000)||(transform.position.z>1000)||(transform.position.z<-1000))
         if (transform.gameObject.name!="bullet")
            DestroyImmediate(transform.gameObject);
   }
}

Он висит на пуле. (Проверки имени нужны чтобы не уничтожать пулю-оригинал, которая всегда должна быть на сцене)

Проблема - пули чаще всего без проблем пролетают стены и не умирают, а убивает их уже проверка выхода за мир. Если сделать скорость поменьше, что это уже никакие не пули, но они благополучно убиваются.

Как исправить, т.е. сделать так, чтобы всегда работал детект вхождения в коллизию. Ибо тогда можно будет сделать удобные деколи/частицы.
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 03 июл 2009, 01:02

Ну так они и будут пролетать. Ведь за время прохода FixedUpdate накапливается некая дистанция и нет никакой гарантии, что перемещение "пули" на новую позицию, не переместит её с одной стороны стены на другую.
Для избежания таких накладок, перед перемещением пули, тыркайте вперёд лучом на дистанцию, равную перемещению. Если там что-то есть, то значит, пуля своё отлетала. Делов то. :ymparty:
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 03 июл 2009, 01:20

И лучше всего, верхний скрипт переписать так, чтобы пули создавались в FixedUpdate, а кнопки проверялись именно в Update (иначе можно потерять нажатие).
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 03 июл 2009, 13:10

Поменял скрипт вот на такой:

Код: Выделить всё
using UnityEngine;
using System.Collections;

public class shoot : MonoBehaviour {

   Transform Tar_rot;
   GameObject Obj;
   GameObject Bullet;
   int speed;
   float waitTime;
   float curTime;
   int canShoot;
      
   // Use this for initialization
   void Start () {
      canShoot=0;
      speed=910;
      waitTime=0.2f;
      curTime=0;
      Tar_rot = GameObject.Find("Main Camera").transform;
      Obj = GameObject.Find("bullet");
      }
   
   // Update is called once per frame
   void Update () {
      if (Input.GetMouseButtonDown(0)) {
            curTime=0;
            canShoot=1;
         } else
         if (Input.GetMouseButton(0) ) {
            if (curTime<waitTime) {
               curTime=curTime+Time.deltaTime;
               canShoot=0;
            }
            else {
               curTime=0;
               canShoot=1;
            }
      }
   }
   
   void FixedUpdate() {
      if (canShoot==1) {
            GameObject Bullet = (GameObject) Instantiate(Obj, Tar_rot.position, Tar_rot.rotation);
            Bullet.rigidbody.velocity = Tar_rot.TransformDirection(0, 0, speed);
            canShoot=0;
         }
   }
}


Все равно шарики-снаряды пролетают сквозь множество стен. как так и надо.
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 03 июл 2009, 13:31

Я бы предложил сделать Проект-пример и выложить тут, чтобы можно было "в живую" посмотреть на то, что у вас происходит. :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Mr_Anderson 03 июл 2009, 13:43

Может пригодится код из юнити-вики (переписан на шарп и немного переделан /убрал выбор слоя, вернуть недолго :)/). Здесь можно жестко исключить взаимопроникновение Rigidbody, но если пуль будет много, то надо оптимизировать...

Код: Выделить всё
using UnityEngine;
using System.Collections;

public class WalkThroughProtection : MonoBehaviour
{
    //public LayerMask layerMask; //make sure we aren't in this layer
    float skinWidth = 0.1f; //probably doesn't need to be changed

    float minimumExtent;
    float partialExtent;
    float sqrMinimumExtent;
    Vector3 previousPosition;
    Rigidbody myRigidbody;

    //initialize values
    void Awake()
    {
        myRigidbody = rigidbody;
        previousPosition = myRigidbody.position;
        minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y),
            collider.bounds.extents.z);
        partialExtent = minimumExtent * (1.0f - skinWidth);
        sqrMinimumExtent = minimumExtent * minimumExtent;
    }

    void FixedUpdate()
    {
        //have we moved more than our minimum extent?
        if ((previousPosition - myRigidbody.position).sqrMagnitude > sqrMinimumExtent)
        {
            Vector3 movementThisStep = myRigidbody.position - previousPosition;
            float movementMagnitude = movementThisStep.magnitude;
            RaycastHit hitInfo;

            //check for obstructions we might have missed
            if (Physics.Raycast(previousPosition, movementThisStep, out hitInfo, movementMagnitude,
                1))
            {
                myRigidbody.position = hitInfo.point - (movementThisStep / movementMagnitude) * partialExtent;
            }
        }
        previousPosition = myRigidbody.position;
    }

}
Mr_Anderson
UNIт
 
Сообщения: 143
Зарегистрирован: 16 апр 2009, 13:32

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 03 июл 2009, 13:48

Ну, это собственно и есть вариант, который я предложил выше - проверка лучом каждого "шага" полёта пули.
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 03 июл 2009, 13:53

Кстати, если не нужна "совершенно реальная" физика полёта пули с гравитацией, сопротивлением воздуха и прочим, я бы сменил в вашем коде AddForse на ConstantForse (непомню, как точно пишется). Вероятно, проблемы с "проникновением" решатся. :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 03 июл 2009, 14:14

Хорошо, попробую.
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 03 июл 2009, 17:20

Neodrop писал(а):Кстати, если не нужна "совершенно реальная" физика полёта пули с гравитацией, сопротивлением воздуха и прочим, я бы сменил в вашем коде AddForse на ConstantForse (непомню, как точно пишется). Вероятно, проблемы с "проникновением" решатся. :-?


Констант форса нету, ибо это уже совсем не реальная физика. Есть компонент Constant Forse. Но по сути - запуска пули - один сильный пинок. Сейчас посмотрю и добавлю код выше, с проверкой лучом.

Я думаю послать нафиг реальную физику в смысле полета по параболе. На видимых расстояниях можно считать прямой. И не надо хранить последнюю позицию. Луч можно пускать от начальной точки.
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 03 июл 2009, 17:51

Доп. вопрос - что я должен увидеть используя вот это:

Код: Выделить всё
Debug.DrawRay(hitInfo.point, hitInfo.normal, Color.white);


Если судить по мгновенной смерти шарика при стрельбе в дома - то все работает. (я про срипт от Мистера Андерсона)
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 03 июл 2009, 21:36

Вы должны увидеть белую чёрточку от этой камеры в окне Scene.

А скрипт от mr. Andersona я вам описывал, так что довольно обидно (шутка).
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 03 июл 2009, 23:04

Точек я не замечаю, хотя конечно, я не в то окно смотрю.

Вы мне предлагали свой скрипт написать? Это конечно хорошо, особенно с моим полным отсутствием опыта, но сейчас совсем нет времени. Настолько совсем, что я на неделю передаю проект другому камраду.
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение Neodrop 04 июл 2009, 09:49

Камраду с ещё меньшим опытом? :-?
Добавить neodrop в Skype
Изображение
"Спасибо!" нашему порталу, вы сможете сказать ЗДЕСЬ.
Если проблема не решается честно, нужно её обмануть! || Per stupiditas at Astra!
Страх порождает слабость. Бесстрашных поражают пули.
Протратившись на блядях байтах, на битах не экономят.
Аватара пользователя
Neodrop
Админ
 
Сообщения: 8480
Зарегистрирован: 08 окт 2008, 15:42
Откуда: Питер
Skype: neodrop
  • Сайт

Re: OnCollisionEnter() не всегда срабатывает.

Сообщение wild_r 04 июл 2009, 12:19

Хехе, с Юнити - да, но с большим опытом программирования. Не бойтесь, таких-же тупых вопросов он задавать не будет. Я ему еще тутор вручил...

З.Ы. Можно пример использования Projector для рисования партиклов от пуль?
wild_r
UNITрон
 
Сообщения: 220
Зарегистрирован: 16 апр 2009, 20:46
Откуда: Россия, Санкт - Петербург
  • ICQ

След.

Вернуться в Общие вопросы

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

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