forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   3D-программирование (http://forum.boolean.name/forumdisplay.php?f=12)
-   -   Скорость юнита (http://forum.boolean.name/showthread.php?t=8371)

karry 24.05.2009 21:42

Скорость юнита
 
Начну новую тему, пожалуй.

Вот допустим у меня юнит двигается со скоростью 5 единиц/секунду, а я ему указываю цель на расстоянии 11 единиц от него. Как остановить юнит в нужной точке ?
Не строить же, в самом деле, дерево из IF-Else, проверяющих расстояние через каждую единицу ?
Можно поставить скорость в зависимость от расстояния, но это изменит начальные условия задачи.

Knightmare 24.05.2009 22:05

Ответ: Скорость юнита
 
Мммм... Дык в чем проблема?
Перемещение изначально равно скорости юнита. Если расстояние до цели меньше чем то, которое проходит юнит за шаг (т.е. скорости юнита), то перемещение ставится равным этому расстоянию. Алгоритм допиливать напильником по желанию, до получения желаемого результата.

karry 24.05.2009 22:09

Ответ: Скорость юнита
 
Цитата:

Мммм... Дык в чем проблема?
В том что я до этого не додумался. :dontknow:

karry 25.05.2009 02:06

Ответ: Скорость юнита
 
Вроде работает...но !
Я пишу так :

Код:

;move mode init
        Select unit01\movemode
        Case 1
                If pickhover<>0
                        If EntityName$(pickhover)="Ground"
                                PositionEntity move_icon,PickedX(),.1,PickedZ()
                                ShowEntity move_icon
                        EndIf
                EndIf
        Case 0
                If unit01\movemode=0 Then HideEntity move_icon
        Case 2
                dis#=EntityDistance#(unit01\pivot,move_icon)
                If unit01\movemode=2 And dis>.5 Then
                        PositionEntity move_icon,unit01\wpx,.01,unit01\wpz
                        PointEntity unit01\pivot,move_icon
                        MoveEntity unit01\pivot,0,0,.5
                Else If dis<=.5 And dis>0 Then
                        MoveEntity unit01\pivot,0,0,dis
                Else If dis=0 Then
                        unit01\movemode=0
                EndIf
        End Select

movemode 0 - юнит стоит на месте.
movemode 1 - состояние выбора точки на земле для помещения waypoint.
movemode 2 - юнит в движении.
move_icon это waypoint, который остается на земле при клике, и к которому идет юнит. Когда юнит достигает цели картинка move_icon должна прятаться.
Большую часть времени юнит точно достигает цели, то есть расстояние между юнитом и целью становится равно нулю. Но иногда что-то сглючивает, и movemode так и остается равным 2, хотя юнит достиг цели. А расстояние от юнита до цели при этом становится равным чему-то вроде 1.190059e-007 и тому подобное.


Кстати, как бы еще заставить юнит поворачиваться к waypoint плавно, а не в один фрейм ?
Я пытался сделать так : припарентил к юниту еще один пивот, pointentity его на waypoint, затем считал его entityyaw в переменную, и хотел использовать разницу между этой переменной и entityyaw самого юнита, но не тут-то было, в большинстве случаев юнит достигает цели и начинает бесконечно кружить на месте...

ABTOMAT 25.05.2009 02:13

Ответ: Скорость юнита
 
Цитата:

Кстати, как бы еще заставить юнит поворачиваться к waypoint плавно, а не в один фрейм ?

karry 25.05.2009 02:22

Ответ: Скорость юнита
 
Для тебя это было буквально вчера - а для меня десять лет назад. :-D

karry 25.05.2009 03:11

Ответ: Скорость юнита
 
В процессе дебага обнаружилось вот что :

-создаю два пивота, один родитель другого.
-на всякий случай присваиваю им одинаковые координаты.
-ни один пивот никуда не повернут, ориентация дефолтная.
-делаю обоим pointentity на один и тот же объект.
-проверяю у обоих пивотов глобальный EntityYaw - и они несовпадают !
Как такое может быть ? И главное - как с этим бороться ?

MiXaeL 25.05.2009 03:41

Ответ: Скорость юнита
 
а координаты тоже глобально присваиваешь?

tormoz 25.05.2009 04:00

Ответ: Скорость юнита
 
Если один припаренчен к другому - нафига оба поворачивать ?
а углы не совпадают, потомучто ты сначала повернул ребенка, а потом родителя.

rr333 25.05.2009 06:35

Ответ: Скорость юнита
 
Кстати, karry, если дистанция между юнитом и целью меньше скорости, то просто обнули скорость и поставь юнит на цель. Тогда
Кружить точно не будет.

Damp 25.05.2009 09:28

Ответ: Скорость юнита
 
Для плавного поворота AlignToVector , но иногда получаются глюки, указываешь ехать назад, а юнит едет вперед.
Причем тоже самое получается если делать PointEntity временного пивота и плавно менять угол юнита до угла этого пивота (почти аналог AlignToVector получается).
Я так думаю глюк начинается с функции EntityYaw(), которая при некоторых углах дает не верные значения.
Моск сломал думая как этого избежать ))

karry 25.05.2009 12:38

Ответ: Скорость юнита
 
Всем спасибо за участие в теме. Теперь будем разбираться...

Michael
Цитата:

а координаты тоже глобально присваиваешь?
В данном случае да.

tormoz
Цитата:

Если один припаренчен к другому - нафига оба поворачивать ?
Ну как...один пивот определяет текущую ориентацию юнита, а второй требуемую. Получается разница углов. Это во-первых.
Во-вторых, первым делается pointentity чайлда, и его entityyaw сразу считывается в переменную.

rr333
Хороший совет.

Damp
Цитата:

Для плавного поворота AlignToVector , но иногда получаются глюки
Хм, у меня глюки случаются в 100% случаев. Поворачивает-то он плавно, автоматом, но угол выдает всегда неверный...то есть он направляет энтити "куда-то в ту сторону", а не на конкретный угол...не знаю почему.

Цитата:

если делать PointEntity временного пивота и плавно менять угол юнита до угла этого пивота
Я именно это и пытался сделать.
Писал так :
Код:

If EntityYaw#(unit01\pivot,1)=ppv_yaw then
moveentity, etc.
else if abs(ppv_yaw-entityyaw#(unit01\pivot,1))>4
turnentity
else turnentity,0,ppv_yaw-entityyaw#(unit01\pivot,1),0

Не работало.
В чем засада ? Вроде логично...

karry 25.05.2009 14:07

Ответ: Скорость юнита
 
Черт, я-то думал что углы поворота в блице как во всех нормальных 3D приложениях, от 0 до 360, а они от 0 до 180 и до -180 !
Вот в чем загвоздка...как же определять в какую сторону юниту поворачиваться если один угол положительный а второй отрицательный ?

SBJoker 25.05.2009 14:49

Ответ: Скорость юнита
 
логично: угол +180, вот тебе и формат 0-360

rr333 25.05.2009 17:22

Ответ: Скорость юнита
 
А может так выйдет глюк с entityyaw исправить:
припарентить пивот сбоку от объекта, и при определении угла определять глобально положение пивота относительно объекта. Т.е. если пивот справа - угол от 0 до 180, если слева - 180 до 360.

NitE 25.05.2009 18:02

Ответ: Скорость юнита
 
не знаю о чем развговор, но глянь это http://forum.boolean.name/showthread...E5%EA%F2%EE%F0

Damp 25.05.2009 19:01

Ответ: Скорость юнита
 
Чтоб не заводить новую тему, о повороте.
Хэлп плиз, что тут не так... ни чего в голову не идет, как этот косяк обойти.
============Copy==============
;чтобы засечь глюк, нужно сразу после загрузки
;кликнуть ровно сзади `юнита`
;а он падла поедет вперд :(
;при втором типе поворота вообще кавардак,
;хотя теоретически должно быть все в елочку
Graphics3D 1024,768,0,1
SetBuffer BackBuffer()

camera=CreateCamera()
PositionEntity camera,0,10,-10
RotateEntity CreateLight (),33,33,0

Global TempPivot=CreatePivot ()

Land=CreatePlane () : EntityColor Land,0,100,0 : EntityPickMode Land,2

Unit=CreateCube () : ScaleEntity Unit,.5,.5,1 : EntityColor Unit,0,0,100

WayPoint=CreateCube () : ScaleEntity WayPoint,.05,1,.05 : EntityColor WayPoint,100,0,0

PointEntity camera,Unit

Trigger=-1

Repeat;======

If MouseHit (1)
CP=CameraPick (camera,MouseX(),MouseY())
If CP
PX%=PickedX()
PZ%=PickedZ()
PositionEntity WayPoint,PX,0,PZ
EndIf
EndIf

d#=EntityDistance(Unit,WayPoint)
If d#>0.1
If Trigger<0
Align1(Unit, WayPoint, 0.15)
Else
Align2(Unit, WayPoint, 0.15)
EndIf
MoveEntity Unit,0,0,0.1
EndIf

If KeyHit (57) Trigger=-1*Trigger ;пробелом

RenderWorld

Rect MouseX(),MouseY(),2,2

If Trigger<0
Text 50,50, "Align1"
Else
Text 50,50, "Align2"
EndIf
Flip
Until KeyHit(1) ;======
End

Function Align1(Entity, WP, AlignRate#)
dx#=EntityX(WP,1) - EntityX(Entity,1)
dz#=EntityZ(WP,1) - EntityZ(Entity,1)
AlignToVector Entity, dx, 0, dz , 3 , AlignRate#
RotateEntity Entity,0,EntityYaw (Entity,1),0,1 ; чтоб не перевернуло, не влияет на баг с поворотом
End Function

Function Align2(Entity, WP, AlignRate#)
PositionEntity TempPivot , EntityX(Entity,1) , 0 , EntityZ(Entity,1),1
PointEntity TempPivot,WP
Yaw#= ( EntityYaw(TempPivot,1) - EntityYaw(Entity,1) ) *AlignRate#
TurnEntity Entity,0,Yaw#,0
End Function
============Past==============

karry 25.05.2009 20:13

Ответ: Скорость юнита
 
Нет, послушайте, это чокнуться можно, два дня уже сижу не могу сделать плавный поворот.

Пробовал через Atan2 - так он только к глобальной системе координат применяется, как его использовать в связке с системой координат юнита - х.з.

Пробовал через DeltaYaw - та же хрень, ну неправильно угол определяется !!!
Вот откопал на форуме кусок кода, HolyDel пишет :
Код:

function smoothturn(ent1,ent2,speed# = 1)
s# = DeltaYaw(ent1,ent2)
turnentity ent1,0,speed * sign(s),0
endfunction

И таки-да, вращается, в нужную сторону, но стоит добавить условие когда он должен остановить вращение - и всё рассыпается.

МЛЯ !!! Мозги кипят.

Damp 27.05.2009 09:25

Ответ: Скорость юнита
 
Нашел способ избавиться от косяка.
Поворот с AlignToVector, но нужно чтоб вэйпоинт менял свое положение в близи своих координат. Причем чем дальше он от юнита, тем сильнее должно быть отклонение, т.е. пропорционально дистанции.
Способ странный, но надежно работает.

karry 27.05.2009 12:15

Ответ: Скорость юнита
 
Я сделал через сравнение Yaw. Примерно 1 раз из 10 глючит, но всё же лучше чем ничего.


Часовой пояс GMT +4, время: 06:45.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot