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...
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 think that should work. 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...
Joined: 22 Feb 2006, 01:02 Location: cheap kitchen
gun always aimed "downwards", no matter how chasis rotates:
Code:
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
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.
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.
Code:
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
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
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
Should be bug free now and taking the shortest of both turns.
Users browsing this forum: No registered users and 1 guest
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot post attachments in this forum