Как правильно связать информацию о юните с самим юнитом на клиенте

20 Дек 2016
892
170
Я сделал свой манабар, инфа о нем хранится для каждого юнита в поле. Часть этой информации должна отправляться на клиент, чтобы отображать манабар и его состояние. Я реализовал это так:
Есть таблица, в которой ключи - индексы юнитов, а значения - таблицы с необходимой информацией. Эта таблица отправляется на клиент 30 раз в секунду, и там уже происходит дальнейшая обработка. Вот необходимая часть кода:
RegisterManaBarC Вызывается для каждого юнита при первом спавне.
Финкер для UpdateManaClientC устанавливается после пика.
Две таблицы с инфой для клиента я сделал потому, что как выяснилось, индекс юнита может внезапно поменяться в процессе игры. Поэтому в одной я в качестве ключей использую хендлы юнитов, и перебираю по ней; а в другой ключи это индексы юнитов, ее я отправляю на клиент.
Lua:
_G.ManaBarRegistredUnits = ManaBarRegistredUnits or {}
_G.ManaBarRegistredUnitsIndex = {}
function CDOTA_BaseNPC:RegisterManaBarC()
    if self:GetMaxMana() <= 0 then return end
 
    self.manabar = table.deep_copy( ManaBar )
 
    local unitKV = HeroesKV[ self:GetUnitName() ] or UnitsKV[ self:GetUnitName() ]
    if unitKV then
        self.manabar.mana_base = unitKV.StatusMana or self.manabar.mana_base
        self.manabar.regen_base = unitKV.StatusManaRegen or self.manabar.regen_base
    end
 
    self:AddNewModifier( self, nil, "custom_manabar", {} )
    self:CheckAbilitiesManacost()
 
    ManaBarRegistredUnits[ self ] = {}
end

function _G.UpdateManaClientC()
    for unit in pairs( ManaBarRegistredUnits ) do
        if unit == nil or unit:IsNull() then
            ManaBarRegistredUnits[ unit ] = nil
        else
         
            local abilities = {}
            local slot = 0
            for i = 0, unit:GetAbilityCount()-1 do
                ability = unit:GetAbilityByIndex(i)
                if ability and not ability:IsHidden() and not ability:IsAttributeBonus() then
                    abilities[ slot ] = ability:GetManaCostC()
                    slot = slot + 1
                end
            end
         
            local manainfo = {
                maxmana = unit:GetMaxManaC(),
                mana = unit:GetManaC(),
                regen = unit:GetManaRegenC(),
                abilities = abilities
            }
         
            ManaBarRegistredUnits[ unit ] = manainfo
            ManaBarRegistredUnitsIndex[ unit:entindex() ] = manainfo
         
        end
    end
 
    CustomGameEventManager:Send_ServerToAllClients( "UpdateManaBarInfo", ManaBarRegistredUnitsIndex )

    return 1/30
end
Проблема в том, что UpdateManaClientC после непродолжительной игры вызывает вот такое говно в консоли:
1546204215339.png
(В прошлой моей подобной теме это происходило по той же причине, просто тогда я даже предположить не мог из-за чего это)
При чем эти сообщения продолжают прилетать даже на паузе (что не удивительно, ибо финкер паузой не останавливается)

Собственно, в чем проблема и как ее исправить?
Мб во вложенности, тогда можно отправлять эвент для каждого юнита по отдельности, просто читал где-то, что обильный обмен сообщениями между клиентом-сервером тоже ни к чему хорошему не приводит. Сам этого еще не проверил, ибо прежде чем кардинально менять систему, мне хотелось бы быть уверенным, что это изменение поможет. Да и вложенность тут неизбежна, ибо abilities должно быть таблицей полюбому.

Те кто шарит, помогите плиз, уже не первый месяц с этой херней страдаю.
 

Дикий Пёс

Друзья CG
28 Июн 2017
411
96
Проект
Petri Reborn
я конечно не 1337 про кодер, но мне кажется, что 30 раз в секунду это слишком много, как вариант обновлять только когда какое-либо значение меняется(мб это очевидно, я хз)
 
20 Дек 2016
892
170
Если предположить, что на карте 10 героев, у каждого из которых не фуллмана, поэтому из-за ее регенерации она меняется 10 раз в секунду, то это будет уже 100 сообщений в секунду. Правда, в них достаточно отправлять информацию только об одном конкретном юните, а не о всех сразу, как я это делаю сейчас.
 

HappyFeedFriends

Друзья CG
14 Авг 2017
540
32
Проект
Battle Heroes Arena
Если предположить, что на карте 10 героев, у каждого из которых не фуллмана, поэтому из-за ее регенерации она меняется 10 раз в секунду, то это будет уже 100 сообщений в секунду. Правда, в них достаточно отправлять информацию только об одном конкретном юните, а не о всех сразу, как я это делаю сейчас.
разве на клиенте нету готовых при показывающих характеристики юнита? Привязывая это всё через портрет.
 

shesmu

Продвинутый
22 Фев 2018
158
22
Entities.GetMana( Players.GetLocalPlayerPortraitUnit() ) Entities.GetManaThinkRegen( Players.GetLocalPlayerPortraitUnit() )
 
20 Дек 2016
892
170
Мне нужна кастомная механика манабара, поэтому функции для получения текущей маны/регена у меня тоже кастомные, и они по очевидным причинам только на луа.
 

Дикий Пёс

Друзья CG
28 Июн 2017
411
96
Проект
Petri Reborn
но в любом случае отправлять то ты будешь только значение маны, остальные значения меняются гораздо реже
 

HappyFeedFriends

Друзья CG
14 Авг 2017
540
32
Проект
Battle Heroes Arena
Мне нужна кастомная механика манабара, поэтому функции для получения текущей маны/регена у меня тоже кастомные, и они по очевидным причинам только на луа.
Значит собирай одну таблицу, и меняй её, если в ней что-то изменилось.
 

shesmu

Продвинутый
22 Фев 2018
158
22
А можно эту таблицу обновлять каждые 0.03 секунд, а отправлять ее на клиент раз в 0.1 секунд, ведь на клиент надо отправлять только для отображения в интерфейсе(как я понял), а игрок разницы между 0.03 и 0.1 глазами не увидит, но я не особо шарю, поэтому мб что-то не понимаю
 
Последнее редактирование:
20 Дек 2016
892
170
Какая разница буду я отправлять 30 раз в секунду или 10 раз в секунду, если у меня через 20 минут кастомка падает? Так будет падать через час, а у меня игры могут и дольше продлиться.
 

HappyFeedFriends

Друзья CG
14 Авг 2017
540
32
Проект
Battle Heroes Arena

I_GRIN_I

Друзья CG
15 Мар 2016
1,335
105
CustomNetTables:SetTableValue( string TableName, string KeyName, script_table Value )
 

HappyFeedFriends

Друзья CG
14 Авг 2017
540
32
Проект
Battle Heroes Arena
CustomNetTables:SetTableValue( string TableName, string KeyName, script_table Value )
Я конечно не намекаю, но мне кажется он именно так и делает. Хотя возможно,он отправляет инфу с помощью CustomEvents,каждые 1/30,тогда бы я сказал, что можно делать с помощью schedule на клиенте, но я не знаю.
 

HappyFeedFriends

Друзья CG
14 Авг 2017
540
32
Проект
Battle Heroes Arena
Тебе правильно дали. Обновлять таблицу, а из нее получать всю инфу.
 
Реклама: