Make part go other direction when it hits another part

  1. What do you want to achieve?
    Hey!
    I’m making some planet orbiting thing and I’m currently attempting to make it so when a planet collides with another planet/sun, it goes the other direction it was going (e.g if it hit going north, it would go south)

  2. What is the issue?
    I don’t know how to do so, CFrame.LookVector.X returns -0.

  3. What solutions have you tried so far?
    There isn’t anything to help with this

local CanOrbit = true
task.wait(5)

local Planet = script.Parent
local OrbitAround = workspace.Sun

local OriginalPosition = Planet.Position
local degree = 0
local range = 10

Planet.Position = OrbitAround.Position + Vector3.new(0, 0, -range)
local Cooldown = 0.01


Planet.Touched:Connect(function(otherPart)
	if CanOrbit == false then return end
	print(otherPart)
	CanOrbit = false
	workspace.Planet.Anchored = false
	print(otherPart.Mass)
	range = range * otherPart.Mass / 2
	
	
	coroutine.wrap(function()
		while true do
			
			if range < 0 then break end

			degree += 1
			range -= math.random(1, 5) / 50
			print(range)

			local x = math.cos(math.rad(degree)) * range
			local y = 1
			local z = math.sin(math.rad(degree)) * range

			--Planet.Position = OriginalPosition + Vector3.new(x, y, z)
			Planet.LinearVelocity.VectorVelocity = Vector3.new(otherPart.CFrame.LookVector.X, 0, 0)
			task.wait()
		end
	end)()
	
end)

coroutine.wrap(function()
	while CanOrbit == true do

		degree += 1
		Cooldown = range / 500
		print(Cooldown)
		range -= math.random(1, 5) / 1000

		local x = math.cos(math.rad(degree)) * range
		local y = 1
		local z = math.sin(math.rad(degree)) * range

		--Planet.Position = OriginalPosition + Vector3.new(x, y, z)
		Planet.LinearVelocity.VectorVelocity = Vector3.new(x, 0, z)
		task.wait(Cooldown)
	end
end)()


1 Like

Here’s an example on how you could do this:

local part = script.Parent
local curr: Vector3 = part.CFrame.LookVector * 2

--@ function taken from https://github.com/EgoMoose/Articles/blob/master/Vectors/Dot%20product.md
local function Reflect(vector, normal)
	return -2 * vector:Dot(normal) * normal + vector;
end

part.Touched:Connect(function(target: BasePart)
	local ray = workspace:Raycast(part.Position, (target.Position - part.Position))
	local normal = ray and ray.Normal
	
	if normal then
		curr = Reflect(curr, normal)
	end
end)

while true do
	part.AssemblyLinearVelocity += curr
	task.wait()
end

You can add the planet’s CFrame with a 180 degree at any axis, something like this.

Earth.CFrame *= CFrame.Angles(math.pi, 0, 0)
-- you should only rotate 180 degree at ONE axis only

The x, y, and z values were not being used to set the position of the part.
I re-coded your code and this should work:

local CanOrbit = true
task.wait(5)

local Planet = script.Parent
local OrbitAround = workspace.Sun

local OriginalPosition = Planet.Position
local degree = 0
local range = 10

Planet.Position = OrbitAround.Position + Vector3.new(0, 0, -range)
local Cooldown = 0.01


Planet.Touched:Connect(function(otherPart)
	if CanOrbit == false then return end
	print(otherPart)
	CanOrbit = false
	workspace.Planet.Anchored = false
	print(otherPart.Mass)
	range = range * otherPart.Mass / 2
	
	
	coroutine.wrap(function()
		while true do
			
			if range < 0 then break end

			degree += 1
			range -= math.random(1, 5) / 50
			print(range)

			local x = math.cos(math.rad(degree)) * range
			local y = 1
			local z = math.sin(math.rad(degree)) * range

			--Planet.Position = OriginalPosition + Vector3.new(x, y, z)
			Planet.LinearVelocity.VectorVelocity = Vector3.new(otherPart.CFrame.LookVector.X, 0, 0)
			task.wait()
		end
	end)()
	
end)

coroutine.wrap(function()
	while CanOrbit == true do

		degree += 1
		Cooldown = range / 500
		print(Cooldown)
		range -= math.random(1, 5) / 1000

		local x = math.cos(math.rad(degree)) * range
		local y = 1
		local z = math.sin(math.rad(degree)) * range

		--Planet.Position = OriginalPosition + Vector3.new(x, y, z)
		Planet.LinearVelocity.VectorVelocity = Vector3.new(x, 0, z)
		task.wait(Cooldown)
	end
end)()

It just makes the planet stop moving altogether after about 4 seconds.
Tested it and it’s because of the AssemblyLinearVelocity loop.