Войти
UnityФорумПрограммирование

Детектирование попадания в цель холодным оружием (2 стр)

Страницы: 1 2 3 Следующая »
#15
14:42, 12 окт. 2020

Llevellyn
мне кажется, что-то не так с настройкой коллайдера. может лэйермаски не совпадают или что-то еще такое.


#16
14:48, 12 окт. 2020

Llevellyn
Мне кажется, что на картинке лучи вышли из коллайдера, а не зашли в него )
это если они начинаются именно там, где начинаются линии.
unity выход из коллайдера за raycasthit по-умолчанию не считает.

> а куда посылать один сферкаст то?
вот по среднему лучу(на картинке) и можно было бы послать.
но я вижу что игра не плоская, сферкаст может и не прокатить. Стукнется в колено и точка контакта будет не там где надо.
Может boxcast не будет иметь такой проблемы, но вот им я уже не пользовался.

#17
15:16, 12 окт. 2020

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

Kaper
>
> Мне кажется, что на картинке лучи вышли из коллайдера, а не зашли в него )
я пробовал их уже и в обратную сторону посылать, результат не сильно отличается. Разве что осталось сделать их и в ту и в другую сторону, но это уже 20 рейкастов будет)

Еще у меня сложилось такое впечатление, что RaycastNonAlloc в буфер пишет только первый хит, а остальные игнорирует (первый хит это у меня обычно или сам меч, или какая-то часть персонажа что его держит). Буфер я сделал на 5 хитов - RaycastNonAlloc же должен перезаписывать его каждый раз?

#18
(Правка: 16:11) 16:08, 12 окт. 2020

Llevellyn
> RaycastNonAlloc в буфер пишет только первый хит, а остальные игнорирует
т.е. этот метод в твоем случае возвращает единицу? Метод возвращает сколько хитов найдено (и соответственно записано в буффер). я обычно делают буффер очень большим, чтобы исключить возможные проблемы.

#19
19:25, 12 окт. 2020

kkolyan
да, либо 0 либо 1. А буфер у тебя массив или лист?

#20
1:18, 13 окт. 2020

Llevellyn
массив. c листом - это же другой метод, который с аллокациями)

#21
3:01, 13 окт. 2020

kkolyan
если у тебя массив, то он перезаписывается полностью при следующем вызове RaycastNonAlloc, или следующий хит добавляется после предыдущего? Или перезаписываются только хиты, которые при текущем вызове рейкаста получились, а старые остаются? в С# же нет нормальных методов очистки массива?
kkolyan
> c листом - это же другой метод, который с аллокациями)
в документации юнити RaycastAll в примере тоже пишет в массив. Т е в лист они писать не будут, или будут писать только первый хит?

#22
(Правка: 3:34) 3:23, 13 окт. 2020

Llevellyn
RaycastNonAlloc всегда пишет новые хиты начиная с начала переданного массива. И возвращает число записанных в него элементов. Не знаю, очищает ли он массив полностью, но я просто не вижу в этом никакого смысла.

Освежил память докой - там и нет листа нигде, только массивы. Код с List<RaycastInfo> и не скомпилируется ведь даже. Видимо я совсем не понял, что ты имеешь ввиду, говоря про лист.

А не покажешь кусок кода, в котором делается рэйкаст и отрисовка гизмы? Может свежим глазом угляжу какую-нить простецкую ошибку - такое бывает. А то выглядит как полтергейст.

#23
4:21, 13 окт. 2020

kkolyan
> Не знаю, очищает ли он массив полностью, но я просто не вижу в этом никакого
> смысла.
ну так для меня в этом есть смысл - у меня в цикле просматриваются все хиты в массиве (после каждого рейкаста) и сравнивается их collider.transform.root с таковым у меча, и отбрасываются совпадающие (т к эти хиты - это попадание в сам меч или в персонажа, держащего меч). Если рейкаст забьет к примеру буфер десятью такими хитами, то они будут просматриваться в цикле 10 раз за кадр всю оставшуюся игру(если 10 рейкастов посылать), при том что толку от этого никакого :) . Поэтому хочется обнулять буфер с хитами после каждого рейкаста.

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

> А не покажешь кусок кода, в котором делается рэйкаст и отрисовка гизмы?
Если выкинуть все лишнее, там примерно так:

public float part;
public int raycasts = 10; //сколько рейкастов пускать из лезвия

void Awake(){
part = 1f / raycasts;
}

void LateUpdate(){
for (i = 0; i < raycasts; i++) {
    startveerpos[i] = Vector3.Lerp(laststartpos,nowstartpos,part*i);
    endveerpos [i] =Vector3.Lerp (lastendpos, nowendpos, part*i); 
    Debug.DrawLine (startveerpos[i], endveerpos [i], Color.cyan); //это собственно веер с картинки
    }

//версия на лайнкастах
for (i = 0; i < raycasts; i++) {
        if (Physics.Linecast(startveerpos [i], endveerpos[i], out hit, swordhitmask)){
          if (hit.transform.root != transform.root) {
            SendDamage (hit.collider);
            break;
        }
        }

//версия на рейкастах
  numberOfHits = Physics.RaycastNonAlloc (startveerpos [i], endveerpos[i], hits, blade_length, swordhitmask);
        if (numberOfHits>0)    {
            for (k = 0; k < numberOfHits; k++){            
            if (hits [k].transform.root != transform.root) {              
              SendDamage (hits [k].collider);  
              break;            
            }
          }        
}
}

#24
(Правка: 13:23) 12:47, 13 окт. 2020

Llevellyn

буффер и обновляется после каждого рейкаста. но не весь, а первые N элементов. но мы ведь остальные и не читаем, так зачем движку их занулять? :)

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

по теме: кастую повышенное внимание на второй аргумент в RaycastNonAlloc в твоем примере кода.

#25
15:04, 13 окт. 2020

>
> буффер и обновляется после каждого рейкаста. но не весь, а первые N элементов.
> но мы ведь остальные и не читаем, так зачем движку их занулять? :)
ну ок)

> выходит что мечи входят в маску попадания мечом... чтобы мечом можно было
> остановить мечом меч?
не только остановить, но и сломать например или выбить из рук


>
> по теме: кастую повышенное внимание на второй аргумент в RaycastNonAlloc в
> твоем примере кода.
а что в нем не так? Это же направление, в сторону которого летит рейкаст

#26
15:11, 13 окт. 2020

Llevellyn

> не только остановить, но и сломать например или выбить из рук
крутота)

> Это же направление
тогда кастую внимание на второй аргумент Debug.DrawLine :)

#27
(Правка: 16:41) 16:26, 13 окт. 2020

kkolyan
>
> тогда кастую внимание на второй аргумент Debug.DrawLine :)
Дошло) . Спасибо Колян, без тебя бы до меня еще долго доходило)

теперь RaycastNonAlloc делает то что должен, правда выглядит это не очень (меч уже вошел в персонажа, отскакивает от чего-то там внутри, а потом возвращается обратно). А если сделать "грабли" из рейкастов, торчащие из лезвия меча, то при срабатывании рейкаста меч будет не доходить до коллайдера. Может есть какой-то вариант заставить юнити сгенерить промежуточный кадр анимации (в котором меч касается коллайдера и останавливается)?

#28
20:39, 13 окт. 2020

Llevellyn

> Спасибо Колян
рад помочь!

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

> сгенерить промежуточный кадр анимации (в котором меч касается коллайдера и останавливается)?
по логике, нужно остановить progress анимэйшн контроллера на правильном месте (вычисляемом на основании того, какой из лучей веера сработал) и досрочно включить анимацию возврата меча. но я пока так глубоко в анимации не лазил, не знаю какие там подводные камни.

#29
23:02, 13 окт. 2020

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

kkolyan
> нужно остановить progress анимэйшн контроллера на правильном месте (вычисляемом
> на основании того, какой из лучей веера сработал)
веер нельзя посылать в будущее, потому что неизвестно где в следующем кадре будет меч. Веер делается из лерпа между положением меча в прошлом и текущем кадре.
>и досрочно включить анимацию возврата меча.
у меня просто скорость проигрывания анимации умножается на -1 )
> но я пока так глубоко в анимации не лазил, не знаю какие там подводные камни.
юнитевский аниматор - это такая "вещь в себе", с ней вообще мало что можно сделать и инфы из нее не получить никакой. Я сейчас думаю в сторону того что надо блендить кадр с попаданием мечом и предыдущий, а коэффициент блендинга вычислять по скорости движения меча и расстоянию между хитом и мечом.

Страницы: 1 2 3 Следующая »
UnityФорумПрограммирование