OnMlrsTargetSet
OnMlrsTargetSet is called after an MLRS recalculates and snaps its target aim point, right before the solved world position is stored. It fires once per target update with the vehicle, the final hit position and the mounted player.
void OnMlrsTargetSet(MLRS mlrs, UnityEngine.Vector3 trueTargetHitPos, BasePlayer mountedPlayer)Parameters
| Parameter | Type | Description |
|---|---|---|
mlrs | MLRS | The MLRS entity whose target was just recalculated. Use it to read the vehicle's position, owner (OwnerID) or mounted player state. |
trueTargetHitPos | UnityEngine.Vector3 | The final world position where the MLRS solved its aim point, after the game clamped and height-snapped it. This is the coordinate the rockets will be aimed toward. |
mountedPlayer | BasePlayer | The BasePlayer currently mounted on the MLRS at the moment the target is set, or null if it is unmanned. Passed from the vehicle's mounted player field. |
Return value
The hook is patched with a plain continue behavior: whatever your method returns is ignored and the original SetUserTargetHitPos logic keeps its already-computed target. Returning a value has no effect on the aim point; to influence behavior you must act on the vehicle or player instead.
How it works
The hook runs at the end of MLRS.SetUserTargetHitPos, after the game has converted the requested aim coordinates into a real world position: it clamps the point to the map, checks the terrain/entity surface with GetSurfaceHeight and writes the resulting Y back into the vector. By the time OnMlrsTargetSet is invoked, trueTargetHitPos already holds that adjusted coordinate, so it is the position the launcher will actually use.
This makes it the right place to observe or react to aiming rather than to opening the launch dialog. Use mlrs to identify the vehicle (compare net.ID or OwnerID against your own records), trueTargetHitPos to check where the player aimed, and mountedPlayer to attribute the action. The mounted player can be null when the MLRS is operated through other means or is in an unusual state, so null-check before using it.
Declaring a more specific type is not useful for mlrs here, since there is only one MLRS class. Narrowing is not available for the Vector3 argument either; treat it as a value type always present. The hook fires on every target update, so keep the body cheap and avoid logging inside it.
Example plugin: Log and restrict MLRS aiming by permission
using System.Linq;
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using UnityEngine;
namespace Oxide.Plugins
{
[Info("Mlrs Target Guard", "RustPluginGenerator", "1.0.0")]
[Description("Logs MLRS aiming and dismounts players who lack the launcher permission.")]
public class MlrsTargetGuard : RustPlugin
{
private const string PermUse = "mlrstargetguard.use";
private PluginConfig config;
private readonly List<string> recentAims = new List<string>();
private class PluginConfig
{
[JsonProperty("Require permission to aim")]
public bool RequirePermission { get; set; } = false;
[JsonProperty("Maximum stored aim records")]
public int MaxRecords { get; set; } = 50;
}
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>
{
["NotAllowed"] = "You are not permitted to aim this MLRS.",
["AimRecorded"] = "Aim point stored: {0}"
}, 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(PermUse, this);
}
private void OnMlrsTargetSet(MLRS mlrs, Vector3 trueTargetHitPos, BasePlayer mountedPlayer)
{
if (mlrs == null) return;
if (mountedPlayer != null && config.RequirePermission &&
!permission.UserHasPermission(mountedPlayer.UserIDString, PermUse))
{
mountedPlayer.ChatMessage(Msg("NotAllowed", mountedPlayer.UserIDString));
var mounted = mountedPlayer.GetMounted();
if (mounted != null && mounted == mlrs)
{
mountedPlayer.EnsureDismounted();
}
return;
}
string name = mountedPlayer != null ? mountedPlayer.displayName : "unmanned";
recentAims.Add(string.Format("{0} aimed at {1:F1} {2:F1} {3:F1}", name,
trueTargetHitPos.x, trueTargetHitPos.y, trueTargetHitPos.z));
if (recentAims.Count > Math.Max(1, config.MaxRecords))
{
recentAims.RemoveAt(0);
}
}
[ChatCommand("mlrsaims")]
private void CmdAims(BasePlayer player, string command, string[] args)
{
if (player == null || !player.IsAdmin) return;
if (recentAims.Count == 0)
{
player.ChatMessage("No MLRS aims recorded.");
return;
}
for (int i = recentAims.Count - 1; i >= 0; i--)
{
player.ChatMessage(recentAims[i]);
}
}
}
}The plugin registers a permission and stores recent aim events in memory. When OnMlrsTargetSet fires, it resolves the mounted player, checks the permission, and warns the player through localized chat if they are not allowed to use the MLRS. Because the hook return value is ignored, the plugin reacts by kicking the player off the vehicle: it calls mountedPlayer.GetMounted() and dismounts if unauthorized. If the player is allowed, it records the aim position in a small ring buffer for later inspection. The buffer is trimmed to keep memory bounded on busy servers, and all chat text is routed through lang messages.
Common use cases
Audit who aims the MLRS and where
Record the mounted player's name and the solved target position in memory or a data file so admins can review targeting during a raid without logging every rocket.
Gate MLRS use behind a permission
Dismount or warn a player who is not allowed to aim the launcher, using the mounted player argument to identify them.
Reject aiming outside allowed zones
Compare
trueTargetHitPosagainst a list of protected monument coordinates and react by dismounting the player or notifying other online staff.
Pitfalls
The mounted player can be null
_mountedis read straight from the vehicle field, so check for null before calling player methods like GetMounted, ChatMessage or permission checks.The hook ignores your return value
Returning false or any value does not cancel or change the target. You must act on the MLRS or the player directly to influence what happens next.
It fires on every target update
Do not send chat, spawn effects or write data files on every call unless you throttle; the method runs each time the launcher recalculates a target, which can be often.
Build a plugin with OnMlrsTargetSet
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 OnMlrsTargetSet
Generate