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!