Skip to content
RustPluginGenerator

OnEntityLeave

OnEntityLeave is called when a BaseEntity exits a trigger volume, before the trigger removes it from its internal entity list. Returning a non-null value cancels the removal for that call.

Signature
object OnEntityLeave(TriggerBase trigger, BaseEntity ent)

Parameters

Hook parameters
ParameterTypeDescription
triggerTriggerBaseThe trigger the entity is leaving, passed as a TriggerBase. Cast it to TriggerComfort, TriggerRadiation, TriggerPressurePad, etc. to find out which kind of zone is involved; the entity is still registered inside the trigger when the hook runs.
entBaseEntityThe entity that has left (or is about to leave) the trigger volume. It may be a player, a horse, a dropped item or any other BaseEntity; null-check it and filter by type before acting.

Return value

Returning null (or nothing) lets the trigger remove the entity from its list and invoke its own leave callback. Returning any non-null value skips that removal and the OnEntityLeaveTrigger delegate for that single call, leaving the entity registered in the trigger.

How it works

The hook fires from TriggerBase.OnEntityLeave, the virtual method the base trigger patch runs whenever something is removed from a trigger's entity contents, and again from TriggerComfort.OnEntityLeave for comfort zones. In both places it runs before the game edits its own bookkeeping: the entity is still in entityContents (or the comfort zone's _entities list) at the time your plugin sees it, which makes the hook useful for state that depends on "currently inside".

The comfort overload only reaches the hook for players, RidableHorse and similar rideable mounts, so if you need a stable hook for seats and horses you can declare TriggerComfort instead of TriggerBase to skip every other trigger type. Declaring BasePlayer for ent narrows the dispatch further and drops horses and items.

Typical triggers that produce this call include comfort bubbles, radiation zones, pressure pads, safe zones and player-built sam sites. Triggers also raise the hook as players leave due to disconnect, death or teleport, so do not assume the player is still alive.

Other signatures

Oxide also calls OnEntityLeave from other places in the game with these parameter types. Declare the overload you need, or several:

  • object OnEntityLeave(TriggerComfort triggerComfort, BaseEntity ent)

Example plugin: Announce when a player leaves a comfort zone

ComfortZoneExit.cs
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("Comfort Zone Exit", "RustPluginGenerator", "1.0.0")]
    [Description("Notifies players when they leave a comfort zone and reports how long they stayed inside")]
    public class ComfortZoneExit : RustPlugin
    {
        private const string PermNotify = "comfortzoneexit.notify";

        private PluginConfig config;
        private readonly Dictionary<ulong, float> enteredAt = new Dictionary<ulong, float>();

        private class PluginConfig
        {
            [JsonProperty("Send chat message on leave")]
            public bool Announce { get; set; } = true;

            [JsonProperty("Minimum seconds inside before announcing")]
            public float MinimumSeconds { get; set; } = 2f;
        }

        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>
            {
                ["LeftComfort"] = "You left the comfort zone after {0} seconds inside.",
                ["LeftComfortNoTime"] = "You left the comfort zone."
            }, this);
        }

        private string Msg(string key, string userId = null, params object[] args) =>
            string.Format(lang.GetMessage(key, this, userId), args);

        private void Init()
        {
            permission.RegisterPermission(PermNotify, this);
        }

        private void Unload()
        {
            enteredAt.Clear();
        }

        private object OnEntityEnter(TriggerComfort comfort, BaseEntity ent)
        {
            var player = ent as BasePlayer;
            if (player == null || player.IsNpc) return null;

            enteredAt[player.userID.Get()] = UnityEngine.Time.realtimeSinceStartup;
            return null;
        }

        private object OnEntityLeave(TriggerComfort comfort, BaseEntity ent)
        {
            var player = ent as BasePlayer;
            if (player == null || player.IsNpc) return null;

            ulong id = player.userID.Get();
            float started;
            if (!enteredAt.TryGetValue(id, out started)) return null;
            enteredAt.Remove(id);

            if (!config.Announce || !player.IsConnected) return null;
            if (!permission.UserHasPermission(player.UserIDString, PermNotify)) return null;

            float stayed = UnityEngine.Time.realtimeSinceStartup - started;
            if (stayed < config.MinimumSeconds) return null;

            player.ChatMessage(Msg("LeftComfort", player.UserIDString, Mathf.RoundToInt(stayed)));
            return null;
        }
    }
}

The plugin builds on OnEntityLeave with a specific TriggerComfort parameter, so it only reacts to comfort zones and ignores every other trigger type. The entity is cast to BasePlayer; NPCs and horses are dropped. When a real player steps out, the plugin checks the config for the message and sends a chat notification including the elapsed seconds spent inside the zone, tracked per player in a Dictionary<ulong, float> that is filled on OnEntityEnter with UnityEngine.Time.realtimeSinceStartup. The hook always returns null so the comfort zone still removes the player normally. The dictionary is cleared in Unload.

Common use cases

  • Zone entry/exit notifications

    Send a chat line when a player leaves a radiation, safe-zone or comfort bubble so they notice the effect ending.

  • Session timing for minigames

    Record entry on OnEntityEnter and compute time spent inside a trigger on exit, then score or reward the player.

  • Trigger volume bookkeeping

    Maintain your own list of players inside a custom area by removing them from it when the trigger reports they left.

Pitfalls

  • The entity is still inside the trigger

    The game removes the entity only after the hook returns null. Do not query the trigger's contents expecting it gone, and never assume the trigger list already excludes ent.

  • Returning non-null blocks removal

    Any non-null object from the hook stops the trigger from removing the entity, which can leave stale references and repeat calls. Return null unless you are intentionally pinning the entity.

  • Horses and players share the comfort overload

    TriggerComfort passes players, horses and other mounts. Cast ent to BasePlayer and check IsNpc() before running player-only logic.

Build a plugin with OnEntityLeave

Describe what should happen and get a compiled plugin that uses this hook.

Prompt: Zone entry/exit notifications using the OnEntityLeave hook, with a config file and a permission
Generate this plugin

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 OnEntityLeave

Generate