- What do you want to achieve?
- I want to resolve an issue with the movement between waypoints.
- What is the issue?
- Sometimes, when it reach the end of a waypoint, it get teleportation-like behavior, which is unintended and affects the smoothness of the movement.
- What solutions have you tried so far?
- I’ve attempted to address the issue by adjusting the movement and waypoint logic, but the problem persists. I’ve also looked for solutions on the Devforum without success.
Description:
- The movement issue occurs when it reach the end of a waypoint. Instead of smoothly transitioning to the next waypoint, it seem to teleport back a bit.
My localscript
-- local ReplicatedStorage = game:GetService("ReplicatedStorage")
local TweenService = game:GetService("TweenService")
local player = game.Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")
local pokemonsData = {}
local pokemonsDataEvent = ReplicatedStorage:WaitForChild("PokemonsData")
local pokemonModels = ReplicatedStorage:WaitForChild("Pokemons") -- Assuming you have a folder with Pokemon models
local function tweenPokemon(pokemonId, pokemonName, startPosition, endPosition, speed)
local pokemonModel = pokemonModels:FindFirstChild(pokemonName)
if pokemonModel then
if not workspace:WaitForChild("PokemonFolder"):FindFirstChild(pokemonId) then
local clonedPokemon = pokemonModel:Clone()
clonedPokemon.Name = pokemonId -- Name the cloned Pokemon using the pokemonId
clonedPokemon.Parent = workspace:WaitForChild("PokemonFolder") -- Assuming you have a folder to hold the Pokemon models
clonedPokemon.PrimaryPart.Position = startPosition
end
local pokemon = workspace:WaitForChild("PokemonFolder"):FindFirstChild(pokemonId)
local primaryPart = pokemon.PrimaryPart
local direction = (endPosition - startPosition).Unit
local lookAt = CFrame.new(primaryPart.Position, primaryPart.Position + direction)
local tweenInfoPos = TweenInfo.new((endPosition - primaryPart.Position).Magnitude / speed, Enum.EasingStyle.Linear)
local tweenInfoRota = TweenInfo.new((endPosition - primaryPart.Position).Magnitude / speed * 2, Enum.EasingStyle.Linear)
local positionGoal = {}
positionGoal.Position = endPosition
local rotationGoal = {}
rotationGoal.CFrame = lookAt
local positionTween = TweenService:Create(primaryPart, tweenInfoPos, positionGoal)
local rotationTween = TweenService:Create(primaryPart, tweenInfoRota, rotationGoal)
positionTween:Play()
rotationTween:Play()
end
end
pokemonsDataEvent.OnClientEvent:Connect(function(updatedPokemonsData)
pokemonsData = updatedPokemonsData
for _, data in pairs(pokemonsData) do
if data.Health <= 0 then
local deadPokemon = workspace.PokemonFolder:FindFirstChild(data.pokemonId)
if deadPokemon then
deadPokemon:Destroy()
end
else
tweenPokemon(data.pokemonId, data.Name, data.StartPos, data.EndPos, data.Speed)
end
end
end)
ModuleScript
--
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Pokemons = ReplicatedStorage.Pokemons
local RunService = game:GetService("RunService")
local WaveManager = {}
function WaveManager.new(map, difficulty)
local self = {}
local waveData = require(game.ServerScriptService.WaveData)
local PokemonStatsEnemy = require(game.ServerScriptService.PokemonStatsEnemy)
local waveInfo = {
Easy = {waves = 10, coinMultiplier = 10, healthMultiplier = 1},
Normal = {waves = 20, coinMultiplier = 25, healthMultiplier = 1.5},
Hard = {waves = 30, coinMultiplier = 50, healthMultiplier = 2.5},
Expert = {waves = 50, coinMultiplier = 100, healthMultiplier = 5},
Nightmare = {waves = 70, coinMultiplier = 250, healthMultiplier = 15},
Impossible = {waves = 100, coinMultiplier = 500, healthMultiplier = 50}
}
local currentWave = 0
local pokemonsData = {}
local uniqueIdCounter = 0 -- Unique identifier counter
local function generateUniqueId()
uniqueIdCounter = uniqueIdCounter + 1
return uniqueIdCounter
end
local function updatePokemonPosition(pokemonId, currentWaypoint, elapsedTime, speed)
local waypoints = workspace.Path.Waypoints
local startPosition = waypoints[currentWaypoint].Position
local endPosition = waypoints[currentWaypoint + 1].Position
local totalDistance = (endPosition - startPosition).Magnitude
local Speed = totalDistance / speed --pokemon.PrimaryPart.WalkSpeed
local progress = elapsedTime / Speed
if progress <= 1 then
local newPosition = startPosition:Lerp(endPosition, progress)
local pokemonData = pokemonsData[pokemonId]
if pokemonData then
pokemonData.StartPos = startPosition
pokemonData.EndPos = newPosition
end
end
end
local function moveToNextWaypoint(pokemonId, pokemon, currentWaypoint, speed)
local waypoints = workspace.Path.Waypoints
local startTime = tick()
if currentWaypoint <= #waypoints:GetChildren() - 1 then
local elapsedTime = 0
while elapsedTime <= (waypoints[currentWaypoint + 1].Position - waypoints[currentWaypoint].Position).Magnitude / speed do
elapsedTime = tick() - startTime
updatePokemonPosition(pokemonId, currentWaypoint, elapsedTime, speed)
wait()
end
print(pokemon .. ' reached waypoint ' .. currentWaypoint)
moveToNextWaypoint(pokemonId, pokemon, currentWaypoint + 1, speed)
else
print(pokemon .. ' reached the end of waypoints')
end
end
local function spawnPokemon(pokemonName, parentFolder)
if not parentFolder then
parentFolder = workspace:FindFirstChild("PokemonFolder")
if not parentFolder then
parentFolder = Instance.new("Folder")
parentFolder.Name = "PokemonFolder"
parentFolder.Parent = workspace
end
end
local pokemon = Pokemons:FindFirstChild(pokemonName)
if pokemon and parentFolder then
local startPosition = workspace.Path.Waypoints[1].CFrame.Position
local maxHealth = PokemonStatsEnemy[pokemonName].maxHealth
local speed = PokemonStatsEnemy[pokemonName].speed
local uniqueId = generateUniqueId()
local pokemonId = pokemonName .. "_" .. uniqueId
local pokemonData = {Name = pokemonName, pokemonId = pokemonId, StartPos = startPosition, EndPos = startPosition, Health = maxHealth, maxHealth = maxHealth, Speed = speed}
pokemonsData[pokemonId] = pokemonData -- Use the Pokemon's name as the key
moveToNextWaypoint(pokemonId, pokemonName, 1, speed) -- Start moving the Pokemon
end
end
local function spawnWave()
currentWave = currentWave + 1
local mapData = waveData[map]
if mapData then
local difficultyData = mapData[difficulty]
if difficultyData then
local currentWaveData = difficultyData[currentWave]
if currentWaveData then
print("Wave " .. currentWave .. " on " .. map .. " has started!")
for _, pokemonData in ipairs(currentWaveData) do
for _ = 1, pokemonData.Quantity do
spawnPokemon(pokemonData.Pokemon)
wait(0.5)
end
end
else
print("No more waves for difficulty: " .. difficulty)
end
else
warn("Invalid difficulty level.")
return
end
else
warn("Invalid map.")
return
end
end
local function rewardPlayer()
local rewardCoins = waveInfo[difficulty].coinMultiplier * currentWave
print("Wave " .. currentWave .. " cleared! You earned total " .. rewardCoins .. " coins.")
end
function self.startWaves()
for wave = 1, waveInfo[difficulty].waves do
spawnWave()
repeat
wait(.1)
until #workspace:FindFirstChild("PokemonFolder"):GetChildren() == 0
rewardPlayer()
print('Starting next wave in: 3')
wait(1)
print('Starting next wave in: 2')
wait(1)
print('Starting next wave in: 1')
wait(1)
end
local rewardCoins = waveInfo[difficulty].coinMultiplier * currentWave * 10
print("All waves cleared! You earned total " .. rewardCoins .. " coins.")
end
local count = 0
RunService.Heartbeat:Connect(function()
count = count + 1
if count >= 10 then
count = 0
if next(pokemonsData) then
print(pokemonsData['Bulbasaur_1'].StartPos, pokemonsData['Bulbasaur_1'].EndPos)
ReplicatedStorage.PokemonsData:FireAllClients(pokemonsData)
end
end
end)
return self
end
return WaveManager
I think is maby because updatePokemonPosition in the ModuleScript.
local function updatePokemonPosition(pokemonId, currentWaypoint, elapsedTime, speed)
local waypoints = workspace.Path.Waypoints
local startPosition = waypoints[currentWaypoint].Position
local endPosition = waypoints[currentWaypoint + 1].Position
local totalDistance = (endPosition - startPosition).Magnitude
local Speed = totalDistance / speed --pokemon.PrimaryPart.WalkSpeed
local progress = elapsedTime / Speed
if progress <= 1 then
local newPosition = startPosition:Lerp(endPosition, progress)
local pokemonData = pokemonsData[pokemonId]
if pokemonData then
pokemonData.StartPos = startPosition
pokemonData.EndPos = newPosition
end
end
end