This script can be used to control if individual players can activate a door, trap, treasure chest or anything else. A lock can be locked and unlocked for everyone, access can be granted to specific players or a payment can be required for access. These conditions can be combined but in most cases it is enough to only use one of the three conditions and ignore the other two.


Here is an example of how to use lockScript without writing any code. We are going to place locked pickups in a shop so that it costs currency to pick them up. This requires using advanced mode, being in a game that has pickups and currency, such as those based on the Starter: Adventure blueprint, and having installed the lockScript package.

First we must turn off any existing interactivity so that it doesn’t bypass the lock.

  1. Place a Resource Spawner in the shop and right click it in the entity tree to Add → Script → lockablePickupSpawnerScript.
  2. Make sure that useOnInteract and useOnCollision are both turned off on the new script.
  3. Adjust the other settings. You can use the resourceSpawner’s pickupSpawnerScript settings as a reference if those work the way you want them to. I like to set the spawn times to 0, uncheck useSelfAsTemplete, select Shop Resource as pickupTemplete and check showOnInit.
  4. Delete the pickupSpawnerScript from the resourceSpawner.

Now we can add the actual price lock.

  1. Add a lockScript to the resourceSpawner.
  2. Find the InteractibleBox’s OnInteract binding. The InteractibleBox is a child of the resourceSpawner in the entity tree.
  3. Change the binding’s Script from pickupSpawnerScript to lockScript and Event to Activate.
  4. Return to the pickupSpawner and choose values for lockScript’s currencyTemplate and activationPrice.
  5. Add a new binding to onGrantAccess with the resourceSpawner dragged from the entity tree as Entity, lockablePickupSpawnerScript as Script and Pickup as Event.

Time for a few finishing touches.

  1. Write for example “buy (insufficient currency)” and “buy” respectively in lockedPromptMsg and unlockedPromptMsg.
  2. Drag InteractibleBox (or another child of the resourceSpawner) from the entity tree to either lockedIndicators or unlockedIndicators.
  3. Add an effect or mesh as a child of InteractibleBox and turn off its collision. It will only be visible when the lock is in the corresponding state for the player.

That completes the transformation from free pickup to purchasable shop item.

Events such as OnInteract, OnCollision and OnTriggerEnter can be hooked up not just to Activate but to lockScript’s other functions as well. If the function expects to receive a player as the only argument then it will understand calls from anything that sends a player as the first argument. onGrantAccess and onDenyAccess can be hooked up to anything that expects to receive only a player or no arguments at all. If you can find a way to achieve what you want with functions that already exist then you don’t have to write any code.


bool IsUnlocked()
Returns true if the lock is unlocked so that anyone can activate the lock for free and false if it is locked so that only authorized users can activate it for free.

bool HasAccess(object player)
Returns true if player is authorized to activate the lock for free even when it is locked and false otherwise.

bool CanActivate(object player, bool payForActivation)
Returns true if player can activet the lock due to it being unlocked, they having access or they being able to afford the price. If payForActivation is true then the activation price is deducted from the player if paying was their only way of activating the lock. If payForActivation is false then the player’s currency is left unchanged.

bool CanLocalUserActivate()
Returns true if the local user can activate the lock. This is useful for displaying different effects or messages depending on if you have accesss or not.

Activate(object player)
Calls onGrantAccess with player as argument if player can activate the lock and onDenyAccess also with player as argument otherwise.

Locks the lock.

Unlocks the lock.

bool ToggleLocked()
Toggles whether or not the lock is unlocked. Returns true if the lock is unlocked afterwards.

AuthorizeAccess(object player)
Gives player access to activate the lock for free even when it is locked.

RevokeAccess(object player)
Removes player’s access to activating the lock for free even when it is locked.

bool ToggleAccess(object player)
Toggles whether or not player has access to activate the lock for free even when it is locked. Returns true if player has access afterwards and false otherwise.

AddLockIndicator(Entity indicator, bool indicateAccess)
Child entities of indicator will only be visible when indicator is visible and CanLocalUserActivate == indicateAccess.

RemoveLockIndicator(Entity indicator)
This script will no longer change the visibility of child entities of indicator.

The reason for listing player as type object is that although lockScript was designed to lock things for players it actually accepts any Lua object. For example calling AuthorizeAccess(42) and then Activate(42) would cause onGrantAccess to provide the number 42 instead of a player as argument to the functions hooked up to it. It is up to you to ensure that the functions that call a lock only send things that the functions the lock calls can understand. This flexibility may be useful in some cases.