Does anyone have an idea how to make a units turret compensate for
the units turning in order to give the illusion of working independant of it?
What i want is basically a chassis that can move and turn in any direction while the turret stays focussed at the target.
Turret rotating independant from unit chassis?
Moderator: Moderators
Re: Turret rotating independant from unit chassis?
Im not sure I understand the question, since I believe almost all tanks do this in spring.
Re: Turret rotating independant from unit chassis?
I have a turret, i have a chassis.
If the chassis piece turns the turret piece will turn the same in addition to its own turning.
If i now have a fast turning unit with a slow turing turret usually a turn of the vehicle will cause it to loose aim.
What i want now is that the turret works totally independant of the chassis so the chassis may turn in one direction for movement while the turret isn't affected at all, basically like floating over the chassis and not beeing attached to it.
I guess i could work it out if i were to find out how much the unit turned in worldspace and then counterbalance that movement by rotating the turret piece in the other direction.
I reduced my Problem to a simpler one: Can i turn a unit piece by a set angle, for example 90┬░ left without knowing what the result will be?
OR
Can i get a pieces current rotation? Wiki says the function for this is broken...
If the chassis piece turns the turret piece will turn the same in addition to its own turning.
If i now have a fast turning unit with a slow turing turret usually a turn of the vehicle will cause it to loose aim.
What i want now is that the turret works totally independant of the chassis so the chassis may turn in one direction for movement while the turret isn't affected at all, basically like floating over the chassis and not beeing attached to it.
I guess i could work it out if i were to find out how much the unit turned in worldspace and then counterbalance that movement by rotating the turret piece in the other direction.
I reduced my Problem to a simpler one: Can i turn a unit piece by a set angle, for example 90┬░ left without knowing what the result will be?
OR
Can i get a pieces current rotation? Wiki says the function for this is broken...
Re: Turret rotating independant from unit chassis?
real world tanks keep their gun pointed at the target now matter how the chasis rotates or tilts.
ie http://www.youtube.com/watch?v=JTq2D ... page#t=18s
could also be used for hot air ballons that do not rotate when they change direction, radar dishes on vehicles and other stuff.
Something similiar:
I tried to make units aim at units that are in LOS but not in weapon range yet. Because it looks kind of silly if a tank drives towards an enemy without pre-aiming.
Gave them a long range weapon that aims the turret but never fires (or is invisible and does no damage, both work)
Kind of worked but had some problems too...
ie http://www.youtube.com/watch?v=JTq2D ... page#t=18s
i think that should work.Erik wrote:I guess i could work it out if i were to find out how much the unit turned in worldspace and then counterbalance that movement by rotating the turret piece in the other direction.
could also be used for hot air ballons that do not rotate when they change direction, radar dishes on vehicles and other stuff.
Something similiar:
I tried to make units aim at units that are in LOS but not in weapon range yet. Because it looks kind of silly if a tank drives towards an enemy without pre-aiming.
Gave them a long range weapon that aims the turret but never fires (or is invisible and does no damage, both work)
Kind of worked but had some problems too...
Re: Turret rotating independant from unit chassis?
If you are using lua;Can i get a pieces current rotation? Wiki says the function for this is broken...
http://springrts.com/wiki/Animation-LuaCallouts
Spring.UnitScript.GetPieceRotation ( piece ) -> number x, y, z
Re: Turret rotating independant from unit chassis?
gun always aimed "downwards", no matter how chasis rotates:

needs stuff to keep unit from doing that when it is actually aiming but thats just the principle.
was thinking to make it toggleable by on/off button.

Code: Select all
function updateheading()
while (true) do
lastheading = currentheading
currentheading = Spring.GetUnitHeading(unitID)
deltaheading = lastheading - currentheading
Sleep (200)
local _,turretDir,_ = Spring.UnitScript.GetPieceRotation (turret)--pro tip: do this for tilting axis too
deltaheading = deltaheading * math.pi / 32768
Turn (turret, y_axis, (deltaheading+turretDir), math.rad(180))
end
end
was thinking to make it toggleable by on/off button.
Re: Turret rotating independant from unit chassis?
Working solution with one small bug.
Implemented here as a hovercraft unit so the turret is basically the chassis, the unit can move around a target and stay focussed at all times.
For the tank variant replace "chassis" by a centered turret.
Feel free to use it but if you do any improvements please post them.
Implemented here as a hovercraft unit so the turret is basically the chassis, the unit can move around a target and stay focussed at all times.
For the tank variant replace "chassis" by a centered turret.
Feel free to use it but if you do any improvements please post them.
Code: Select all
local chassis = piece "chassis"
local flare1 = piece "flare1"
local SIG_RESTORE=2
local SIG_TURRET=4
local attack_mode=0 --will the unit turn turret along movement or focus on the enemy?
--constant for converting unitheadings to radians
local conversion= 2*3.14159/(2^16)
local attack_heading=conversion*Spring.GetUnitHeading(unitID)
local function restore()
Signal(SIG_RESTORE)
SetSignalMask(SIG_RESTORE)
local unit_dir=0
Sleep(5000)
--slowly restore to original settings
while(true) do
unit_dir=Spring.GetUnitHeading(unitID)
if (attack_heading<0.03+conversion*unit_dir and attack_heading>-0.03+conversion*unit_dir) then
attack_heading=conversion*unit_dir
attack_mode=0
end
--TODO: take into consideration shortest way, as it is now sometimes the
--longer turn is taken making the poor driver pretty sick xD
if attack_heading>=0.03+conversion*unit_dir then attack_heading=attack_heading-0.03 end
if attack_heading<=-0.03+conversion*unit_dir then attack_heading=attack_heading+0.03 end
Sleep(60)
end
end
local function turret()
Signal(SIG_TURRET)
SetSignalMask(SIG_TURRET)
local unit_dir=Spring.GetUnitHeading(unitID)
local diff_dir=0
Sleep(180)
while(true) do
if (attack_mode==1) then
unit_dir=Spring.GetUnitHeading(unitID)
--turn the chassis piece to exactly the needed position
Turn(chassis, y_axis,attack_heading-conversion*unit_dir)
Sleep(30)
end
--normal behaviour when not in combat situation
if (attack_mode==0) then Sleep(30) end
end
end
function script.Create()
StartThread(turret)
end
function script.Killed(recentDamage, maxHealth)
Explode(chassis, SFX.SHATTER)
end
function script.StartMoving ()
Move(chassis, y_axis, 20,9)
end
function script.StopMoving ()
end
function script.AimFromWeapon1()
return flare1
end
function script.QueryWeapon1()
return flare1
end
function script.AimWeapon1( heading, pitch )
Signal(SIG_RESTORE)
Signal(1)
SetSignalMask(1)
attack_mode=1
--aiming animation
local unit_dir=Spring.GetUnitHeading(unitID)
while(true) do
unit_dir=Spring.GetUnitHeading(unitID)
if (attack_heading<0.10+conversion*unit_dir+heading and attack_heading>-0.10+conversion*unit_dir+heading) then
--fire shot !
StartThread(restore)
return true
end
--TODO: take into consideration shortest way, as it is now sometimes the
--longer turn is taken
-- Spring.Echo("attack heading",attack_heading)
-- Spring.Echo("wanted heading",conversion*unit_dir+heading)
if attack_heading>=0.10+conversion*unit_dir+heading then
attack_heading=attack_heading-0.10
end
if attack_heading<=-0.10+conversion*unit_dir+heading then
attack_heading=attack_heading+0.10
end
Sleep(60)
end
--attack_heading=2*3.1415926 --this would be a full circle
StartThread(restore)
return true
end
Re: Turret rotating independant from unit chassis?
cool
2 small things:
Signal(1)
SetSignalMask(1)
why not use the constants here?
In function turret() does the Sleep(180) before the loop have a use?

2 small things:
Signal(1)
SetSignalMask(1)
why not use the constants here?
In function turret() does the Sleep(180) before the loop have a use?
Re: Turret rotating independant from unit chassis?
nope the sleep has no use, mostlikely an artifact of earlier attemts on this.
As for the constant that might aswell be called SIGNAL_AIM or anything.
As for the constant that might aswell be called SIGNAL_AIM or anything.
Re: Turret rotating independant from unit chassis?
Code: Select all
--Define the wheel pieces
local wheel_speed = math.rad(180)
--Define the pieces of the weapon
local chassis = piece "chassis"
local turret = piece "turret"
local guns = piece "guns"
local flare1 = piece "flare1"
local flare2 = piece "flare2"
local active_barrel = 1 --the barrel that the next shot will be fired from
local number_of_barrels = 2 --how many barrel there are in total
local SIG_AIM=1
local SIG_RESTORE=2
local SIG_TURRET=4
--constant for converting unitheadings to radians
local conversion= 2*3.14159/(2^16)
local attack_heading=conversion*Spring.GetUnitHeading(unitID)
local attack_mode=0 --will the unit turn turret along movement or focus on the enemy?
local function restore()
Signal(SIG_RESTORE)
SetSignalMask(SIG_RESTORE)
local unit_dir=0
local turnspeed=0.06 --the speed at which the turett will turn
Sleep(5000)
--slowly restore to original settings
while(true) do
unit_dir=Spring.GetUnitHeading(unitID)
--reduce attack_heading & wanted_heading to a number between 0 and 2*PI
if (attack_heading<0) then
attack_heading=attack_heading+2*3.14159
end
if (attack_heading>2*3.14159) then
attack_heading=attack_heading-2*3.14159
end
local wanted_heading=conversion*unit_dir
if (wanted_heading<0) then
wanted_heading=wanted_heading+2*3.14159
end
if (wanted_heading>2*3.14159) then
wanted_heading=wanted_heading-2*3.14159
end
local dist1=0
local dist2=0
--check if at original position
--calculate distance from desired rotation
dist1=attack_heading-wanted_heading
if (dist1<0) then dist1=-dist1 end
dist2=(2*3.14159-attack_heading)+wanted_heading
if (dist2<0) then dist2=-dist2 end
if (dist1<1.5*turnspeed or dist2<1.5*turnspeed) then
attack_heading=wanted_heading
attack_mode=0 --return to normal mode where turret turns along chassis
end
if attack_heading>wanted_heading then
dist1=attack_heading-wanted_heading
dist2=(2*3.14159-attack_heading)+wanted_heading
if (dist1 >= dist2) then
attack_heading=attack_heading+turnspeed
wanted_heading=-100 --in order not to trigger the 2nd one aswell
end
if (dist1 < dist2) then
attack_heading=attack_heading-turnspeed
wanted_heading=-100 --in order not to trigger the 2nd one aswell
end
end
if attack_heading<wanted_heading then
dist1=wanted_heading-attack_heading
dist2=(2*3.14159-wanted_heading)+attack_heading
if (dist1 >= dist2) then
attack_heading=attack_heading-turnspeed
end
if (dist1 < dist2) then
attack_heading=attack_heading+turnspeed
end
end
Sleep(60)
end
end
local function manageturret()
Signal(SIG_TURRET)
SetSignalMask(SIG_TURRET)
local unit_dir=Spring.GetUnitHeading(unitID)
local diff_dir=0
while(true) do
if (attack_mode==1) then
unit_dir=Spring.GetUnitHeading(unitID)
--turn the turret piece to exactly the needed position
Turn(turret, y_axis,attack_heading-conversion*unit_dir)
Sleep(30)
end
--normal behaviour when not in combat situation
if (attack_mode==0) then Sleep(30) end
end
end
function script.Create()
StartThread(manageturret)
end
----driving animation
function script.StartMoving()
--Turn(guns, x_axis, 0,0.1)
end
function script.StopMoving()
end
----aimining & fire weapon
function script.AimFromWeapon1()
return turret
end
function script.QueryWeapon1()
if (active_barrel == 1) then return flare1 end
if (active_barrel == 2) then return flare2 end
end
function script.AimWeapon1( heading, pitch )
Signal(SIG_RESTORE)
Signal(SIG_AIM)
SetSignalMask(SIG_AIM)
attack_mode=1
Turn(guns, x_axis, -pitch,0.5)
--aiming animation
local turnspeed=0.06 --the speed at which the turett will turn
local unit_dir=Spring.GetUnitHeading(unitID)
while(true) do
unit_dir=Spring.GetUnitHeading(unitID)
--reduce attack_heading & wanted_heading to a number between 0 and 2*PI
if (attack_heading<0) then
attack_heading=attack_heading+2*3.14159
end
if (attack_heading>2*3.14159) then
attack_heading=attack_heading-2*3.14159
end
--Spring.Echo("attack heading",attack_heading)
local wanted_heading=conversion*unit_dir+heading
if (wanted_heading<0) then
wanted_heading=wanted_heading+2*3.14159
end
if (wanted_heading>2*3.14159) then
wanted_heading=wanted_heading-2*3.14159
end
--Spring.Echo("wanted heading",wanted_heading)
local dist1=0
local dist2=0
--check if shot can be fired
--calculate distance from desired rotation
dist1=attack_heading-wanted_heading
if (dist1<0) then dist1=-dist1 end
dist2=(2*3.14159-attack_heading)+wanted_heading
if (dist2<0) then dist2=-dist2 end
if (dist1<1.5*turnspeed or dist2<1.5*turnspeed) then
attack_heading=wanted_heading
--fire shot !
StartThread(restore)
return true
end
if attack_heading>wanted_heading then
dist1=attack_heading-wanted_heading
dist2=(2*3.14159-attack_heading)+wanted_heading
if (dist1 >= dist2) then
attack_heading=attack_heading+turnspeed
wanted_heading=-100 --in order not to trigger the 2nd one aswell
end
if (dist1 < dist2) then
attack_heading=attack_heading-turnspeed
wanted_heading=-100 --in order not to trigger the 2nd one aswell
end
end
if attack_heading<wanted_heading then
dist1=wanted_heading-attack_heading
dist2=(2*3.14159-wanted_heading)+attack_heading
if (dist1 >= dist2) then
attack_heading=attack_heading-turnspeed
end
if (dist1 < dist2) then
attack_heading=attack_heading+turnspeed
end
end
Sleep(60)
end
--attack_heading=2*3.1415926 --this would be a full circle
StartThread(restore)
--return true
end