Want players to have a reference to an entity

Okay the server’s going to make an entity like a waypoint or something and I need to send that to players so they can draw it on their HUDs. How should I do this?

Updatin

I tried sending the entity through a usermessage but that only gives the position once, and I’d have to keep sending usermessages to keep it updated. Is this too expensive?

If the checkpoint is moving, send the entity and work out it’s position on the client.

I don’t really understand when you say ‘only gives the position once’. Usually checkpoints are stationary.

It’s not a checkpoint I was using that as an example, I’m trying to move a client’s view to wherever some entity is, but the entity moves. So far I’ve got it working by sending a usermessage with the entity’s position in GM:Think, is there a better way to do this or did I do it right?

[lua]
– /gamemode/cl_init.lua
function GM:CalcView( pl, origin, angles, fov )
local view = {}
view.origin = pl:GetNWEntity(‘myent’):GetPos()
view.angles = angles
view.fov = fov
return view
end[/lua]

[lua]
– somewhere on the server:
pl:SetNWEntity(‘myent’, ent )
[/lua]

[lua]-- Shared File
if (SERVER) then
– Serverside
umsg.PoolString(“SetViewEntity”);
umsg.PoolString(“ResetViewEntity”);
–[[
Set the player’s view entity to tracking something
Use SetPlayerViewEntity(ply,ent) to set the view entity,
or SetPlayerViewEntity(ply,NULL) to disable the view.
]]–
function SetPlayerViewEntity(ply,ent)
if (IsValid(ent)) then
SendUserMessage(“SetViewEntity”,ply,ent);
else
SendUserMessage(“ResetViewEntity”,ply);
end
end
else
– Clientside
usermessage.Hook(“SetViewEntity”,function(msg)
LocalPlayer()._ViewEnt = msg:ReadEntity();
end);
usermessage.Hook(“ResetViewEntity”,function()
LocalPlayer()._ViewEnt = nil;
end);
hook.Add(“CalcView”,“ViewEntity”,function(ply, origin, angles,fov)
if (IsValid(ply._ViewEnt)) then
return {
origin = ply._ViewEnt:GetPos(),
angles = ply._ViewEnt:GetAngles(),
fov = fov;
};
end
end);
end[/lua]

Okay I understand most of that, but what is ._ViewEnt

Just a random variable name, you can call it ViewEnt, poopiecrap, or anything else and it would still work.
Basically, all you really need to do is send the entity to the player (the entity, not its position), retrieve it on the client, and then use it like any other entity.

Only problem I’d see with this method is that it will have an incorrect position for players who can’t see it (when it’s ouside their PVS), so if your entity is moving and you should be able to see it through walls, it might be problematic.

Would DEADBEEF’s solution avoid that problem?

No.

[editline]09:42PM[/editline]

To clarify, my version is DEADBEEF’s taken and made into an actual workable solution, rather than a throwaway “do it something like this” scrap of code.

Then I should just send vectors in usermessages instead with positions and angles and just calc the view clientside?

No, you just need to add the ent’s origin to the player’s PVS.
Like so:
[lua]-- Shared File
if (SERVER) then
– Serverside
umsg.PoolString(“SetViewEntity”);
umsg.PoolString(“ResetViewEntity”);
–[[
Set the player’s view entity to tracking something
Use SetPlayerViewEntity(ply,ent) to set the view entity,
or SetPlayerViewEntity(ply,NULL) to disable the view.
]]–
function SetPlayerViewEntity(ply,ent)
if (IsValid(ent)) then
SendUserMessage(“SetViewEntity”,ply,ent);
ply._ViewEnt = ent;
else
SendUserMessage(“ResetViewEntity”,ply);
ply._ViewEnt = nil;
end
end
– Ensure the view ent is always in the player’s PVS.
hook.Add(“SetupPlayerVisibility”, “ViewEntityPVSFix”, function(ply)
if (IsValid(ply._ViewEnt)) then
AddOriginToPVS(ply._ViewEnt:GetPos());
end
end);
else
– Clientside
usermessage.Hook(“SetViewEntity”,function(msg)
LocalPlayer()._ViewEnt = msg:ReadEntity();
end);
usermessage.Hook(“ResetViewEntity”,function()
LocalPlayer()._ViewEnt = nil;
end);
hook.Add(“CalcView”,“ViewEntity”,function(ply, origin, angles,fov)
if (IsValid(ply._ViewEnt)) then
return {
origin = ply._ViewEnt:GetPos(),
angles = ply._ViewEnt:GetAngles(),
fov = fov;
};
end
end);
end[/lua]

Sorry for my throwaway scrap of code.
I didn’t want to do it all for him as there’s no future value in that.

I prefer to point someone in the right direction and let them figure the rest out for themselves.

I still wouldn’t use usermessages though, just send the ent as a networked entity added to the player’s metatable.

Why? A NWEntity is far more wasteful than a usermessage.
If (admittedly unlikely but still) you had 64 players on the server, and each one required a view entity, using a NWEntity would send 4096 usermessages, 4032 of which would be because you didn’t want the minor extra fuss of manually catching view entity updates.

Where do you get 4096 usermessages from?

How do you figure that it takes 64 usermessages to set a single NWEntity?

[editline]11:54PM[/editline]

Actually yeah, I see what you’re saying it’s only the individual client which needs to know what their view entity is.
For some reason I thought you meant 4096 messages received by each client.

Unless it were absolutely necessary I wouldn’t use view entities anyway, just let the client sort their own camera position themselves.

.