You have a typo:
if v.CameraMode == Enum.CameraMode.LockFistPerson then
You missed the 'r' in "First".
(The rest of this post is relevant even if that typo wasn't in your original script).
Sometimes Roblox won't tell you about an error. In that case, it's good to employ "print" debugging -- add print statements throughout your code (that is, the area of the code you are debugging) to figure out exactly what's running (deleting them when you fix the bug, of course). If you need to test it online, don't forget that you can read what the print statements say in the Developer Console (press F9 to open it).
ex, I might debug it like this:
function onCall(plr, message)
print(plr, "chatted", message)
if message:sub(1, 13):lower() == ":thirdperson " then
print(plr, "chatted thirdperson")
local victim = findTargets(plr, message:sub(14))
print(#victim, " victims detected")
for i, v in pairs(victim) do
coroutine.resume(coroutine.create(function()
print("About to do if statement for", v)
if v.CameraMode == Enum.CameraMode.LockFirstPerson then
print("About to switch to Classic mode for", v)
v.CameraMode = Enum.CameraMode.Classic
else
print(v, "did not have FirstPerson camera. CameraMode:", v.CameraMode)
end
end))
end
end
end))
end
If a print statement gives unexpected output, or doesn't even get run, this will inform you of what's actually going on. ex, if print(plr, "chatted thirdperson") --prove that the if statement worked was the last thing you saw in the output before a print(plr, "chatted", message) message, this would tell you that findTargets is encountering an error.
Do be careful: while using print statements to debug your program, it is very easy to introduce new bugs (ex if you assume something's not nil when -in reality - it could be).
Also, don't forget to remove the coroutines, which serve no purpose in this function. If you need to prove it to yourself, try experiments with them. ex, put this script in a new place:
function test(i, doWait)
print("Starting test", i)
if doWait then wait(0.5) end
print("Ending test", i)
end
print("Tests all at once")
for i = 1, 3 do
coroutine.resume(coroutine.create(function() wait() test(i, false) end))
end
wait(0.1)
print("Tests that wait")
for i = 1, 3 do
coroutine.resume(coroutine.create(function() wait() test(i, true) end))
end
Tests all at once
Starting test 1
Ending test 1
Starting test 2
Ending test 2
Starting test 3
Ending test 3
Tests that wait
Starting test 1
Starting test 2
Starting test 3
Ending test 1
Ending test 2
Ending test 3
The first set of tests proves that if the coroutine doesn't wait, the coroutine will finish before letting the next one start (if you want better proof of this, put in a for loop that runs for a 100k iterations -- it'll lag your computer for a fraction of a second or so, and you'll note that the same output is displayed). The second set of tests show what happens when a coroutine does wait: it lets the next coroutine start/resume.
[EDIT] I discovered that error messages are hidden when you use coroutines and the error message occurs before/without a 'wait' command. You can display the error message by checking the return value of 'coroutine.resume', which will return true if there was no immediate error or else false, errorMsg.
3 comments
Can you think of any reason at all this script should be using coroutines?
So that if multiple people are calling commands and so everyone has the commands used at the same time(?). Also, removing them does nothing to fix the script's current problem.
If 'onCall' is getting called from an event (ex OnChatted), each one gets its own coroutine anyway, so you don't need them here. Further, since this function doesn't use wait commands, it'd work the same way even if everyone was on one coroutine (since only one coroutine runs at a time in lua).