Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

How to visualise a vector force, in game?

Repost because previous question had no answers

TLDR: I want to show a Vector3, as an arrow, in game

Ive been working on this script for about a week now. I'm trying to create a custom particle system that can do way more then the default particle effect.

local RunService = game:GetService("RunService")
local DebrisService = game:GetService("Debris")

local sigma = 10
local rho = 28
local beta = 8/3
local theta = ??
local pi = 22/7

function GenerateVectorField(style, scaleX, scaleY, scaleZ, seed)
	local VectorField = {}
	if style == -1 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = (scaleX/2)*(-1)+i * pi
					local y = (scaleY/2)*(-1)+j * pi
					local z = (scaleZ/2)*(-1)+k * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(0, 0, 0), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	if style == 0 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = (scaleX/2)*(-1)+i * pi
					local y = (scaleY/2)*(-1)+j * pi
					local z = (scaleZ/2)*(-1)+k * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(0, -196.2, 0), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	if style == 1 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = ((scaleX/2)*(-1)+i) * pi
					local y = ((scaleY/2)*(-1)+j) * pi
					local z = ((scaleZ/2)*(-1)+k) * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(x, y, z), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	if style == 2 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = (scaleX/2)*(-1)+i * pi
					local y = (scaleY/2)*(-1)+j * pi
					local z = (scaleZ/2)*(-1)+k * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(y * z, x * z, x * y), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	if style == 3 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = (scaleX/2)*(-1)+i * pi
					local y = (scaleY/2)*(-1)+j * pi
					local z = (scaleZ/2)*(-1)+k * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(math.sign(x), math.sign(y), math.sign(z)), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	if style == 4 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = (scaleX/2)*(-1)+i * pi
					local y = (scaleY/2)*(-1)+j * pi
					local z = (scaleZ/2)*(-1)+k * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(sigma * (y - x), rho * x - y - x * z, x * y - beta * z), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	if style == 5 then
		for i=1, scaleX do
			for j=1, scaleY do
				for k=1, scaleZ do
					local x = (scaleX/2)*(-1)+i * pi
					local y = (scaleY/2)*(-1)+j * pi
					local z = (scaleZ/2)*(-1)+k * pi
					
					local Vector = CFrame.new(Vector3.new((scaleX/2)*(-1)+i, (scaleY/2)*(-1)+j, (scaleZ/2)*(-1)+k)) * CFrame.fromAxisAngle(Vector3.new(math.random() - .5, math.random() - .5, math.random() - .5), 1)
					table.insert(VectorField, i, Vector)
				end
			end
		end
	end
	return VectorField
end

if true then
	RunService.Heartbeat:Connect(function()
		for i=1,5 do
			local part = game.ServerScriptService.Part:Clone()
			part.Parent = workspace.Particles
			part.Velocity = Vector3.new(math.random(-10,10)/100,math.random(-10,10)/100,math.random(-10,10)/100)
			-- part.Position = part.Position + Vector3.new(math.random(-10,10)/10,math.random(-10,10)/10,math.random(-10,10)/10)
			local temp = Color3.new(math.random(), math.random(), math.random())
			part.SphereHandleAdornment.Color3 = temp
			part.Trail.Color = ColorSequence.new(temp,temp)
			part.Anchored = false
			part.Trail.Parent = workspace.Trails
		end
	end)
end

for i=1,math.huge do
	local VectorField, scale = GenerateVectorField(0, 10, 10, 10)
	workspace.Vectors:ClearAllChildren()
	workspace.Visuals:ClearAllChildren()
	workspace.Particles:ClearAllChildren()
	workspace.Trails:ClearAllChildren()
	for i=1,#VectorField do
		local part = Instance.new("Part", workspace.Vectors)
		local vector = Instance.new("Vector3Value", part)
		part.Size = Vector3.new(1,1,1)
		part.CFrame = VectorField[i]
		vector.Value = part.Orientation
		part.Orientation = Vector3.new(0, 0, 0)
		part.Anchored = true
		part.Transparency = 1
		part.CanCollide = false
		part.Locked = true
		if true then
			local part = Instance.new("Part", workspace.Visuals)
			local vector = Instance.new("VectorForce", part)
			part.Size = Vector3.new(0.05,0.05,0.05)
			part.CFrame = VectorField[i]
			-- vector.Force = part.Orientation
			-- vector.Visible = true
			-- vector.Enabled = true
			-- part.Orientation = Vector3.new(0,0,0)
			part.Anchored = true
			part.Transparency = 1
			part.CanCollide = false
			part.Locked = true
			local Cone = script.ConeHandleAdornment:Clone()
			Cone.Parent = part
			Cone.Adornee = part
			-- Cone.Color3 = Color3.fromHSV((part.Position - Vector3.new(0, 0, 0)).Magnitude / scale, 1, 1)
			-- Cone.Height = (part.Position - Vector3.new(0, 0, 0)).Magnitude
			local Cylinder = script.CylinderHandleAdornment:Clone()
			Cylinder.Parent = part
			Cylinder.Adornee = part
			-- Cylinder.Color3 = Color3.fromHSV((part.Position - Vector3.new(0, 0, 0)).Magnitude / scale, 1, 1)
			-- Cylinder.Height = (part.Position - Vector3.new(0, 0, 0)).Magnitude
		end
	end
	if false then
		for i=1,200 do
			local part = game.ServerScriptService.Part:Clone()
			part.Parent = workspace.Particles
			part.Velocity = Vector3.new(math.random(-10,10)/1,math.random(-10,10)/1,math.random(-10,10)/1)
			part.Position = part.Position + Vector3.new(math.random(-10,10)/10000,math.random(-10,10)/10000,math.random(-10,10)/10000)
			local temp = Color3.new(math.random(), math.random(), math.random())
			part.SphereHandleAdornment.Color3 = temp
			part.Trail.Color = ColorSequence.new(temp,temp)
			part.Anchored = false
		end
	end
	wait(10)
end

Basically what this does is make an array of vectors (function GenerateVectorField), then construct them into a vector field. And spawn particles to simulate on the vector field.

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

RunService.Heartbeat:Connect(function()
	local particles = workspace.Particles:GetChildren()
	local ignore = workspace.Vectors:GetChildren()
	for i=1,#particles do
		local currentvector = workspace:FindPartsInRegion3WithWhiteList(Region3.new(particles[i].Position - (0.5 * particles[i].Size), particles[i].Position + (0.5 * particles[i].Size)), ignore)
		for j=1,#currentvector do
			local goal = {}
			goal.Velocity = (currentvector[j].Value.Value / 10)
			local tweenInfo = TweenInfo.new(1)
			local tween = TweenService:Create(particles[i], tweenInfo, goal)
			tween:Play()
		end
		if (particles[i].Position - Vector3.new(0,0,0)).Magnitude > 10 then
			particles[i]:Destroy()
		end
	end
end)

Basically what this does is find a vector that is in range of a particle and set the velocity of the particle to the vector.

All I want to do is visualize the vector field I have.

Ive tried HandleAdornments and setting the orientation to show the vectors but they don't seem to point in the correct direction according to other simulations (Ex. f(x,y,z) = [x,y,z]) or even the way particles move when they intersect (Ex. f(x,y,z) = [sigma * (y - x), rho * x - y - x * z, x * y - beta * z]). I've tried visible VectorForces, which works exactly as I need, but they don't show up ingame so they are completely useless. I've tried hundreds of things but none of them work.

1 answer

Okay so I only read the TLDR, but here's what I'd try

Add each Vector3 to the midpoint of the vector field to figure out where the arrow head would be, then create a part in between the midpoint and the end of the arrow, use the magnitude of the vector to size the part accordingly, and set the orientation so its pointing from the midpoint to the end.

This might be completely off since I didn't fully read the question, but oh well.

1 comment

0

You got it right, though the problem is that orientation and vector forces are completely different. So you cant just set orientation as the vector, or it wont point in the right direction.

This discussion is preserved as it was. New answers, comments, and votes are closed.