And then I have a script which has a function to check if what the player inputted matches with any of the moves and it works however turns out there’s an issue where if there’s multiple moves that start with the same input it doesn’t know which one to do. So if I’m trying to do the grab move I’ll go press G, but my code is gonna think I’m trying to do light punch and yeah. How can I fix this?
If you’re still planning it out then the easiest solution is try not to match up keys at the front of a sequence - for example, if you want all your moves to start with G, instead make them end with G and keep the different parts of the code at the start.
The other option which is a bit more work and has a bit of latency is to add a key delay where the next key needs to be pressed before a certain time. If I press G then the script will have to wait X amount of time in order to know if I really only want to do a light punch or if I want to continue entering keys for a different move. Then there is a balance in making the delay short enough so it doesn’t feel laggy for shorter sequences and still long enough to allow flexible timing.
Hm you think you could give me an example of how how I could add a key delay? By the way my current script is all connected to a RenderStep so it’s constantly running and I use a thing called a FIFO queue which I thought I needed, but I’m starting to feel like maybe I don’t need it, but basically when a key is entered it gets put into a queue and then added to a table.
Main.UIS.InputBegan:Connect(function(inputObj, processed)
if (processed) or (Modules.PauseGame.Paused) then return end
local Key = Main.UIS:GetStringForKeyCode(inputObj.KeyCode)
if CommandInputs[Key] then
AddToFrame(Key)
local input = CommandInputs[Key]
--push input to the queue
Queue:push({INPUT = input, TIME = tick()})
end
end)
--This is inside a function which is connected to a RenderStepped
AddToInputSequence(data['INPUT'])
local function AddToInputSequence(input)
table.insert(InputSequence, input)
CheckSequence()
end
What I would do is to make a sort of timer system where it would work like this
Detected input start timer
Put input into array
Wait an specified amount of time
If an input occurs within that time then restart the timer.
Else check the input and try to match with the dictionary of different combos.
So, maybe something like this.
local ComboInput = {}
local ComboActive = false
local ComboLength = 0
local PrevComboLength = 0
local ComboInputSpeed = 0.3
UserInputService.InputBegan:Connect(function(InputObject,GameProccessed)
if GameProccessed then return end
if InputObject.UserInputType == Enum.UserInputType.Keyboard then
if not ComboActive then
ComboInput = {}
end
if InputObject.KeyCode == (Enum.KeyCode.G or Enum.KeyCode.R) then -- You should put all the keys that can be available to be used for a combo
table.insert(ComboInput,InputObject.KeyCode)
-- Here is where the combo check will do
PrevComboLength = #ComboInput
delay(ComboInputSpeed,function() -- User has 0.3 seconds to press another key. If not the fight code runs
ComboLength = #ComboInput -- We are using the fact that when we add a move to a combo the length changes. So if the length hasn't changed in the 0.3 seconds we will run the fight code.
if ComboInput == <find the combo that is correct> then -- NOTE: I highly reccommend you use a string instead of an array here. I have used an array so checking if an array is the same as another requires a lot more code than an if statement. I think it is much more simpler to use a string to hold combos as it is a lot more easier to understand and more readable. Plus the elements don't really need to be separated.#
if ComboLength == PrevComboLength then
--FIght code here
--Fight code for each combo should be put here.
end
end
end)
end
end
end)
I am pretty sure this will work. Let me know if it doesn’t.
Of course there might be a better solution due to the fight code will not run only after 0.3 seconds.
I think it might even be better to lessen the combo length time between keypress
Then I think that is where you would put your wait time code - when you call CheckSequence, wait X time before you pick which move to use. Have a counter that represents the number of keys pressed - you store that number locally in the function before you wait, and then after the wait, check if the updated number has increased (ie the function was called again for another key press). If the number went up from what it was at the start of the function call then another key was pressed so you don’t do anything and let the new function call handle picking which move to use with the updated key list. Once a move is selected just reset the counter.
Well this is just one idea, @koziahss also has some good ideas
So I’m a bit confused although I might just be to tired to understand this lol, but basically if I’m understanding this correctly inside the function I’d do this?
local function CheckSequence()
local KeysPressed = 0
wait(1) --just an example idk how to long to actually wait for
--check stuff
end
The only thing is how would I increase this? because it’s just gonna reset every time it gets called unless you mean put the counter outside of the function which probably makes more sense.
Also here’s the current CheckSequence function if you’re itnerested.
local function CheckSequence()
local commandInputIndex = 0 --stores the index of the InputSequence table
local lastMatchIndex = 0 --stores the last matching move
local matchedInputCount = 0 --stores the amount of matching inputs
for moveIndex = 1, #Moveset do
commandInputIndex = ((#InputSequence - 1) + 1) --makes sure that it always stays at 1
matchedInputCount = 0 --sets it to zero for each move in the moveset
--walk backwards through the sequence
for inputIndex = #Moveset[moveIndex].Sequence, 1, -1 do
--"consume" the InputSequence until it is no more or we found our target input.
while (commandInputIndex >= 0) do
if Moveset[moveIndex].Sequence[inputIndex] == InputSequence[commandInputIndex] then
matchedInputCount += 1
break
end
commandInputIndex -= 1 --decrease the InputSequence's index
end
end
if (matchedInputCount == #Moveset[moveIndex].Sequence) then
lastMatchIndex = moveIndex
local move = Moveset[lastMatchIndex]
if not Compare(move.Sequence, InputSequence) then
for i, moveData in pairs(Moveset) do
if Compare(moveData.Sequence,InputSequence) then
move = moveData
break
end
end
end
print("you performed: "..move.Name)
Modules.ClientCombat:MoveInputted(move)
InputSequence = {} --reset InputSequence table
end
end
end
So trying to do this right now, but lol I for some reason just have no idea what I’m doing this is what I tried to do.
local Counter = 0
Main.UIS.InputBegan:Connect(function(inputObj, processed)
Counter += 1
end)
local function CheckSequence()
local OldCounter = Counter
wait(1)
if KeysPressed == OldKeysPressed then
--Code here?
end
end
local function CheckSequence()
Counter += 1
local OldCounter = Counter
wait(1)
if OldCounter == Counter then
--Code here?
end
end
Instead of hooking Counter to update on any UIS input event, update it in CheckSequence since you are controlling when it is called. Plus you don’t want to check against the old key because if one of your combos is ‘G’-‘G’-__ for example then you won’t be able to catch consecutive same-key presses.
Nah it’s not any key I have this in the input event
local Key = Main.UIS:GetStringForKeyCode(inputObj.KeyCode)
if CommandInputs[Key] then
KeysPressed += 1
end
although I didn’t eve think about increasing the counter inside the function so I’ll do that. Anyways overall this seems to work the only thing that sucks is having to delay the input, but it doesn’t seem like it’s that noticeable.
If the delay thing is too noticeable then having a startup animation that doesn’t use the full effect of the move can let you still make it feel responsive but while keeping the delay to overwrite a new move if more keys are pressed afterwards. Though obviously this requires much more work to setup in terms of adjusting animations and timing everything. Ideally, finding the sweet spot for the delay should be the first thing to try and see if it improves the experience without needing startup animations.