The blood part ceases to exist in an inaccurate position very far away from the blood trail part. This is my first attempt at messing with raycasts. I am trying to achieve a part that exists right wheret he blood trail finishes.
If you add the normal, you’ll get a proper look CFrame. I don’t advise setting the CFrame’s own position as the point for it to look at.
As far as positioning goes, there’s not enough info here to guarantee an answer. BloodTrail needs to be defined in this case. If you tell me exactly where BloodTrail.Position is at in the video (or provide a new video with better visuals) I think I can come up with an answer for that.
BloodTrail.Position = Position -- this is a given functino argument
BloodTrail.Velocity = Vector3.new(math.random(v1.Value,v2.Value),math.random(v1.Value,v2.Value) + 30,math.random(v1.Value,v2.Value))
Also I did try normal but the blood part would sometimes exist inside the red part which i dont really want
Are you using a .Touched event to initiate the raycast? I’m saying this because I saw “TouchedHit.Position - BloodTrail.Position” for the direction of the raycast
there are two things wrong with this approach
The first being mathematical, the TouchedHit.Position refers to the center of the hit part, not the position where it was hit, so you end up casting a ray that is pretty much sideways, and the raycast result position is far from the position where the bloodtrail hit the part.
The second thing is that you shouldn’t be using .Touched along with raycast, just pick one, unless you insist on getting the normal vector of the hit part.
If you do use .Touched, simply put the blood splatter at the position of the blood trail the moment the .Touched event fires
For more precise collision detection for projectiles such as the blood trail, I recommend using raycast to calculate the ballistics, and if you don’t want to do the math, use FastCastRedux (you can find the module in the toolbox)
Whenever the cast hits something, place the splatter at the result position and u could do some fancy CFrame stuff with the normal vector
That’s what I did also, but the part spawns inside the touched part, which I don’t want, and the solution to this was to make the blood part appear above the part but I don’t know the math formula for it.
Well I don’t use .Touched event that much because it’s pretty unreliable, especially at higher speeds
For example, I’m scripting flight physics and aircraft go several hundred studs per second, and bullets thousands. I almost exclusively use raycast for collision detection, and for the blood trail, which is a ballistic projectile, I would recommend simulating its trajectory using raycast instead of built-in physics.
The .Touched event sometimes completely misses the collision and fails to fire or delays firing, which might be why the blood splatter spawns inside the hit part
But if it worked ideally, spawning the blood splatter at the blood trail position the moment the event fires should work fine, so long as you account for the size of the blood splatter so it’s not clipped halfway into the hitpart
Yes that’s because the direction of the raycast is incorrect which results in the wrong position
You could try putting the origin of the raycast back a bit to where the blood trail might have been, and then cast it towards the blood trail’s current position (should be touching the hit part because this happens in the .Touched event)
local origin = BloodTrail.Position - BloodTrail.AssemblyLinearVelocity.Unit
--there is a short interval of time during which something can move into position immediately after the bloodtrail passes and just happen to block the raycast
-- you could do BloodTrail.Position - BloodTrail.AssemblyLinearVelocity.Unit * .1 to make it even less likley
--I also noticed that you're using the Velocity property which is deprecated,
--and assemblylinearvelocity is not exactly its replacement,
--you'll have to read up on that it's too long to explain
local direction = BloodTrail.AssemblyLinearVelocity.Unit * 2 --a bit of extra length in case it barely misses the hitpart
--the bloodtrail should be in the filterdescendantsinstances table
local result = workspace:Raycast(origin, direction, params)
if result.Instance ~= TouchedHit:: BasePart then
--this should not happen but can happen
warn("Ray hit instance, ", result.Instance, ", is not the same as Touched event hit part!")
end
bloodpart.CFrame = CFrame.new(result.Position, result.Position + result.Normal)
--makes the lookvector of the bloodpart parallel to the surface's normal
--idk what dimensions of the bloodpart actually are so change this accordingly
However, I still highly recommend raycast projectile simulation, it is superior in literally every way. It would allow you to get the precise point of contact between the blood trail and whatever part it hit, it will not fail to detect a collision unlike with roblox physics, and way faster, which will eventually be a huge deal as more processes are added to the game
for your purposes, using “AssemblyLinearVelocity” is the exact same thing as Velocity, except with more letters to type
but if the bloodtrail involved multiple baseparts welded together, it’s a different story
welding puts baseparts into a common “assembly”, and AssemblyLinearVelocity actually refers to linear velocity at the center of mass of the assembly
the true replacement for BasePart.Velocity is actually BasePart:GetVelocityAtPosition(BasePart.Position)
But unless you’re making something that demands extremely precise physics calculations that involve fast rotating assemblies, the differences are negligible
but yeah if you want your code to be future proof, use AssemblyLinearVelocity
Okay, thank you! I did some adjustements to the function and it works great! though, for some reason if Time is 1, the blood part won’t spawn.
for i = 1, Time do
local BloodTrail = __REPLIC.Effects.BloodTrail:Clone() -- this is a part with trail
BloodTrail.Name = "BL"
BloodTrail.Position = Position
BloodTrail.AssemblyLinearVelocity = Vector3.new(math.random(10,15),math.random(10,15) + math.random(25,30), math.random(10,15))
BloodTrail.Parent = workspace
C = BloodTrail.Touched:Connect(function(hit)
if hit.Anchored and not tostring(hit):find("BL") then
BloodTrail.Anchored = true
warn("Touched: ".. hit.Name)
local origin = BloodTrail.Position - BloodTrail.AssemblyLinearVelocity.Unit
local direction = BloodTrail.AssemblyLinearVelocity.Unit * 2 --a bit of extra length in case it barely misses the hitpart
local rayParams = RaycastParams.new()
rayParams.IgnoreWater = true
local result = workspace:Raycast(origin, direction, rayParams)
if result then
local BloodPart = __REPLIC.Effects.BloodPool:Clone()
BloodPart.Name = "BL2"
local R = math.random(2,2)
Tween:Create(BloodPart, TweenInfo.new(1), { Size = Vector3.new(R, R,0.5) }):Play()
BloodPart.Anchored = true
BloodPart.Color = Color3.fromRGB(76, 0, 1)
BloodPart.CanCollide = false
BloodPart.CanTouch = false
BloodPart.CFrame = CFrame.new(result.Position, result.Position + result.Normal)
BloodPart.Parent = workspace
task.delay(4,function()
Tween:Create(BloodPart, TweenInfo.new(4), {Transparency = 1}):Play()
end)
Debris:AddItem(BloodPart, 9)
end
end
C:Disconnect()
end)
Debris:AddItem(BloodTrail, 4)
end