Hes not asking someone to make him an entire system if you actually red correctly you would see that he said
Oh okay.
…
Hmm, well you could attach a part infront of the car, and calculate the speed of the car and if that part is hit by anything and the car is going at a fast enough speed then loop through the car unanchor all the parts and put smoke and other effects you want in the different parts of the car!
I’m not sure but if you use a vehicle seat, idk if there is a property in that where you can check the current speed. But if it you can use it to check the speed right before it collides with a part, or you can use tick and see how much the humanoid root part is changing in position over time and by that way calculate the speed. Hope it helps
I’m not asking for a whole system to be made, I just want pointers
Car crashes can be described by classical physics pretty well. In its simplest form, for the purpose of recreating this in a game, you should look at Newton’s laws of motion i.e. law of inertia (car stays in motion until it is acted upon by an external force) and the 1st law of thermodynamics i.e. that the total energy of a system is constant (kinetic energy of a car is transformed into malformation of the car when crashing).
Now we have two basic models to base your script on. Now we just need to check for collisions with objects that would enact a force on the car (e.g. check for collisions with anchored / large models or parts with a great enough mass to damage the car) and then based on the velocity at that impact, we can damage the car to some extent.
Edit:
I got bored and decided to play around with this. In no way is this a finished product, you’ll need to do far more than this, but it’s a start and should give you some idea on how to do this yourself:
Script:
-- local
local function create(obj)
obj = Instance.new(obj)
return function (props)
for prop, val in next, props do
obj[prop] = val
end
return obj
end
end
-- init
local car = require(script.car_class).new(script.Parent)
-- fires when the car crashes as defined by our MassThreshold and VelocityThreshold properties
car.crashed:connect(function (hit, position, normal, surface, impact)
-- debug
print(
('Our car instance collided with %s\'s %s surface (relative mass %d) at a velocity magnitude of %d studs/second'):format(hit.Name, surface, impact.relativeMass, impact.impactVelocity)
)
-- Instantiate our smoke / do any other animations
create "Smoke" {
Parent = car:getCar()
}
end)
car:setMassThreshold(10):setVelocityThreshold(30):getCar().BodyVelocity.Velocity = Vector3.new(0, 0, -50)
Car module class:
-- helpers
local function create(obj)
obj = Instance.new(obj)
return function (props)
for prop, val in next, props do
obj[prop] = val
end
return obj
end
end
-- init
local car = { }
function car.new(model)
local this = { }
this.car = nil
this.mass = nil
this.bounds = nil
this.currentVelocity = nil
this.lastPosition = nil
this.update = Instance.new 'BindableEvent'
this.crashed = this.update.Event
this.connections = { }
this.massThreshold = 0 --> Determines the minimum relative mass our object needs to be to damage our car
this.veloThreshold = 0 --> Determines the minimum velocity we need to be travelling to cause damage => You could alter this to be partly determined by the mass of the object instead
-- local
local function getMass(part)
local density = PhysicalProperties.new(part.Material).Density
local size = part.Size
local volume = size.x * size.y * size.x
return density * volume
end
local function recurseMass(obj)
local mass = 0
local recurse do
function recurse(item)
for i, v in next, item:GetChildren() do
if v:IsA 'BasePart' then
mass = mass + getMass(v)
end
recurse(v)
end
end
end
return mass
end
local function normalToSurface(cf, normal)
normal = cf:vectorToObjectSpace(normal)
local x, y, z = normal.x, normal.y, normal.z
if x ~= 0 and (y == 0 and z == 0) then
return x > 0 and 'Right' or 'Left'
elseif y ~= 0 and (x == 0 and z == 0) then
return y > 0 and 'Top' or 'Bottom'
elseif z ~= 0 and (x == 0 and y == 0) then
return z > 0 and 'Back' or 'Front'
end
return 'Back'
end
local function carCollision(hit)
if not this.currentVelocity then
return
end
if hit and hit.Parent then
local mass = getMass(hit)
-- Is it at least the same or more mass than ourselves?
if mass - this.mass > this.massThreshold then
-- Are we travelling faster than our threshold velocity for damage to occur?
if this.currentVelocity.magnitude > this.veloThreshold then
-- Find the position, normal and surface of the hit to pass back for some kind of impact on that part etc
local _, collision, normal = game.Workspace:FindPartOnRayWithWhitelist(
Ray.new(this.bounds.Position, (hit.Position - this.bounds.Position).unit * (hit.Position - this.bounds.Position).magnitude),
{hit}
)
local surface = normalToSurface(hit.CFrame, normal)
-- Perform our crash event
this:crash(hit, collision, normal, surface, {
relativeMass = mass - this.mass,
impactVelocity = this.currentVelocity.magnitude
})
end
end
end
end
-- private
function this._construct(obj)
if typeof(obj) ~= 'Instance' then
return warn 'Unable to instantiate, provide an instance'
end
-- construct our basic variables and our hit box
if obj:IsA 'Part' then
this.mass = getMass(obj)
this.bounds = obj
else
this.mass = recurseMass(obj)
local cf, size = obj:GetBoundingBox()
this.bounds = create 'Part' {
Name = 'BOUNDING_BOX';
CanCollide = false;
Anchored = obj.PrimaryPart.Anchored;
Size = size;
Transparency = 1;
Parent = obj;
}
_ = not this.bounds.Anchored and create 'Weld' {
Parent = this.bounds;
Part0 = obj.PrimaryPart;
Part1 = this.bounds;
C0 = obj.PrimaryPart.CFrame:toObjectSpace(cf);
}
end
this.car = obj:IsA "Model" and obj.PrimaryPart or obj
if not this.lastPosition then
this.lastPosition = this.bounds ~= obj and (function () local cf = obj:GetBoundingBox() return cf.p end)() or obj.CFrame.p
end
this.connections['joint'] = game:GetService('RunService').Heartbeat:connect(function (delta)
if not this.car or not this.car.Parent then
return this:destroy()
end
-- move our bounding box along with our car if it's anchored
local cf = this.bounds ~= obj and obj:GetBoundingBox() or obj.CFrame
if this.bounds ~= obj then
this.bounds.CFrame = cf
end
-- set up our velocity determinants
local pos = cf.p
this.currentVelocity = (pos - this.lastPosition) / delta
this.lastPosition = pos
end)
this.connections['collision'] = this.bounds.Touched:connect(carCollision)
return this
end
-- public
function this:getMass()
return this.mass
end
function this:getCar()
return this.car
end
function this:setMassThreshold(val)
this.massThreshold = val
return this
end
function this:setVelocityThreshold(val)
this.veloThreshold = val
return this
end
function this:crash(hit, position, normal, surface, impact)
-- Remove our listeners
for i, v in next, this.connections do
if v then
v:disconnect()
end
end
if this.bounds ~= this.car then
this.bounds:Destroy()
end
-- Remove our body objects if we're not anchored
if not this.car.Anchored then
for i, v in next, this.car:GetChildren() do
if v:IsA "BodyVelocity" or v:IsA "BodyPosition" or v:IsA "BodyGyro" then
v:Destroy()
end
end
end
this.update:Fire(hit, position, normal, surface, impact)
end
function this:destroy()
-- Remove all listeners and delete our car
for i, v in next, this.connections do
if v then
v:disconnect()
end
end
if this.car and this.car.Parent then
this.car:Destroy()
end
end
-- construct
return this._construct(model)
end
return car
Place file: car_collisions.rbxl (22.9 KB)
OP said hes not 100% sure where to start and yes yours might work as intended but it is way to complicated
In what way is it too complicated? I’m more than happy to explain the code further if it would help you better understand the code if you’re struggling
As far as I’m concerned, a script that took me ~20 minutes to write and demonstrates how to implement this in a replicable way, as well as solving several issues that OP would likely have had to return to Scripting Support for isn’t very complicated. Similarly, if you note in my post, I do mention that this code isn’t a finished example and shouldn’t be used as one.
Well I dont think objected oriented programming is what OP was really looking for, more procedural code is what I think he wanted something minimalistic and simple.
So the reason you, and the OP, should use OOP is that it provides you with a solution that is easy to maintain and modify. My code, although not a finished product as mentioned, answers the basis of his question:
And clearly demonstrates (1) a method to deetermine if the car has hit something (2) if it has hit it with enough force to damage the car itself as well as (3) how to act upon this event by creating smoke and to stop the car from working - the latter of which is procedural and simple as you may note.
As I have used OOP, OP can examine my code, determine how he would like to change it if he desires to use it as a framework, and modify it to adapt it further into a completed project, or tear out the parts he requires thanks to its OOP nature. I appreciate that it may look complex but in truth, I think for the functionality it currently has, it’s quite a simple solution - OOP doesn’t make it anymore complex, it just provides OP with a solution that be modified and maintained easier, as well as applied to a number of cars in his game without replicating code.
OOP is overrated you dont need it to make efficient functioning code.
I appreciate you may think that but this thread is a question by OP on how to make a system that determines whether a car has crashed - you are currently derailing it by debating the functionality and efficiency of OOP vs non-OOP and questioning the functionality of my own solution without truly explaining why and/or providing your own solution. I appreciate you are trying to help but I don’t think our debate over OOP will be of any use to OP unless you make it relevant to his question and/or provide a solution better than the above.
OP has already seen my post and gone about scripting it im just here to inform you on some things
Hey! I once browsed looking for a possible way to create something like this before. Your best option to keep it simple and sweet is to create a part named “Collider” or such. This is what we will use to detect when the car comes into collision with something. You will also insert a NumberValue named “Health” and set it’s value to 100 or higher if you wish. Insert some smoke aswell and customise it to your liking and set Enabled to false.
script.Parent.Touched:Connect(function(Hit) -- We use this to detect when our "Collider" hits a part
local Speed = math.floor((script.Parent.Velocity - Hit.Velocity).magnitude) -- Detecting the speed the part is travelling at
if Speed > 30 and not game.Players:GetPlayerFromCharacter(Hit.Parent) and not Hit.CanCollide == false then -- If Speed is above the desired speed you want, and not a Player or a part with CanCollide set to false then do code
script.Parent.Health.Value = script.Parent.Health.Value - script.Parent.Velocity.Magnitude / 1.06 -- Takes away "Health" based on the speed
print("You damage your vehicle at a speed of: "..Speed)
end
if script.Parent.Health.Value =< 30 then
script.Parent.Smoke.Enabled = true
end
-- If you want to stop the player from being able to stop driving you can access the DriveSeat and set Disabled to true.
Hope this helps! I’m sure their are many other alternatives you can tackle this idea with, but i found this to be the most simple personally.
Oops, change =< to <= i did a typo.
Let me help further as you seem to be confused, and as I mentioned, we should really keep this relevant to the post.
- As you only attach a part to the front of the car, you will only be able to detect head on collisions
- Calculating purely the speed is fine but if you don’t account for mass as I have, then the car will break if the front-facing collision detector hits anything incl. players or other small objects that shouldn’t necessarily break a car e.g. a malleable metal bin
I’m not sure where this came from as I never said it was required to make efficient coding. If you mean efficiency in terms of processing power, you are correct that there is a trade off between OOP and procedural coding - OOP provides you with increased modularity and improved programming efficiency (in terms of developer efficiency when coding) but will be slightly slower than procedural due to runtime lookup.
The solution provided is an example, and an example is just that - as I mentioned OP can choose what to take from it. The solution is minimalistic & simplistic as it not only provides OP with a solution that answers his original post, but provides him with a model that calculates collisions based on the bounds of the object (solving the problem in your solution of it only detecting front on collisions) - dealing with both unanchored and anchored cars, as well as providing a deterministic solution to calculating collisions with (1) objects that are of a great enough mass to cause damage (solving the issue with your code where it would break if any object hit it) and (2) if the car is travelling at a great enough velocity.
Similarly, it also provides OP with a mechanism to determine where the collision position is, so that in the future OP could deform the car based on the position, velocity of the crash, and the relative forces thanks to the calculation of masses. To top it off, it also provides OP with a solution that provides him with the surface that the car hit - which would allow him to deform the surface of the object he hit if he so desired in the future.
As you can see, none of this is too complex if you understand the code. Once again, if you or OP do not understand the code I’m more than happy to help, or if you both desire I can rip out the relevant code to make my solution seem less complex to you.
You should make it blow up and kill the player if they crash hard enough
I’m really sorry, I don’t really understand what your code is doing. The fuction?
Which part are you most struggling with so I can help you understand?
The main part is all the functions, they confuse me a bit.