Jump to content

Accessing HUD from anywhere


Recommended Posts

My goal is to add more feedback on my custom meter by adding pulses to it, like the sanity badge when pulsing red or green. My intent is to make something like this :

-- inst is the player instance in that case ; hud_hat is the special hud i've added in statusdisplays
inst.HUD.controls.status.hud_hat:PulseGreen()

 

I put my widget creation context as well, just in case :

-- Context : The following line is added in my modmain to add my custom widget to statusdisplays
AddClassPostConstruct("widgets/statusdisplays", OnStatusDisplaysConstructed)

-- Context : snipped code that adds the widget
local function OnStatusDisplaysConstructed(inst)

    -- Don't add special meter if it's not the modded character
	if inst.owner.prefab ~= "myCharacter" then
        return
    end
    
    -- Create a new hud in StatusDisplays by adding a child in a new variable
    inst.hud_hat = inst:AddChild( hatmeter(inst, inst.owner) )

    -- [...]
end

 

However, I'm having serious issues understanding how accessing HUD works. I've read several files on how to access it, but it doesn't work for me for some reasons.

Consider the following code, that is contained into the OnEquip function of a hat :

--Method OnEquip (inst, owner), where inst is the hat instance, and owner, the hat owner when equipped
if owner:HasTag("player") then
        TheNet:SystemMessage("Owner is really the player!", true)
        
        local ownerHUD = owner.HUD
        local theplayer = ThePlayer
        local theGlobalPlayer = _G.ThePlayer -- same as GLOBAL.ThePlayer but GLOBAL is not defined in the hat file so I use _G directly
    
        if ownerHUD then
            TheNet:SystemMessage("OK", true)
        else
            TheNet:SystemMessage("No HUD in " .. tostring(owner), true)
        end
        
        if theplayer then
            TheNet:SystemMessage("OK", true)
        else
            TheNet:SystemMessage("Unable to get ThePlayer", true)
        end
        
        if theGlobalPlayer then
            TheNet:SystemMessage("OK", true)
        else
            TheNet:SystemMessage("Unable to get ThePlayer with GLOBAL", true)
        end

    end

 

All tests fail and I struggle to know why.

Owner.HUD is null and I don't understand why because :

  1. My modded player inherits from player_common, who has HUD as a variable ;
  2. Woodie.lua uses inst.HUD.controls.status:SetWereMode for the wereness mode to update the UI and works fine.

Both ThePlayer are null. I've seen a lot of code that use ThePlayer.HUD to access the UI but I don't know why it does not work in my case, even when explicitly saying that ThePlayer is defined in GLOBAL : it makes sense that "theplayer" would not work, but not "theGlobalPlayer".

What am I forgetting here ?

  • Like 1
Link to comment
Share on other sites

I suspect that you are doing this in a world with caves?

This is probably the cause:

inst.HUD only exists on the client. Your OnEquip function is only run on the server. So all attempts to access inst.HUD will be nil, as it's nil on the server.

You will need to use netvars or a ClientModRPC to achieve what you want :)

  • Like 1
Link to comment
Share on other sites

1 hour ago, Monti18 said:

I suspect that you are doing this in a world with caves?

This is probably the cause:

inst.HUD only exists on the client. Your OnEquip function is only run on the server. So all attempts to access inst.HUD will be nil, as it's nil on the server.

You will need to use netvars or a ClientModRPC to achieve what you want :)

Urgh... I was afraid of that answer. I indeed have caves, since I'm always testing on a configuration where you can have the full DST features. I was wondering if I would need to use another netvars... Well, seems I will be obliged to do that. :?

However, I still don't understand why the line would work in woodie.lua. A player playing Woodie is a prefab instanciated server-side, right ? So why inst.HUD is not null in that case ?

  • Like 1
Link to comment
Share on other sites

If you have a look at woodie.lua, you can see that the function that sets the weremode where also HUD is called is SetWereMode. 

Now lets backtrack to see where this is coming from:

It's called in OnWereModeDirty and SetGhostMode.

OnWereModeDirty is called in OnPlayerActivated.

OnPlayerActivated and SetGhostMode are called in the common_postinit.

common_postinit is run on both the server and client on when the prefab is initialized. So if you want to access the HUD from the prefab, you need to do it from the common_postinit.

You can do something like this:

--character prefab

local function MakePulse(inst)
	if inst.HUD and inst.HUD.controls.hud_hat then
		inst.HUD.controls.status.hud_hat:PulseGreen()
	end
end


--common_postinit of character

inst.hat_meter_pulse = net_event(inst.GUID,"hat_meter_pulse")
if not TheWorld.ismastersim then
	inst:ListenForEvent("hat_meter_pulse",MakePulse)
end

--onequip function of hat

local function OnEquip(inst,owner)
	if owner and owner.hat_meter_pulse ~= nil then
		owner.hat_meter_pulse:push()
	end
end

We make a net_event, which is the same as a net_bool just that it fires the listenforevent when you use push(), so no need to always change from false to true and back to fire the event.

Then we add a function that makes the hat meter pulse which is only called if you are the client.

Then you push this event if you equip the hat.

Hope that helps, if you have more questions let me know!

Edited by Monti18
  • Like 1
  • Thanks 1
Link to comment
Share on other sites

7 hours ago, Monti18 said:

common_postinit is run on both the server and client on when the prefab is initialized. So if you want to access the HUD from the prefab, you need to do it from the common_postinit.

That's something I completely missed so it explain a lot.

Thanks a lot for the net_event example. I can't wait to test it out !

  • Like 2
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
  • Create New...