So I'm making a custom animation script for a custom character on Roblox. The AI works fine but it will almost always only play idle animations even with humanoid events.
What should normally happen is when the monster is Idle the idle animation should play. When walking the walk animation should play. And when the AI attacks, the attack animation should play.
I've dried commenting out the idle animation part, but then no animations play at all.
Here's the code:
local myHuman = script.Parent.Humanoid
local walkAnim = myHuman:LoadAnimation(script.Parent.Walk)
local idleAnim = myHuman:LoadAnimation(script.Parent.Idle)
local jumpAnim = myHuman:LoadAnimation(script.Parent.Jump)
myHuman.Running:Connect(function(speed)
if speed > 3 then
walkAnim:Play()
else
walkAnim:Stop()
idleAnim:Play()
end
end)
myHuman.Jumping:Connect(function()
jumpAnim:Play()
end)
myHuman.Died:Connect(function()
for i,v in pairs(myHuman:GetPlayingAnimationTracks()) do
v:Stop()
end
end)
Try adding a print instead of the animation and see what happens and tell me if it prints anything.
myHuman.Running:Connect(function(speed)
if speed > 3 then
print("walk")
else
print("start idle")
end
end)
Edit: https://devforum.roblox.com/t/getplayinganimationtracks-is-deprecated/1075650 I believe that you must do
myHuman.Animator:getPlayingAnimationTracks()
Related
I was trying to make a music player for my game, however, when I was trying to get my sound to play it refused to work. The games output works before and after the sound, but I can't hear anything. I tried using both a folder and sound group (what I'm using currently) and both did not work. How would I fix this? I presume it has something to do with client-server but I am not sure.
local ss = game:WaitForChild("SoundService")
local rp = game:WaitForChild("ReplicatedStorage")
local list = ss.Music:GetChildren()
rp.SongOn.OnServerEvent:Connect(function(plr)
repeat
local num = math.random(1, #list)
print(num)
local track = list[num]
local name = track.Name
print(name)
plr.PlayerGui.Overhead.Notch.SongTitle.Text = track.Name
local song = ss.Music:WaitForChild(name)
print("played")
wait(track.TimeLength)
print("waited length")
until
rp.SongOff.OnServerEvent
end)
You never play anything. You don't actually reproduce the Sound. To run a Sound, use Sound:Play()
https://create.roblox.com/docs/reference/engine/classes/Sound
Your repeat until condition is also wrong. The music will not stop playing once that event is fired, and it will actually not matter at all - when the loop finishes running once, it will compare if literally rp.SongOff.OnServerEvent evaluates to true. OnServerEvent is the literal event itself, which will be true since it is not false or nil. So the loop will stop running when it runs once.
Instead, you likely want to make a function that plays the music, and run this function whenever:
Playing music is requested with the remote
The playing music naturally ends (https://create.roblox.com/docs/reference/engine/classes/Sound#Ended)
And then, bind to that stop music remote a function that stops the sound.
Also you should have some more shame, you didn't even try to hide you're making a nazi game
I have the following code in my Roblox game:
local DataStoreService = game:GetService("DataStoreService")
local myDataStore = DataStoreService:GetDataStore("myDataStore")
function saveCurrentStats(player)
print("saveCurrentStats")
local success, errormessage = pcall(function()
myDataStore:SetAsync(player.UserId.."-foundcats", player.FoundCats.Value)
end)
if success then
print("Progress successfully saved")
else
print("Error while saving progress")
warn(errormessage)
end
print("saveCurrentStats done")
end
game.Players.PlayerRemoving:Connect(function(player)
saveCurrentStats(player)
end)
Often this works - the data is saved for the player. But quite often I also only get something like this in the output:
18:18:38.708 saveCurrentStats - Server - Script:66
So I get neither if nor else printout (and the data is also indeed not saved)
Is there something I should do to make this robust? Like wait for something at some point.
Problem started to happen more often when my project grew, and the reason is that when running the game from Roblox Studio the script is just terminated when you hit the stop button. It will not be given time to execute, and with a larger project the chance of running the script decreases.
A work-around is to type this in the command bar instead of pressing the stop button:
game:GetService("Players").LocalPlayer:Kick()
This allows you to run the script properly when testing the game in Roblox Studio. When running the game live the issue is not seen, since then the script execution is not terminated prematurely.
I am trying to make a LoadCharacter() script, but when it runs it makes the player load several times before they actually load.
Here is the code:
game.Players.PlayerAdded:Connect(function(player)
game.ReplicatedStorage.Remotes.LoadCharacter.OnServerEvent:Connect(function()
player:LoadCharacter()
end)
player:LoadCharacter()
end)
BTW I disabled CharacterAutoLoad.
Your issue is that your connection is inside the PlayerAdded event. It is causing the event to register callbacks every single time a player joins. So when any player fires the event, it is causing EVERYONE to reload their character.
So just move the connection outside it, and get the player object from the RemoteEvent. The first argument from OnServerEvent is always the player that called FireServer so you don't need to make any changes to your LocalScript.
game.Players.PlayerAdded:Connect(function(player)
player:LoadCharacter()
end)
game.ReplicatedStorage.Remotes.LoadCharacter.OnServerEvent:Connect(function(player)
player:LoadCharacter()
end)
I am using events in Lua I subscribe with:
Runtime:addEventListener("balanceChanged", onBalanceChanged)
And raise them with
Runtime:dispatchEvent({ name = "balanceChanged" })
Now in onBalanceChanged, I want to do some animation on the screen that may take a few seconds to finish - but during this time the same event can be dispatched again.
How to I ensure that the onBalanceChanged function is only executed one at a time, aka if it's currently executing, wait for it to finish before carrying on?
ex:
local isAnimOver = false
function playAnimation()
if not isAnimover then
isAnimOver = true
-- here play the animation
--- Once the animation is over then set the flag to
isAnimOver = false
end
end
I'm new to Corona. I'm not sure how to solve this.
In main I am creating 2 local objects, player and enemy.
Player has a function called takeDamage.
When I try to call player.takeDamage from within enemy, it can't see the function.
I presume it's because main owns both objects and they don't know about each other.
How can I have Enemy call that function so that it can deal damage to Player?
main.lua contains:
-- Create player character
local player = require("player");
player = player.new();
-- Create enemy character
local enemy = require("enemy");
enemy = enemy.new();
I think I could make player global, but from what I know, that would not be a best practice.
Any help would be greatly appreciated.
If it is safe to assume that there will be only one "player" instance, you can make it global. Otherwise, you would have to do something along these lines:
-- main.lua
local player = require 'player'.new()
local enemy = require 'enemy'.new()
enemy:setPlayer(player)
-- enemy.lua
...
function enemy:setPlayer(player)
self.player = player
end
And later use self.player in the enemy code to reference the player. Note that this will consume memory, because the player reference will be copied to every enemy instance.
One side note, I do not consider it good to call a module and an instance the same, i.e. player. It will become unclear later if you mean the module, or the instance. A safe way would be to call the modules as Player and Enemy, and the code will look like this:
Player = require 'Player'
local player = Player.new()
Ideally, you don't want the player referencing the enemy directly or the enemy referencing the player. Instead, you could poll each participant in a game loop and update the game state based on the result.
local player = make_player()
local enemy = make_enemy()
--game loop - in a real game this isn't a busy while
while true do
local move = player.move()
local result = validate_move(move)
if result.is_valid then
update_position(player, result)
end
move = enemy.move()
result = validate_move(move)
if result.is_valid then
update_position(enemy, result)
end
local attack = player.attack()
local attack_result = validate_attack(attack)
if attack_result.hit then
update_health(enemy, attack_result)
end
-- more game logic here
render(player)
render(enemy)
end
In a real game, state change would be driven by events - touch events, drawing events, etc. My busy loop (while true do) illustrates the general idea.
You'll also have to use your imagination for missing implementation.
There are many ways to model a game. I'm not suggesting this is the best. It does, however, show one way of decoupling interacting elements.