Ontouch Enable Local Script

I am trying to make a Part where when I touch it It enables a LocalScript For the player that touched the part.

I have tried making a script for it but it does not work and won’t do anything. Not even showing an error.

Here is the script I made:

local Character = game.Players.LocalPlayer

function onTouch(part)
Character:FindFirstChild(“Gravity”).Enabled = true
end

script.Parent.Touched:connect(onTouch)

If the touch script is a server side script, I would recommend looking into RemoteEvents. A local script should be handled by the client, whereas the touch event is more suitably handled by the server.

If you are unaware of RemoteEvents, they essentially provide a way to communicate from the server to the client, and vice versa. In this case, you would send the client a signal via the RemoteEvent, and upon receival, the client would then run whatever code is desired.

Well, the Script is a LocalScript in StarterCharacterScripts.

Add this code into a server script that is inside the part.

-- Begin by creating a RemoteEvent. This can be done on the script or manually.
local Remote = Instance.new("RemoteEvent")

Remote.Name = "StartGravity"
Remote.Parent = game:GetService("ReplicatedStorage")

-- Establish the Touch event connection for the part.
script.Parent.Touched:Connect(function(Hit)
    -- This attempts to find the player that stepped on the part.
    local Player = game:GetService("Players"):GetPlayerFromCharacter(Hit.Parent)

    -- Checks that the player exists, and then fires the RemoteEvent.
    if Player ~= nil then
        Remote:FireClient(Player)
    end
end)

Next, put this code inside the local script that is within StarterCharacterScripts.

-- Define the RemoteEvent that the server created.
local Remote = game:GetService("ReplicatedStorage"):WaitForChild("StartGravity")

-- Create a function that performs the desired "gravity" code.
local function gravity()
    -- Paste the code from the existing local script here.
end

-- Create a debounce variable to prevent the gravity from starting multiple times.
local gravityStarted = false

-- Establish a connection to the RemoteEvent.
Remote.OnClientEvent:Connect(function()
    -- Check if gravity has been started or not.
    if not gravityStarted then
        -- Set gravityStarted to true, preventing future calls.
        gravityStarted = true

        -- Perform the function from above.
        gravity()
    end
end)

This should solve your issue, however I do not know the full structure of your workspace, nor do I know the content of the gravity local script. However, I wish you the best of luck. I commented all parts of my code as to provide the most comprehensive instruction possible.

  • Galactiq

Oh god. It worked thank you so much! Quick question. How would I make a brick that would make the Gravity local script turn off?

Would you mind copy and pasting the gravity script into this post?
Use ``` to wrap your code.

local Remote = game:GetService("ReplicatedStorage"):WaitForChild("StartGravity")

-- Create a function that performs the desired "gravity" code.
local function gravity()
	local PLAYERS = game:GetService("Players")
	local RUNSERVICE = game:GetService("RunService")

	local GravityController = require(game:GetService("ReplicatedStorage"):WaitForChild("GravityController"))
	local Controller = GravityController.new(PLAYERS.LocalPlayer)

	local PI2 = math.pi*2
	local ZERO = Vector3.new(0, 0, 0)

	local LOWER_RADIUS_OFFSET = 3 
	local NUM_DOWN_RAYS = 24
	local ODD_DOWN_RAY_START_RADIUS = 3	
	local EVEN_DOWN_RAY_START_RADIUS = 2
	local ODD_DOWN_RAY_END_RADIUS = 1.66666
	local EVEN_DOWN_RAY_END_RADIUS = 1

	local NUM_FEELER_RAYS = 9
	local FEELER_LENGTH = 2
	local FEELER_START_OFFSET = 2
	local FEELER_RADIUS = 3.5
	local FEELER_APEX_OFFSET = 1
	local FEELER_WEIGHTING = 8

	function GetGravityUp(self, oldGravityUp)
		local ignoreList = {}
		for i, player in next, PLAYERS:GetPlayers() do
			ignoreList[i] = player.Character
		end

		-- get the normal

		local hrpCF = self.HRP.CFrame
		local isR15 = (self.Humanoid.RigType == Enum.HumanoidRigType.R15)

		local origin = isR15 and hrpCF.p or hrpCF.p + 0.35*oldGravityUp
		local radialVector = math.abs(hrpCF.LookVector:Dot(oldGravityUp)) < 0.999 and hrpCF.LookVector:Cross(oldGravityUp) or hrpCF.RightVector:Cross(oldGravityUp)

		local centerRayLength = 25
		local centerRay = Ray.new(origin, -centerRayLength * oldGravityUp)
		local centerHit, centerHitPoint, centerHitNormal = workspace:FindPartOnRayWithIgnoreList(centerRay, ignoreList)

		local downHitCount = 0
		local totalHitCount = 0
		local centerRayHitCount = 0
		local evenRayHitCount = 0
		local oddRayHitCount = 0

		local mainDownNormal = ZERO
		if (centerHit) then
			mainDownNormal = centerHitNormal
			centerRayHitCount = 0
		end

		local downRaySum = ZERO
		for i = 1, NUM_DOWN_RAYS do
			local dtheta = PI2 * ((i-1)/NUM_DOWN_RAYS)

			local angleWeight = 0.25 + 0.75 * math.abs(math.cos(dtheta))
			local isEvenRay = (i%2 == 0)
			local startRadius = isEvenRay and EVEN_DOWN_RAY_START_RADIUS or ODD_DOWN_RAY_START_RADIUS	
			local endRadius = isEvenRay and EVEN_DOWN_RAY_END_RADIUS or ODD_DOWN_RAY_END_RADIUS
			local downRayLength = centerRayLength

			local offset = CFrame.fromAxisAngle(oldGravityUp, dtheta) * radialVector
			local dir = (LOWER_RADIUS_OFFSET * -oldGravityUp + (endRadius - startRadius) * offset)
			local ray = Ray.new(origin + startRadius * offset, downRayLength * dir.unit)
			local hit, hitPoint, hitNormal = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

			if (hit) then
				downRaySum = downRaySum + angleWeight * hitNormal
				downHitCount = downHitCount + 1
				if isEvenRay then
					evenRayHitCount = evenRayHitCount + 1					
				else
					oddRayHitCount = oddRayHitCount + 1
				end
			end
		end

		local feelerHitCount = 0	
		local feelerNormalSum = ZERO

		for i = 1, NUM_FEELER_RAYS do
			local dtheta = 2 * math.pi * ((i-1)/NUM_FEELER_RAYS)
			local angleWeight =  0.25 + 0.75 * math.abs(math.cos(dtheta))	
			local offset = CFrame.fromAxisAngle(oldGravityUp, dtheta) * radialVector
			local dir = (FEELER_RADIUS * offset + LOWER_RADIUS_OFFSET * -oldGravityUp).unit
			local feelerOrigin = origin - FEELER_APEX_OFFSET * -oldGravityUp + FEELER_START_OFFSET * dir
			local ray = Ray.new(feelerOrigin, FEELER_LENGTH * dir)
			local hit, hitPoint, hitNormal = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

			if (hit) then
				feelerNormalSum = feelerNormalSum + FEELER_WEIGHTING * angleWeight * hitNormal --* hitDistSqInv
				feelerHitCount = feelerHitCount + 1
			end
		end

		if (centerRayHitCount + downHitCount + feelerHitCount > 0) then
			local normalSum = mainDownNormal + downRaySum + feelerNormalSum
			if (normalSum ~= ZERO) then
				return normalSum.unit
			end
		end

		return oldGravityUp
	end

	Controller.GetGravityUp = GetGravityUp

	RUNSERVICE.Heartbeat:Connect(function(dt)
		local height = Controller:GetFallHeight()
		if height < -50 then
			Controller:ResetGravity(Vector3.new(0, 1, 0))
		end
	end)
end

-- Create a debounce variable to prevent the gravity from starting multiple times.
local gravityStarted = false

-- Establish a connection to the RemoteEvent.
Remote.OnClientEvent:Connect(function()
	-- Check if gravity has been started or not.
	if not gravityStarted then
		-- Set gravityStarted to true, preventing future calls.
		gravityStarted = true

		-- Perform the function from above.
		gravity()
	end
end) 

Can you also paste the GravityController module script code?

Also it is late for me, so I will resume this conversation some time tomorrow. Sorry for the abrupt leaving, but I really need to get off for the night. I will continue tomorrow and try to analyze the GravityController and see if I can help you toggle it on and off.

Oh it’s alright It’s late for me too. Here is the Module Script:

local PLAYERS = game:GetService(“Players”)
local RUNSERVICE = game:GetService(“RunService”)

local GravityController = require(game:GetService(“ReplicatedStorage”):WaitForChild(“GravityController”))
local Controller = GravityController.new(PLAYERS.LocalPlayer)

local PI2 = math.pi*2
local ZERO = Vector3.new(0, 0, 0)

local LOWER_RADIUS_OFFSET = 3
local NUM_DOWN_RAYS = 24
local ODD_DOWN_RAY_START_RADIUS = 3
local EVEN_DOWN_RAY_START_RADIUS = 2
local ODD_DOWN_RAY_END_RADIUS = 1.66666
local EVEN_DOWN_RAY_END_RADIUS = 1

local NUM_FEELER_RAYS = 9
local FEELER_LENGTH = 2
local FEELER_START_OFFSET = 2
local FEELER_RADIUS = 3.5
local FEELER_APEX_OFFSET = 1
local FEELER_WEIGHTING = 8

function GetGravityUp(self, oldGravityUp)
local ignoreList = {}
for i, player in next, PLAYERS:GetPlayers() do
ignoreList[i] = player.Character
end

– get the normal

local hrpCF = self.HRP.CFrame
local isR15 = (self.Humanoid.RigType == Enum.HumanoidRigType.R15)

local origin = isR15 and hrpCF.p or hrpCF.p + 0.35*oldGravityUp
local radialVector = math.abs(hrpCF.LookVector:Dot(oldGravityUp)) < 0.999 and hrpCF.LookVector:Cross(oldGravityUp) or hrpCF.RightVector:Cross(oldGravityUp)

local centerRayLength = 25
local centerRay = Ray.new(origin, -centerRayLength * oldGravityUp)
local centerHit, centerHitPoint, centerHitNormal = workspace:FindPartOnRayWithIgnoreList(centerRay, ignoreList)

local downHitCount = 0
local totalHitCount = 0
local centerRayHitCount = 0
local evenRayHitCount = 0
local oddRayHitCount = 0

local mainDownNormal = ZERO
if (centerHit) then
mainDownNormal = centerHitNormal
centerRayHitCount = 0
end

local downRaySum = ZERO
for i = 1, NUM_DOWN_RAYS do
local dtheta = PI2 * ((i-1)/NUM_DOWN_RAYS)

  local angleWeight = 0.25 + 0.75 * math.abs(math.cos(dtheta))
  local isEvenRay = (i%2 == 0)
  local startRadius = isEvenRay and EVEN_DOWN_RAY_START_RADIUS or ODD_DOWN_RAY_START_RADIUS	
  local endRadius = isEvenRay and EVEN_DOWN_RAY_END_RADIUS or ODD_DOWN_RAY_END_RADIUS
  local downRayLength = centerRayLength
  
  local offset = CFrame.fromAxisAngle(oldGravityUp, dtheta) * radialVector
  local dir = (LOWER_RADIUS_OFFSET * -oldGravityUp + (endRadius - startRadius) * offset)
  local ray = Ray.new(origin + startRadius * offset, downRayLength * dir.unit)
  local hit, hitPoint, hitNormal = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

  if (hit) then
  	downRaySum = downRaySum + angleWeight * hitNormal
  	downHitCount = downHitCount + 1
  	if isEvenRay then
  		evenRayHitCount = evenRayHitCount + 1					
  	else
  		oddRayHitCount = oddRayHitCount + 1
  	end
  end

end

local feelerHitCount = 0
local feelerNormalSum = ZERO

for i = 1, NUM_FEELER_RAYS do
local dtheta = 2 * math.pi * ((i-1)/NUM_FEELER_RAYS)
local angleWeight = 0.25 + 0.75 * math.abs(math.cos(dtheta))
local offset = CFrame.fromAxisAngle(oldGravityUp, dtheta) * radialVector
local dir = (FEELER_RADIUS * offset + LOWER_RADIUS_OFFSET * -oldGravityUp).unit
local feelerOrigin = origin - FEELER_APEX_OFFSET * -oldGravityUp + FEELER_START_OFFSET * dir
local ray = Ray.new(feelerOrigin, FEELER_LENGTH * dir)
local hit, hitPoint, hitNormal = workspace:FindPartOnRayWithIgnoreList(ray, ignoreList)

  if (hit) then
  	feelerNormalSum = feelerNormalSum + FEELER_WEIGHTING * angleWeight * hitNormal --* hitDistSqInv
  	feelerHitCount = feelerHitCount + 1
  end

end

if (centerRayHitCount + downHitCount + feelerHitCount > 0) then
local normalSum = mainDownNormal + downRaySum + feelerNormalSum
if (normalSum ~= ZERO) then
return normalSum.unit
end
end

return oldGravityUp
end

Controller.GetGravityUp = GetGravityUp

RUNSERVICE.Heartbeat:Connect(function(dt)
local height = Controller:GetFallHeight()
if height < -50 then
Controller:ResetGravity(Vector3.new(0, 1, 0))
end
end)

I need this:

local GravityController = require(game:GetService(“ReplicatedStorage”):WaitForChild(“GravityController”))

Paste the GravityController module code that is located under ReplicatedStorage.

local RunService = game:GetService(“RunService”)

local Utility = script:WaitForChild(“Utility”)
local CharacterModules = script:WaitForChild(“CharacterModules”)

local Maid = require(Utility:WaitForChild(“Maid”))
local Signal = require(Utility:WaitForChild(“Signal”))
local Camera = require(CharacterModules:WaitForChild(“Camera”))
local Control = require(CharacterModules:WaitForChild(“Control”))
local Collider = require(script:WaitForChild(“Collider”))
local StateTracker = require(script:WaitForChild(“StateTracker”))

– CONSTANTS

local TRANSITION = 0.15
local WALK_FORCE = 200 / 3
local JUMP_MODIFIER = 1.2

local ZERO3 = Vector3.new(0, 0, 0)
local UNIT_Y = Vector3.new(0, 1, 0)

– Class

local GravityControllerClass = {}
GravityControllerClass.__index = GravityControllerClass
GravityControllerClass.ClassName = “GravityController”

– Public Constructors

function GravityControllerClass.new(player)
local self = setmetatable({}, GravityControllerClass)

self.Player = player
self.Character = player.Character
self.Humanoid = player.Character:WaitForChild(“Humanoid”)
self.HRP = self.Humanoid.RootPart

self._gravityUp = UNIT_Y
self._characterMass = 0

self._camera = Camera.new(self)
self._control = Control.new(self)
self._collider = Collider.new(self)

self._fallStart = self.HRP.Position.y
self._prevPart = workspace.Terrain
self._prevCFrame = CFrame.new()

self.StateTracker = StateTracker.new(self)
self.Maid = Maid.new()

init(self)

return self
end

– Private Methods

local function getRotationBetween(u, v, axis)
local dot, uxv = u:Dot(v), u:Cross(v)
if dot < -0.99999 then return CFrame.fromAxisAngle(axis, math.pi) end
return CFrame.new(0, 0, 0, uxv.x, uxv.y, uxv.z, 1 + dot)
end

local function getModelMass(model)
local mass = 0
for _, part in pairs(model:GetDescendants()) do
if part:IsA(“BasePart”) and not part.Massless then
mass = mass + part:GetMass()
end
end
return mass
end

local function onJumpRequest(self)
if not self.StateTracker.Jumped and self._collider:IsGrounded(true) then
local vel = self.HRP.Velocity
self.HRP.Velocity = vel + self._gravityUpself.Humanoid.JumpPowerJUMP_MODIFIER
self.StateTracker:RequestJump()
end
end

local function onHeartbeat(self, dt)
local standingPart = self._collider:GetStandingPart()

if standingPart and self._prevPart and self._prevPart == standingPart then
local offset = self._prevCFrame:ToObjectSpace(self.HRP.CFrame)
self.HRP.CFrame = standingPart.CFrame * offset
end

self._prevPart = standingPart
self._prevCFrame = standingPart and standingPart.CFrame
end

local function onGravityStep(self, dt)
local camCF = workspace.CurrentCamera.CFrame

– update the gravity vector
local oldGravity = self._gravityUp
local newGravity = self:GetGravityUp(oldGravity)

local sphericalArc = getRotationBetween(oldGravity, newGravity, camCF.XVector)
local lerpedArc = CFrame.new():Lerp(sphericalArc, TRANSITION)

self._gravityUp = lerpedArc * oldGravity

– get world move vector
local fDot = camCF.ZVector:Dot(newGravity)
local cForward = math.abs(fDot) > 0.5 and math.sign(fDot)*camCF.YVector or -camCF.ZVector

local left = -cForward:Cross(newGravity).Unit
local forward = -left:Cross(newGravity).Unit

local move = self._control:GetMoveVector()
local worldMove = forwardmove.z - leftmove.x

local isInputMoving = false
local length = worldMove.Magnitude
if length > 0 then
isInputMoving = true
worldMove = worldMove / length
end

– get the desired character cframe
local hrpLook = -self.HRP.CFrame.ZVector
local charForward = hrpLook:Dot(forward)*forward + hrpLook:Dot(left)*left
local charRight = charForward:Cross(newGravity).Unit

local newCharRotation = CFrame.new()
local newCharCF = CFrame.fromMatrix(ZERO3, charRight, newGravity, -charForward)

if self._camera.CameraModule:IsCamRelative() then
newCharCF = CFrame.fromMatrix(ZERO3, -left, newGravity)
elseif isInputMoving then
newCharRotation = newCharRotation:Lerp(getRotationBetween(
charForward,
worldMove,
newGravity
), 0.7)
end

– calculate forces
local g = workspace.Gravity
local gForce = g * self._characterMass * (UNIT_Y - newGravity)

local cVelocity = self.HRP.Velocity
local tVelocity = self.Humanoid.WalkSpeed * worldMove
local gVelocity = cVelocity:Dot(newGravity)*newGravity
local hVelocity = cVelocity - gVelocity

if hVelocity:Dot(hVelocity) < 1 then
hVelocity = ZERO3
end

local dVelocity = tVelocity - hVelocity
local dVelocityM = dVelocity.Magnitude

local walkForceM = math.min(10000, WALK_FORCE * self._characterMass * dVelocityM / (dt*60))
local walkForce = walkForceM > 0 and (dVelocity / dVelocityM)*walkForceM or ZERO3

local charRotation = newCharRotation * newCharCF

self.StateTracker:Update(self._gravityUp, self._collider:IsGrounded(false), isInputMoving)
self._collider:Update(walkForce + gForce, charRotation)
end

function init(self)
self.Maid:Mark(self._camera)
self.Maid:Mark(self._control)
self.Maid:Mark(self._collider)

self._characterMass = getModelMass(self.Character)
self.Maid:Mark(self.Character.AncestryChanged:Connect(function()
self._characterMass = getModelMass(self.Character)
end))

self.Humanoid.PlatformStand = true
self.Maid:Mark(self.Humanoid:GetPropertyChangedSignal(“Jump”):Connect(function()
if self.Humanoid.Jump then
onJumpRequest(self)
self.Humanoid.Jump = false
end
end))

self.Maid:Mark(self.StateTracker.Changed:Connect(function(state, speed)
if state == Enum.HumanoidStateType.Freefall then
self._fallStart = self.HRP.Position:Dot(self._gravityUp)
end
end))

self.Maid:Mark(RunService.Heartbeat:Connect(function(dt)
onHeartbeat(self, dt)
end))

RunService:BindToRenderStep(“GravityStep”, Enum.RenderPriority.Camera.Value - 1, function(dt)
onGravityStep(self, dt)
end)

self.Humanoid.StateChanged:Wait()
self.StateTracker.Changed:Fire(self.StateTracker.State, 0)
end

– Public Methods

function GravityControllerClass:ResetGravity(gravity)
self._gravityUp = gravity
self._fallStart = self.HRP.Position:Dot(gravity)
end

function GravityControllerClass:GetFallHeight()
if self.StateTracker.State == Enum.HumanoidStateType.Freefall then
local height = self.HRP.Position:Dot(self._gravityUp)
return height - self._fallStart
end
return 0
end

function GravityControllerClass:GetGravityUp(oldGravity)
return oldGravity
end

function GravityControllerClass:Destroy()
RunService:UnbindFromRenderStep(“GravityStep”)
self.Maid:Sweep()
self.Humanoid.PlatformStand = false
end

return GravityControllerClass