So, I am making a simple PvP game with a glock, sprint system, ragdoll system and my main problem: a blood system, The thing itself works really well, However it is suppossed to create a part with a trail simulating a blood particle, However it only appears wherever it is on the workspace (Studio), Here's the main blood script (Thing that makes the blood appear):
local HP_PER_SPOT = 7.5 -- how many health points lost allows for a blood spot
local MAX_SPLATTERS = 100 -- max amt to generate
local CONE_ANGLE = 360 -- the angle of the cone of downward spray - MUST BE <180
local MAX_SPLATTER_DISTANCE = 120 -- how far away to splatter at the most
local MIN_SIZE, MAX_SIZE = 0.3, 4 -- min, max radius of particles
local LIFETIME = 30 -- how long to keep spatters
CONE_ANGLE = math.rad(CONE_ANGLE/2)
local template = script:WaitForChild("SplatTemplate"):Clone()
script.SplatTemplate:Destroy()
local model = Instance.new("Model", workspace)
model.Name = "Splatters"
local function Expand(obj, size)
local start = obj.Size
local cframe = obj.CFrame
for i = 0, 1, 0.05 do
wait()
obj.Transparency = 0.5
obj.Size = start:Lerp(size, i)
obj.CFrame = cframe
end
wait(LIFETIME)
for i = 0, 1, 0.05 do
wait()
obj.Transparency = 0.6
end
obj:Destroy()
end
local function GetNormal(part, pos)
local shape
if part:IsA("Part") then shape = part.Shape.Value
elseif part:IsA("WedgePart") then shape = 3
elseif part:IsA("CornerWedgePart") then shape = 4
else shape = 5
end
if shape == 0 then
return (pos-part.Position).unit, "curve", pos
elseif shape == 1 or shape == 3 then
local r = part.CFrame:pointToObjectSpace(pos)/part.Size
local rot = part.CFrame-part.Position
if r.x > 0.4999 then return rot*Vector3.new(1,0,0), "right", pos
elseif r.x < -0.4999 then return rot*Vector3.new(-1,0,0), "left", pos
elseif r.y > 0.4999 then return rot*Vector3.new(0,1,0), "top", pos
elseif r.y < -0.4999 then return rot*Vector3.new(0,-1,0), "bottom", pos
elseif r.z > 0.4999 then return rot*Vector3.new(0,0,1), "back", pos
elseif r.z < -0.4999 then return rot*Vector3.new(0,0,-1), "front", pos
end
return rot*Vector3.new(0,part.Size.Z,-part.Size.Y).unit, "ramp", pos
elseif shape == 2 then -- Cylinders
return (pos-part.Position).unit, "curve", pos
elseif shape == 4 then
local r = part.CFrame:pointToObjectSpace(pos)/part.Size
local rot = part.CFrame-part.Position
if r.x > 0.4999 then return rot*Vector3.new(1,0,0), "right", pos
elseif r.y < -0.4999 then return rot*Vector3.new(0,-1,0), "bottom", pos
elseif r.z < -0.4999 then return rot*Vector3.new(0,0,-1), "front", pos
elseif r.unit:Dot(Vector3.new(1,0,1).unit) > 0 then return rot*Vector3.new(0,part.Size.Z,part.Size.Y).unit, "lslope", pos
end
return rot*Vector3.new(-part.Size.Y,part.Size.X,0).unit, "rslope", pos
else
return Vector3.new(0,1,0), "unknown", pos
end
end
local min, random, rad, pi, tan = math.min, math.random, math.rad, math.pi, math.tan
local ignore = {model}
game.Players.PlayerAdded:connect(function(player)
player.CharacterAdded:connect(function(character)
local torso, humanoid = character:WaitForChild("Torso"), character:WaitForChild("Humanoid")
local lastHealth = humanoid.Health
table.insert(ignore, character)
humanoid.HealthChanged:connect(function(health)
for i = 1, min(MAX_SPLATTERS, (lastHealth-health)/HP_PER_SPOT) do
local part, pos
local try = 1
repeat
local p
repeat
p = Vector2.new(random()*2-1, random()*2-1)
until p.magnitude <= 1
local r = tan(random()*CONE_ANGLE)
local dir = Vector3.new(r*p.x, -1, r*p.y).unit
part, pos = workspace:FindPartOnRayWithIgnoreList(Ray.new(torso.Position, dir*MAX_SPLATTER_DISTANCE), ignore)
try = try + 1
until part or try > 5
if part then
local splat = template:Clone()
local size = min(splat.Size.X, splat.Size.Z) * MIN_SIZE + random()*(MAX_SIZE-MIN_SIZE)
splat.FormFactor = Enum.FormFactor.Custom
splat.Size = Vector3.new()
splat.CFrame = CFrame.new(pos, pos + GetNormal(part, pos)) * CFrame.Angles(-pi/2, 0, 0)
splat.Transparency = 1
coroutine.resume(coroutine.create(function()
Expand(splat, Vector3.new(size, splat.Size.Y, size))
end))
splat.Parent = model
end
end
lastHealth = health
end)
end)
end)
There's also a script on the part with the trail that's causing the problem;
local repathTime = 50 --time in seconds between calculation of random paths
local maxSpeed = 100 --must be positive, this will also make it go backwards sometimes and works in both non-up/down directions
--do not touch the script after here
math.randomseed(tick())
local part = script.Parent
if part:IsA("BasePart") then
while true do
local speed1 = math.random(1, maxSpeed)
local dir1 = math.random (1, 250)
local speed2 = math.random(1, maxSpeed)
local dir2 = math.random (1, 500)
if dir1 % 2 == 1 then
speed1 = -speed1
end
if dir2 % 2 == 1 then
speed2 = -speed2
end
part.Velocity = Vector3.new(speed1, 0, speed2)
wait(repathTime)
end
end
Yes, This script isn't mine, However i suck at scripting and i'm in a desperate need for a blood system since most scripts are either on death or for R15 (While my game is in R6 for the gun system to work correctly), If anyone could help it would be greatly appreciated. Note: The blood is suppossed to work like the type of blood from old blood flow or current criminality, However as explained above, Particles stay wherever the part is in the workspace.
Here's a video showing the problem i have (I forgot to pause the video i was watching, Sorry!) https://youtu.be/DZN7qvapyx0
