OnPlayerUnvanished
OnPlayerUnvanished is called on the server right after a player is switched back to visible with the debug.invis console command. It fires after collision and player-query registration have already been restored.
void OnPlayerUnvanished(BasePlayer player)Parameters
| Parameter | Type | Description |
|---|---|---|
player | BasePlayer | The BasePlayer whose visibility was just restored. Safe to read position, identity and team data from it, but not guaranteed to be connected at the moment the hook fires. |
Return value
The return value is ignored. The command always continues to reply to the caller and to send the invisibility UI update, whether or not the hook returned a value.
How it works
The hook fires only from the debug.invis admin console command when it runs the code path that turns invisibility off. The game first re-adds the player to server query and clears the AI ignore list, then calls OnPlayerUnvanished before it writes the Invis: false reply and triggers the debug.setinvis_ui command on the client. That means by the time your plugin runs, the player is already targetable and visible again. The single argument is the BasePlayer being revealed; you can use it for admin audit logging, restoring combat state, broadcasting a staff message, or re-applying any gameplay restrictions you lifted while the player was hidden. The parameter type is already the most specific useful one, so there is nothing to narrow. Because the hook is driven by a console command, it never fires for players who simply disconnect, sleep, or are killed while invisible, so pair it with OnPlayerVanish / OnPlayerUnvanish if you need full coverage.
Example plugin: Audit and announce admin vanish state changes
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
namespace Oxide.Plugins
{
[Info("Vanish Audit", "RustPluginGenerator", "1.0.0")]
[Description("Logs and optionally announces when a player becomes invisible or visible via debug.invis")]
public class VanishAudit : RustPlugin
{
private const string PermAnnounce = "vanishaudit.announce";
private PluginConfig config;
private class PluginConfig
{
[JsonProperty("Announce vanish state changes in chat")]
public bool Announce { get; set; } = true;
[JsonProperty("Broadcast to all players (false = only the affected player)")]
public bool Broadcast { get; set; } = false;
}
protected override void LoadDefaultConfig() => config = new PluginConfig();
protected override void LoadConfig()
{
base.LoadConfig();
try
{
config = Config.ReadObject<PluginConfig>();
if (config == null) throw new Exception();
}
catch
{
PrintWarning("Configuration file is invalid, using defaults");
LoadDefaultConfig();
}
SaveConfig();
}
protected override void SaveConfig() => Config.WriteObject(config);
protected override void LoadDefaultMessages()
{
lang.RegisterMessages(new Dictionary<string, string>
{
["Vanished"] = "{0} is now hidden from players.",
["Unvanished"] = "{0} is now visible to players again.",
["NoPermission"] = "You do not have permission to announce vanish changes."
}, this);
}
private string Msg(string key, string userId = null, params object[] args)
{
return string.Format(lang.GetMessage(key, this, userId), args);
}
private void Init()
{
permission.RegisterPermission(PermAnnounce, this);
}
private void OnPlayerVanished(BasePlayer player)
{
Handle(player, true);
}
private void OnPlayerUnvanished(BasePlayer player)
{
Handle(player, false);
}
private void Handle(BasePlayer player, bool vanished)
{
if (player == null) return;
string state = vanished ? "vanished" : "unvanished";
Puts(string.Format("{0} ({1}) is now {2}", player.displayName, player.UserIDString, state));
if (!config.Announce) return;
if (!permission.UserHasPermission(player.UserIDString, PermAnnounce)) return;
string key = vanished ? "Vanished" : "Unvanished";
string text = Msg(key, null, player.displayName);
if (config.Broadcast)
{
Server.Broadcast(text);
return;
}
player.ChatMessage(text);
}
}
}The plugin listens to both OnPlayerVanished and OnPlayerUnvanished so it can log the full cycle. Each event writes a timestamped line to the server console through Puts (only from these rare command events, never from a tick), and if the config flag is on it broadcasts a short chat message to everyone so other players know a staff member is currently hidden or back. A permission check gates the broadcast, so regular players using debug.invis on a permissive server do not spam chat. Config supplies the permission name and the on/off switch, messages live in the language file, and nothing is persisted to disk beyond the config.
Common use cases
Staff audit trail
Record who toggled invisibility and when, so server owners can review admin behavior. Because the hook only fires on the reveal side, log both OnPlayerVanished and OnPlayerUnvanished for a complete pair.
Restore combat restrictions
If you strip weapons or block damage while a player is hidden, re-enable them here so the player cannot carry vanish-only advantages into normal gameplay.
Notify the team
Send a chat line to the player's team members (RelationshipManager.ServerInstance.FindTeam) that the staff member is visible again, without broadcasting to the whole server.
Pitfalls
Only fires from the console command
A disconnect, death, or plugin-driven invisibility change does not run this code path, so the hook is not a reliable general-purpose "player is visible" signal. Track the state yourself for those cases.
Player may be disconnecting
The command can be issued while the player's connection is closing. Always null-check the argument and treat
player.IsConnectedas optional before sending chat or UI.Not the same as OnPlayerUnvanish
OnPlayerUnvanish and OnPlayerUnvanished are separate hooks with different call sites. If your plugin depends on both, declare each explicitly rather than expecting one to cover the other.
Build a plugin with OnPlayerUnvanished
Describe what should happen and get a compiled plugin that uses this hook.
Edit the prompt on the next screen. 2 free plugins a month, no card.
Last updated Oct 26, 2026. Found a mistake? Email support@rustplugingenerator.com.
Build a plugin with OnPlayerUnvanished
Generate