I am trying to inherit a baseclass to a subclass using strict mode and typechecking. The baseclass in question is BaseMovement. I set the metatable to {}, basemovement and inside the constructor I did setmetatable(BaseMovement.new() :: any, Sprint).
local Sprint = setmetatable({}, BaseMovement)
Sprint.__index = Sprint
export type ClassType = typeof( setmetatable({} :: {
_connections: Trove.ClassType;
}, Sprint) )
--// constructor
function Sprint.new(): ClassType
local self = {
_connections = Trove.new()
}
setmetatable(BaseMovement.new() :: any, Sprint)
return self
end
--// ALL METHODS USE SELF: CLASSTYPE
function Sprint.Bind(self: ClassType, actionName, inputState, _inputObject): ()
if inputState == Enum.UserInputState.Begin then
CameraTweenIn:Play()
end
if inputState == Enum.UserInputState.End then
CameraTweenOut:Play()
end
end
How do I fix this? ALL METHODS USE SELF: CLASSTYPE
I’m a little confused by how you’re doing the inheritance. Did you get this method from a tutorial? It looks like you aren’t applying the inheritance to the new object in the constructor at all, because you never call setmetatable on it.
I have done this method before but not with strict mode.
--!nonstrict
local BaseClassController = require(script.BaseClassController)
local Example = setmetatable({}, BaseCharacterController)
Example.__index = Example
function Example.new()
local self = setmetatable(BaseClassController.new() :: any, Example)
-- this will now inherit all of the things in baseclass
self.aaaa = nil
self.character = self:GetCharacter() -- method stored inside of BaseClassController
-- which is now autocompletable.
return self
end
-- Assuming BaseMovement is correctly defined elsewhere
local BaseMovement = require(path.to.BaseMovement)
local Trove = require(path.to.Trove) -- Make sure this is correctly required
local Sprint = setmetatable({}, {__index = BaseMovement})
Sprint.__index = Sprint
-- Assuming you have a valid `ClassType` for Trove or adjust as necessary
export type SprintType = {
_connections: any; -- Adjust based on your Trove type definitions
Bind: (self: SprintType, actionName: string, inputState: Enum.UserInputState, _inputObject: any) -> ();
} & BaseMovement.ClassType -- Assuming BaseMovement has a type definition to inherit
function Sprint.new(): SprintType
local self = setmetatable({
_connections = Trove.new(),
}, Sprint)
return self
end
function Sprint:Bind(actionName, inputState, _inputObject)
if inputState == Enum.UserInputState.Begin then
-- Assuming CameraTweenIn is defined elsewhere
CameraTweenIn:Play()
end
if inputState == Enum.UserInputState.End then
-- Assuming CameraTweenOut is defined elsewhere
CameraTweenOut:Play()
end
end
return Sprint
--!strict
--[[
Sprint sub-class
--]]
--// roblox services
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
--// variables
local CurrentCamera = workspace.CurrentCamera
local CameraTweenIn = TweenService:Create(CurrentCamera, TweenInfo.new(0.2), {FieldOfView = 75})
local CameraTweenOut = TweenService:Create(CurrentCamera, TweenInfo.new(0.2), {FieldOfView = 70})
--// Dependencies
local PlayerSettings = require(ReplicatedStorage.PlayerSettings)
local BaseMovement = require(script.Parent.BaseMovement)
local Trove = require(ReplicatedStorage.Packages._Index["sleitnick_trove@1.1.0"]["trove"])
--// class
local Sprint = setmetatable({}, {__index = BaseMovement})
Sprint.__index = Sprint
export type ClassType = {
_connections: Trove.ClassType,
Bind: (self: ClassType, actionName: string, inputState: Enum.UserInputState, _inputObject: any) -> ();
} & BaseMovement.ClassType -- Assuming BaseMovement has a type definition to inherit
--// constructor
function Sprint.new(): ClassType
local self = setmetatable({
_connections = Trove.new(),
}, Sprint)
return self
end
function Sprint.Bind(self: ClassType, actionName, inputState, _inputObject): ()
if not self.character then
return
end
local Character = self.character
local Humanoid = Character:FindFirstChild("Humanoid") :: Humanoid
if inputState == Enum.UserInputState.Begin then
CameraTweenIn:Play()
Humanoid.WalkSpeed = PlayerSettings.CharacterSprintSpeed
end
if inputState == Enum.UserInputState.End then
CameraTweenOut:Play()
Humanoid.WalkSpeed = PlayerSettings.CharacterWalkSpeed
end
end
function Sprint.GetParameters()
return {
actionName = "Sprint", -- mandatory
createTouchButton = false, -- optional, will always be false on default
inputs = { -- mandatory
Enum.KeyCode.LeftShift,
Enum.KeyCode.RightShift
}
}
end
return Sprint.new()
When I removed the Bind Type, I got a shorter warning:
Here’s the Base Class if you need it. Thanks for your help .
--!strict
--[[
The base class for 'movement' // superclass
--]]
--// roblox services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--// Dependencies
local Trove = require(ReplicatedStorage.Packages._Index["sleitnick_trove@1.1.0"]["trove"])
--// class
local BaseMovement = {}
BaseMovement.__index = BaseMovement
export type ClassType = typeof( setmetatable({} :: {
character: Model?;
BaseConnections: Trove.ClassType;
isWalking: boolean;
isSprinting: boolean;
isWallrunning: boolean;
isFloating: boolean;
isSliding: boolean;
}, BaseMovement) )
function BaseMovement.new(): ClassType
local self = {
character = nil,
-- states?
isWalking = false,
isSprinting = false,
isWallrunning = false,
isFloating = false,
isSliding = false,
BaseConnections = Trove.new()
}
setmetatable(self, BaseMovement)
task.spawn(function()
while task.wait(3) do
print(self.isSprinting)
end
end)
self:_init()
return self
end
function BaseMovement._init(self: ClassType): ()
self.BaseConnections:Connect(Players.LocalPlayer.CharacterAdded, function(character: Model)
if not self.character then
self.character = character
end
end)
if Players.LocalPlayer then
if not self.character then
self.character = Players.LocalPlayer.Character:: Model
end
end
end
function BaseMovement.GetCharacter(self: ClassType): ()
return self.character
end
return BaseMovement
Here is some improvements integrated into your base class script if you need it
--!strict
--[[
The base class for 'movement' // superclass
--]]
--// roblox services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
--// Dependencies
local Trove = require(ReplicatedStorage.Packages._Index["sleitnick_trove@1.1.0"]["trove"])
--// class
local BaseMovement = {}
BaseMovement.__index = BaseMovement
export type ClassType = typeof(setmetatable({} :: {
character: Model?;
BaseConnections: Trove.ClassType;
isWalking: boolean;
isSprinting: boolean;
isWallrunning: boolean;
isFloating: boolean;
isSliding: boolean;
}, BaseMovement))
function BaseMovement.new(): ClassType
local self = {
character = nil,
-- states?
isWalking = false,
isSprinting = false,
isWallrunning = false,
isFloating = false,
isSliding = false,
BaseConnections = Trove.new()
}
setmetatable(self, BaseMovement)
task.spawn(function()
while task.wait(3) do
print(self.isSprinting)
end
end)
self:_init()
return self
end
function BaseMovement._init(self: ClassType): ()
self.BaseConnections:Connect(Players.LocalPlayer.CharacterAdded, function(character: Model)
if not self.character then
self.character = character
end
end)
if Players.LocalPlayer.Character then
self.character = Players.LocalPlayer.Character
end
end
function BaseMovement.GetCharacter(self: ClassType): Model?
return self.character
end
return BaseMovement
-- Assuming Sprint and BaseMovement.ClassType are defined elsewhere and compatible.
local MyClass = setmetatable({}, Sprint)
MyClass.__index = MyClass
function MyClass.new()
local instance = setmetatable({
_connections = {}; -- Assuming Trove.ClassType or similar initialization here.
}, MyClass)
return instance
end
-- Example method definition
function MyClass:ExampleMethod()
print("Example method called")
end
-- Assuming BaseMovement.ClassType has its methods and properties defined elsewhere.
-- You would then manually ensure that MyClass includes those methods and properties,
-- either through direct definition or metatable manipulation.
return MyClass