I want to create a vehicle destroy system. Ok so um its like this, there is a ship in the water and it gets shot by a cannonball. Some parts get destroyed. The ship goes to a repair station and once its at full health, all the destroyed parts are restored. How do I do this?
EDIT: When I mean restored I also mean the parts and their welds.
Best way to do that, is to make your boat of of tiny individual parts, together with a Health value.
Once that’s done, you should go create a script where if a cannonball hits that part, it breaks.
(With the usage of BasePart.Touched, explanation here: BasePart | Roblox Creator Documentation)
Then make the ship lose HP.
There is also another way where you could make the usage of velocity magnitude.
The last way is to make the usage of explosions & welds.
(Self explanatory)
To repair a ship’s HP, make a clone in ReplicatedStorage (or ServerStorage), and just make it copy to the destroyed ship once it’s repaired.
Hope this helped!
(I’ve got one of these systems myself, but for cars, to simulate realistic destruction, but without a repair system.)
This is a pretty difficult system depending on how you set it up. I believe the simpler system is to replace the entire vehicle @kpmanaiden and @Ready2XD said.
Personally I was aiming at replicating the armoured patrol system which had special rules like the parts were repaired starting from the root part.
Either way you need to have these things Data on the original structure, which is for every part it needs to have a dictionary of connected parts, with welds you can use getConnectedParts. You will need to store this data with all the parts within the build in one massive dictionary.
This is for my repair system, just to identify the closest destroyed, or damaged part.
Then starting from the root part perform flood fill and search all the parts around it.
If the searched part is destroyed or damaged then begin the repairing process
Repeat until all parts are repaired
Here is the flood fill structure
FloodFill
local findClosestDeadAndDamagedArmorEntity
findClosestDeadAndDamagedArmorEntity = function (armorEntity,ignoreList)
--avoid checking through the same armor entity
ignoreList = ignoreList or {}
if ignoreList[armorEntity] then
return
end
ignoreList[armorEntity] = armorEntity
--checks current entity if dead or damaged, prioritizing dead
--Has not get because it's a tag with no value retunred
local isDead = world.Has(armorEntity,IsDeadComponent) -- My system to detect if parts are damaged
if isDead then
return armorEntity
end
local isDamaged = ServerWorldModule.isEntityDamaged(armorEntity)
if isDamaged then
return armorEntity
end
--search other connected parts
local partsConnected = world.Get(armorEntity, PartConnectivityComponent)
if partsConnected == nil then
warn("No connected parts?")
return nil
end
local aliveArmorEntity
for _, part in pairs(partsConnected) do
local armorEntity = ServerWorldModule.getArmorEntityFromPart(part)
if ignoreList[armorEntity] then
continue
end
if not armorEntity then
continue
end
local armorEntityToReturn = findClosestDeadAndDamagedArmorEntity(armorEntity,ignoreList) -- Perform recursion
if armorEntityToReturn then
aliveArmorEntity = armorEntityToReturn
-- return armorEntityToReturn
end
end
return aliveArmorEntity
-- warn("No armor entities found?") -- end of search no other connected parts should be ok
end
What you do once you found the destroyed part is an entirely different story. For a weld system you probably need to remember the specific weld from the current part to the next part and the C0 and C1 settings used to position it relative to each other. Also you will need to store the original part as a clone in order to avoid using :Clone() on a destroyed instance.
Personally, for my system I used an odd choice to make my parts invisible and noncollidable in order to avoid doing the above C0 and C1 math. But then there is another issue of making stuff like arms fall off when the upper arm is destroyed so I had to do flood fill again and detect that. This works but theres a bug with my implementation so yeah.
Rather than breaking off parts from the ship - you could simply hide them.
Let’s say the Mast of your ship gets damaged to the point of brekaing, and all parts of the ship have a NumberValue called Integrity
function CreateDebris(obj) --create a duplicate part that will enact as the 'breaking' part of the ship
local debris = obj:Clone()
debris.Parent = workspace
debris.Transparency = 0
debris.CanCollide = true
game.Debris:AddItem(debris,120) -- clears up after 2 minutes
end
function Repair(obj) -- do something like this when you want to repair a part of the ship.
obj.Integrity = 100
obj.Transparency = 1
obj.CanCollide = true
end
local mast = ship.Mast
if (mast.Integrity.Value <= 0) then -- your mast will still exist as is, but just be hidden.
mast.Transparency = 1
mast.CanCollide = false
CreateDebris(mast)
end