VectorForces do nothing

I’m trying to make water currents for my boat game. Right now, these are represented with a part that adds a VectorForce to any part of a boat that touches it, and removes it again once the part stops touching.

This works, except that sometimes nothing happens? I’ve confirmed that the VectorForces really do get added and configured correctly, it’s just that the boat doesn’t seem to be affected. Pushing the boat by walking into it with my character seems to “activate” the VectorForces, but only until the boat touches the next “current part”.

Maybe try not using VectorForces then? You can try something like BodyForce, which will probably work much better for you.

1 Like

I’m looking into this issue, it seems to be a bug by no fault of your own.
Will update with more information in a little while and we can look into making a bug report.

In the meantime, can you share a repro of your issue? I think I’ve found a way to reproduce something that sounds like what you’re seeing but I’d like to make sure.

Edit: was a fluke, I need to see what you’re doing so we can see if this is a bug or not.

3 Likes

so you are add a vector force then removing it?
Have you tried there being a single VectorForce modified on contact and again on contactend?

so when 3 parts touch the boat they all add to the boats force then when one leaves it subtracts the force instead deleting it.

Hard to tell what you are doing without code.

It activating when a character bumps it(new physics introduced)
i have no clue :stuck_out_tongue:

Are you ensuring the magnitude of force is appropriate? Are you sure the drag created by water (assuming you are using terrain water) is being adequately compensated for?

Yes, I’m certain of this. I tweaked the water friction and Force magnitude to be sufficient to move the boat at what I feel is a fun/realistic pace while inside the current. It works correctly, except when it doesn’t :stuck_out_tongue:

Here's the responsible script
--Disabled while waiting for SetupCollisionGroups

local TagHelper = require( game.ReplicatedStorage.TagHelper )
local RunService = game:GetService("RunService")
local TagService = game:GetService("CollectionService")
local Util = require( game.ReplicatedStorage.Util )
local PhysicsService = game:GetService("PhysicsService")
local Players = game:GetService("Players")
local Debris = game:GetService("Debris")

local touchingDict = {}
local forcesDict = {}

function boatPartStartedTouching(wavePart, touchingPart)
	table.insert(touchingDict[wavePart], touchingPart)
	
	touchingPart.Velocity = touchingPart.Velocity + Util.v3OnSphere(1)
	
	local force = Instance.new("VectorForce")
	force.Attachment0 = touchingPart.WaveForceAttachment
	force.Attachment1 = wavePart.Attachment
	force.RelativeTo = Enum.ActuatorRelativeTo.Attachment1
	force.Force = Vector3.new(0, 0, -1) * 8 * 40
	force.Name = "WaveForce"
	force.Parent = touchingPart
	
	forcesDict[wavePart][touchingPart] = force
end

function boatPartStoppedTouching(wavePart, touchingPart)
	table.remove( touchingDict[wavePart], Util.indexOf(touchingDict[wavePart], touchingPart) )
	
	local force = forcesDict[wavePart][touchingPart]
	Debris:AddItem(force, 0)
	forcesDict[wavePart][touchingPart] = nil
end

function createWave(wavePart)
	touchingDict[wavePart] = {}
	forcesDict[wavePart] = {}
	
	wavePart.Touched:Connect(function(touchingPart) 
		if TagService:HasTag(touchingPart, "BoatPart") and not Util.indexOf(touchingDict[wavePart], touchingPart) then
			boatPartStartedTouching(wavePart, touchingPart)
		end
	end)
	
	wavePart.TouchEnded:Connect(function(touchingPart) 
		if TagService:HasTag(touchingPart, "BoatPart") and Util.indexOf(touchingDict[wavePart], touchingPart) then
			boatPartStoppedTouching(wavePart, touchingPart)
		end
	end)
end

TagHelper:ApplyToAllTagged("Wave", createWave)

It’s obviously got a couple of dependencies, but you shouldn’t worry about those. The script itself works correctly, I’ve verified that the VectorForce objects really do get created, with the correct Attachment and Force properties.

I’ve sent you a PM with a link to the place file. Thank you for taking the time to look into this.

1 Like

Trying to remove all dependencies

  • manually put touch events on my waves and used presence of the force attachment to identify boats (remove tags)
  • explicit values for forces

Combined your dictionaries to keep track of name and value of forces generated by waves

  • unique key used by combining boat part name and wave name
  • all would need a unique name, which could be affected with a script
  • since all touching event have both objects and therefore their name it works :slight_smile:
Simplified Repro
if(workspace:FindFirstChild("Baseplate")) then workspace.Baseplate:Destroy() end

local forces = {}

local function createWaves()
	local waveparts = {}
	local wave = Instance.new("Part",workspace)
	wave.Size = Vector3.new(10,2,10)
	wave.Position = Vector3.new(0,0,0)
	wave.Anchored = true
	wave.Name = "wave1"
	wave.BrickColor = BrickColor.Black()
	local wave2 = wave:Clone()
	wave2.Parent = workspace
	wave2.Position = Vector3.new(0,0,10)
	wave.Name = "wave2"
	wave2.BrickColor = BrickColor.Blue()
	local wave3 = wave:Clone()
	wave3.Parent = workspace
	wave3.BrickColor = BrickColor.Red()
	wave.Name = "wave3"
	wave3.Position = Vector3.new(10,0,5)
	local dir = Instance.new("Vector3Value", wave)
	dir.Value = Vector3.new(0,0,1)
	dir.Name = "Force"
	dir = Instance.new("Vector3Value",wave2)
	dir.Value = Vector3.new(1,0,0)
	dir.Name = "Force"
	dir = Instance.new("Vector3Value",wave3)
	dir.Value = Vector3.new(1,0,0)
	dir.Name = "Force"
	table.insert(waveparts, wave)
	table.insert(waveparts, wave2)
	table.insert(waveparts, wave3)
		
	for i, w in pairs(waveparts) do
		createWave(w)
	end
end

local function createBoat()
	local boatFront = Instance.new("Part")
	boatFront.Position= Vector3.new(0,2,0)
	boatFront.Size = Vector3.new(1,1,1)
	boatFront.Parent = workspace
	boatFront.Name = "BoatFront"
	local boatBack = Instance.new("Part")
	boatBack.Position = Vector3.new(0,2,-1)
	boatBack.Parent = workspace
	boatBack.BrickColor = BrickColor.Green()
	boatBack.Size = Vector3.new(1,1,1)
	boatBack.Name = "BoatBack"
	local weld = Instance.new("WeldConstraint",boatFront)
	weld.Part0 = boatFront
	weld.Part1 = boatBack
	local attach1 = Instance.new("Attachment",boatFront)
	attach1.Name = "WaveForceAttachment"
	local attach2 = attach1:Clone()
	attach2.Parent = boatBack
end

function boatPartStartedTouching(wavePart, touchingPart)		
	local force = Instance.new("VectorForce")
	force.Attachment0 = touchingPart.WaveForceAttachment
	force.Force = wavePart.Force.Value*45
	force.RelativeTo = "World"
	force.Name = touchingPart.Name..'+'..wavePart.Name
	force.Parent = touchingPart
	forces[touchingPart.Name..'+'..wavePart.Name] = force
	print(force)
end

function boatPartStoppedTouching(wavePart, touchingPart)
 --	table.remove(touchingDict[wavePart], touchingPart)
	
	local force = forces[touchingPart.Name..'+'..wavePart.Name]
	force:Destroy()
	forces[touchingPart.Name..'+'..wavePart.Name] = nil
end

function createWave(wavePart)	
	wavePart.Touched:Connect(function(touchingPart)
		if(touchingPart.WaveForceAttachment) then
			boatPartStartedTouching(wavePart, touchingPart)
		end
	end)
	
	wavePart.TouchEnded:Connect(function(touchingPart) 
		if(touchingPart.WaveForceAttachment) then
			boatPartStoppedTouching(wavePart, touchingPart)
		end
	end)
end

createWaves()
createBoat()

Is this the general functionality you were wanting?
are your waves larger than boat parts or smaller? is the boat single block or multiple?
whats the max number of forces you will have on a single part?

i say use BodyThrust but VectorForce is the best bst one,while next is bodythrust

Thanks, but as I explained earlier in the thread, the script itself doesn’t seem to be broken.

Experimenting further with what you sent me, it appears the friction property of the boat parts is what’s causing it to be unaffected by VectorForces.

Try changing friction for boat parts and see if that solves the issue.
Changing friction for the water will create a nice momentum preserving effect, but it will diminish the water’s ability to move parts via the anchored + velocity trick.

newBoatPart.CustomPhysicalProperties = PhysicalProperties.new(0.7, 0.01, 0.5)

I noticed that a flat boat consisting of an array of parts would only begin to be affected by the VectorForces when all / most of the parts contained a force, which for some reason tipped me off to try playing with friction.

It seems like the actual force applied to an assembly of multiple parts welded together is not equal to the actual force applied to a single part with the same size and physical properties as the assembly.
Either friction or force applied to parts in a rigid assembly seems incorrect.

https://gfycat.com/JubilantVelvetyIndigobunting

2 Likes

Yeah that’s pretty weird. I’ll have to come up with some workaround.