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

20 Дек 2016
566
113
28
11
Проект
DI:LS
Реакции
113 0 0
#1
Я сделал свой манабар, инфа о нем хранится для каждого юнита в поле. Часть этой информации должна отправляться на клиент, чтобы отображать манабар и его состояние. Я реализовал это так:
Есть таблица, в которой ключи - индексы юнитов, а значения - таблицы с необходимой информацией. Эта таблица отправляется на клиент 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 после непродолжительной игры вызывает вот такое говно в консоли:

(В прошлой моей подобной теме это происходило по той же причине, просто тогда я даже предположить не мог из-за чего это)
При чем эти сообщения продолжают прилетать даже на паузе (что не удивительно, ибо финкер паузой не останавливается)

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

Те кто шарит, помогите плиз, уже не первый месяц с этой херней страдаю.
 
28 Июн 2017
139
43
18
Проект
Petri Reborn
Реакции
42 0 1
#2
я конечно не 1337 про кодер, но мне кажется, что 30 раз в секунду это слишком много, как вариант обновлять только когда какое-либо значение меняется(мб это очевидно, я хз)
 
20 Дек 2016
566
113
28
11
Проект
DI:LS
Реакции
113 0 0
#3
Если предположить, что на карте 10 героев, у каждого из которых не фуллмана, поэтому из-за ее регенерации она меняется 10 раз в секунду, то это будет уже 100 сообщений в секунду. Правда, в них достаточно отправлять информацию только об одном конкретном юните, а не о всех сразу, как я это делаю сейчас.
 
14 Авг 2017
513
44
28
18
Проект
Battle Heroes Arena
Реакции
43 0 1
#4
Если предположить, что на карте 10 героев, у каждого из которых не фуллмана, поэтому из-за ее регенерации она меняется 10 раз в секунду, то это будет уже 100 сообщений в секунду. Правда, в них достаточно отправлять информацию только об одном конкретном юните, а не о всех сразу, как я это делаю сейчас.
разве на клиенте нету готовых при показывающих характеристики юнита? Привязывая это всё через портрет.
 

shesmu

Продвинутый
22 Фев 2018
157
34
18
23
Реакции
31 0 3
#5
Entities.GetMana( Players.GetLocalPlayerPortraitUnit() ) Entities.GetManaThinkRegen( Players.GetLocalPlayerPortraitUnit() )
 
Реклама:
20 Дек 2016
566
113
28
11
Проект
DI:LS
Реакции
113 0 0
#6
Мне нужна кастомная механика манабара, поэтому функции для получения текущей маны/регена у меня тоже кастомные, и они по очевидным причинам только на луа.
 

Дикий Пёс

Активный
28 Июн 2017
139
43
18
Проект
Petri Reborn
Реакции
42 0 1
#7
но в любом случае отправлять то ты будешь только значение маны, остальные значения меняются гораздо реже
 
14 Авг 2017
513
44
28
18
Проект
Battle Heroes Arena
Реакции
43 0 1
#8
Мне нужна кастомная механика манабара, поэтому функции для получения текущей маны/регена у меня тоже кастомные, и они по очевидным причинам только на луа.
Значит собирай одну таблицу, и меняй её, если в ней что-то изменилось.
 

shesmu

Продвинутый
22 Фев 2018
157
34
18
23
Реакции
31 0 3
#9
А можно эту таблицу обновлять каждые 0.03 секунд, а отправлять ее на клиент раз в 0.1 секунд, ведь на клиент надо отправлять только для отображения в интерфейсе(как я понял), а игрок разницы между 0.03 и 0.1 глазами не увидит, но я не особо шарю, поэтому мб что-то не понимаю
 
Последнее редактирование:
20 Дек 2016
566
113
28
11
Проект
DI:LS
Реакции
113 0 0
#10
Какая разница буду я отправлять 30 раз в секунду или 10 раз в секунду, если у меня через 20 минут кастомка падает? Так будет падать через час, а у меня игры могут и дольше продлиться.
 
Реклама:
14 Авг 2017
513
44
28
18
Проект
Battle Heroes Arena
Реакции
43 0 1
#11

I_GRIN_I

Друзья CG
15 Мар 2016
1,063
77
48
20
Реакции
76 0 1
#12
CustomNetTables:SetTableValue( string TableName, string KeyName, script_table Value )
 
14 Авг 2017
513
44
28
18
Проект
Battle Heroes Arena
Реакции
43 0 1
#13
CustomNetTables:SetTableValue( string TableName, string KeyName, script_table Value )
Я конечно не намекаю, но мне кажется он именно так и делает. Хотя возможно,он отправляет инфу с помощью CustomEvents,каждые 1/30,тогда бы я сказал, что можно делать с помощью schedule на клиенте, но я не знаю.
 
Реклама:
14 Авг 2017
513
44
28
18
Проект
Battle Heroes Arena
Реакции
43 0 1
#16
14 Авг 2017
513
44
28
18
Проект
Battle Heroes Arena
Реакции
43 0 1
#17
Тебе правильно дали. Обновлять таблицу, а из нее получать всю инфу.
 
Реклама: