So i'm making a system that runs through a list of "Tutorial Steps" during a tutorial, in sequence. the tutorial steps could be anything, but to guarantee some shared structure i've made an 'abstract' class TutorialStep. each unique type of tutorial step uses this as its metatable and __index, like this PressWASDStep for example:
TutorialStep.lua
local TutorialStepAbstract = {Name = "Tutorial Step"}
--setmetatable(TutorialStepAbstract, TutorialStepAbstract);
TutorialStepAbstract.isComplete = false;
function TutorialStepAbstract:new()
local o = {};
setmetatable(o, self);
self.__index = self;
--setmetatable(self, TutorialStepAbstract);
return o
end
function TutorialStepAbstract:IsComplete()
return self.isComplete;
end
function TutorialStepAbstract:Begin()
print("beginning step: "..self.Name);
end
return TutorialStepAbstract;
PressWASDStep.lua
local TutorialStep = require(game.ReplicatedStorage.PPatrol_ReplicatedStorage.Tutorial.TutorialStep);
local UserInputService = game:GetService("UserInputService");
local HelperTChat = require(game.ReplicatedStorage.PPatrol_ReplicatedStorage.Modules.HelperTChat);
local Step = {}
--Step.__index = Step;
function Step:new()
local o = TutorialStep:new();
--setmetatable(o, self);
--self.__index = self;
o.Name = "Press WASD Step";
o.isComplete = false;
o.WPressed = false;
o.APressed = false;
o.SPressed = false;
o.DPressed = false;
return o;
end
--function Step:IsComplete()
-- return self.isComplete;
--end
function Step:Begin()
task.spawn(function ()
local messagedismisscallback = HelperTChat.ShowNewMessage("'You are currently at the patient's artery! Let’s start by going over how to move. Use the WASD keys to move.'", "nouserdimiss", "large");
while not self.isComplete do
self.WPressed = self.WPressed or UserInputService:IsKeyDown(Enum.KeyCode.W);
self.APressed = self.APressed or UserInputService:IsKeyDown(Enum.KeyCode.A);
self.SPressed = self.SPressed or UserInputService:IsKeyDown(Enum.KeyCode.S);
self.DPressed = self.DPressed or UserInputService:IsKeyDown(Enum.KeyCode.D);
if self.WPressed and self.APressed and self.SPressed and self.DPressed then
self.isComplete = true;
print("completing step "..self.Name);
messagedismisscallback();
end
task.wait();
end
end, self)
end
return Step
the issue is, when i call CurrentStep:IsComplete()
, it looks for the function in PressWASDStep, doesn't find it, and invokes the IsComplete()
in TutorialStep, as it should. But the underlying property, self.isComplete
, is always false here, because TutorialStep's self.isComplete
and and PressWASDStep's self.isComplete
are different variables.
I could get around this by referring to isComplete
directly, but i'd rather figure out how to do this seemingly basic thing with lua, and i wouldn't be able to do anything else in :IsComplete()
if i chose to later. I could also reimplement :IsComplete()
in PressWASDStep, but then i'm losing the usefulness of a superclass/abstract class.
Is there a way to have the line self.isComplete = true;
in PressWASDStep modify the property of its metatable instead of defining/modifying a property of itself? i'm not sure if that's the right way to phrase it, but essentially i want to have one shared property isComplete
that is accessible to both TutorialStep and PressWASDStep.
Thanks for any help!