Can't call function in module script

Also why are you using the self parameter? When the contextactionservice calls module.forward it’s not gonna pass in module. It’s just going to pass actionName, inputState, and inputObject.

I am passing the self parameter to change the position of the drone, as you can see there’s something called “self.direction = self.direction + Vector3.new(0,0,-1)”

Well, then the function has to be inside the module.
Exp:
local commands = {} commands.forwards = function(sender, dataTable) end return commands

What do you mean? The function is in the module script. I am getting an error trying to call it from the other script.

It has to be inside the table. I’ve always did it for my admin commands module.

1 Like

Thank you! I am pretty new to module scripts, thanks!

Yeah but your code says.

ContextActionService:BindAction("Forwards", module.forward, false, Enum.PlayerActions.CharacterForward)

Basically it’s not going to pass a reference to module. To do what you’d like you’d want to change it so that ContextActionService calls a function.

local function handleForward(actionName, inputState, inputObject)
  module:forwards(actionName, inputState, inputObject)
end
ContextActionService:BindAction("Forwards", handleForward, false, Enum.PlayerActions.CharacterForward)

Otherwise if you do it the way you’re currently doing it. It will call module.forwards(actionName, inputState, inputObject) where self = nil.

Well um it doesn’t give an error saying it’s nil but it’s not changing positions, but I think this is it.

No, but he cant call the function in first place from the module cause its not inside the module table that he’s referring to…

Exactly, which is why he’d want to make an instance of the drone. And then use the variable he set that instance to.

MyDrone:Forwards()

Nvm, I see what you’re saying. He’s trying to call a private function from a module. Oof.

Yeah, it would work but he’d have to restructure the code. Seems like he’s trying to use metatables but not quite there yet

This is why the second argument was returning nil cause he simply did not include it in the table of the module script. And was referring to it from another local script not from the module itself.

This might be a good start for your module script. Should return a instance of “Drone” that you can use. Though to get it to return instances you would need to setup a new method which acts as a constructor.

local Drone = {}
local Drone_mt = {__index = Drone}

function Drone:Forwards(actionName, userInputState, inputObject)
 -- logic here.
end


return setmetatable({}, Drone_mt)

You can mark the solution reply (so another having same problem can find the answer) and no problem always here to help in my free time :slight_smile:. If you have any more problems with you script you can create new post.

1 Like

I do have a new method, I didn’t show it though. And is there any way to call the function just for that new object?

Edit: I also changed it to: newDrone.forwards yet seems like the drone is still not moving around.

Edit 2: I tried to print when the function is called, and it does print it out yet the drone is not moving anywhere.

To call it for the specific instance the script would look something like this.

local DroneModule = require(game.ReplicatedStorage:WaitForChild("Drone"))
local MyDrone = DroneModule.new()

local function handleForward(actionName, inputState, inputObject)
   MyDrone:Forwards(actionName, inputState, inputObject)
end

ContextActionService:BindAction("Forwards", handleForward, false, Enum.PlayerActions.CharacterForward)

When you use MyDrone.Forwards(self, actionName, inputState, inputObject) it’s equal to MyDrone:Forwards(actionName, inputState, inputObject) as self is passed implicitly with the : .

The real issue here is, you can’t set ContextActionService to just use MyDrone.Forwards because by default ContextActionService does not pass MyDrone as the first argument. So this is why you’d want to use the handleForward function which allows you to call the instance’s method manually.

First, I would recommend creating a remote event to fire from the local script and then from the server script to call that function from the module (so it would be server-sided). Second, transfer the object (drone) in the function so you can reference it in the function.

This way you will only need one Module Script for all drones and it will be server sided.

1 Like

Well good suggestion! Yet I forgot that self.direction is not updating. I need to make it so it updates right?

I usually just add an update method to an instance. And then use RunService to call that new method with the step from the RunService function.

local RunService = game:GetService("RunService")
local DroneInstances = {}

RunService.Stepped:Connect(function(step)
  for i,v in pairs(DroneInstances) do
     v:Update(step)
   end
end)

Then inside of that actual update method you can run the logic you need which updates the properties of the instance. You don’t have to do it this way. You can also hook into the GetPropertyChangedSignals from a instance if you have a direct reference to it. It’s also reasonable to subscribe to those events when the class instance is created using the .new method.

Though the players can’t move, that’s why I made a forwards function.