Sign Entity
This is an advanced example that uses a lot of different features.
Global Script, manages the UI
function OnTemplate()
-- Here we'll call our create UI function
CreateUI()
-- Since we'll be using this UI from entities we'll register some global functions
-- so our entities can interact with this global script.
-- These two will be used to open the UI and close the UI.
self.RegisterGlobalFunction("SignOpenUI",OpenUI)
self.RegisterGlobalFunction("SignCloseUI",CloseUI)
-- These will be used to retrieve references to our input fields and save button.
self.RegisterGlobalFunction("GetSignTitle",GetSignTitle)
self.RegisterGlobalFunction("GetSignText",GetSignText)
self.RegisterGlobalFunction("GetSaveSignButton",GetSaveButton)
end
-- Function to be called from our entities, returns the save button reference.
function GetSaveButton()
return saveButton
end
-- Function to be called from our entities, Unhides our UI.
function OpenUI()
myCanvas.gameObject.SetActive(true)
end
-- Function to be called from our entities, Hides our UI.
function CloseUI()
myCanvas.gameObject.SetActive(false)
end
-- Function to be called from our entities, returns the title input reference.
function GetSignTitle()
return signTitleInput
end
-- Function to be called from our entities, returns the text input reference.
function GetSignText()
return signTextInput
end
function CreateUI()
-- Creates a new UI Canvas to hold our UI.
-- The true value means the game will free the mouse when this canvas is active.
myCanvas = UI.CreateCanvas(true)
-- Creates a main panel in our new canvas.
mainPanel = UI.CreatePanel(myCanvas).SetAnchors(0.3, 0.7, 0.1, 0.9)
-- Adds an image to the main panel.
UI.CreateImage(mainPanel,1,1,1,0.8)
-- Creates a new title panel in the main panel.
titlePanel = UI.CreatePanel(mainPanel).SetAnchors(0.1,0.9,0.80,0.95)
-- Adds a text to the title panel.
titleText = UI.CreateTextMesh(titlePanel, "Sign",76,0,0.6,0.9,1,"center","titletext").SetFont("TitleShadow")
-- We'll create a panel for our Sign Title.
signTitlePanel = UI.CreatePanel(mainPanel).SetAnchors(0.1,0.9,0.75,0.8)
-- We'll add an input field to our signTitlePanel
signTitleInput = UI.CreateInputField(signTitlePanel)
-- We'll add some placeholder text to our sign title.
signTitleInput.placeholderText = "Type your sign title here"
-- We'll create a panel for our Sign Text.
signTextPanel = UI.CreatePanel(mainPanel).SetAnchors(0.1,0.9,0.15,0.7)
-- We'll add an input field to our signTextPanel
signTextInput = UI.CreateInputField(signTextPanel,true)
-- We'll add some placeholder text to our sign text.
signTextInput.placeholderText = "Type your sign message here"
-- Creates a panel to hold our button
buttonsPanel = UI.CreatePanel(mainPanel).SetAnchors(0.1,0.9,0.05,0.12)
-- Creates a new button in the buttons panel without any callback since it's going to be set by our entity.
saveButton = UI.AddBlueButton(buttonsPanel,"Save Sign", "buttons")
-- Makes our button the size of our panel.
saveButton.rectTransform.SetAnchors(0,1,0,1)
-- Adds a close button to the main panel which will call our CloseUI function.
closeButton = UI.AddCloseButton(mainPanel, "closeButton", CloseUI)
-- Sets the anchors of the close button's rect transform to the right corner.
closeButton.rectTransform.SetAnchors(0.9,1,0.9,1)
-- Hides our canvas.
myCanvas.gameObject.SetActive(false)
end
Entity code
function OnTemplate()
-- Add your own model here.
self.AddModel('bToast_Sign')
-- Creates collisions for this entity.
self.CreateSphereCollisions()
-- This makes it possible to place this entity as a buildable piece.
self.MakeBuildable()
end
-- The function OnClone() gets called by the engine whenever this entity is cloned.
-- Anything that needs to be unique to this entity's instance should go on the OnClone function.
-- As an example, if I had put the OnEnable listener OnTemplate instead it would get called on DelayCall
-- clones of this entity whenever any of them is enabled.
function OnClone()
-- Registers a listener to call back the function "Enabled" when this clone gets enabled on the scene.
self.RegisterListener(Messager.OnEnable,Enabled)
-- If I'm the host I want to listen for messages of players connecting so we can send them the sign info.
if(Game.IsHost) then
self.RegisterListener(Messager.PlayerConnected,SendSignInfoToOthers)
end
-- Since our UI inputs are in a global script we'll call some global functions we set to retrieve them.
signTitleInput = Game.CallGlobalFunction("GetSignTitle")
signTextInput = Game.CallGlobalFunction("GetSignText")
-- We would like to listen for networked calls on this clone so other players can receive our sign info.
self.ListenForNetworkCalls()
-- Adds a Lua Trigger to this clone with the name "Sign" and a radius of 3.
-- Triggers are interactable positions in the game where you can press the Interact button to run some code.
actionLua = self.AddLuaTrigger("Sign",3);
-- We're going to override the StartAction of our new trigger with the OpenUI function.
-- StartAction gets called when we first press the Interact button on our trigger's radius.
-- Our OpenUI function will open our Sign's UI.
actionLua.OverrideStartAction(OpenUI)
end
function Enabled()
-- When the object is enabled if we're the host we want to call the LoadSignInfo method in 5 seconds.
-- We're doing this to give enough time for the other players to have finished loading our sign.
-- Also make sure when you're creating the item json for this to set it to always load.
-- Otherwise other players that are far away from the sign might have it not loaded and not get sign changes.
if Game.IsHost() then
self.DelayCall(5,LoadSignInfo)
end
end
-- We'll use this table to hold our sign title and text.
signInfo = {}
-- We'll use these function to concatenate a unique id for our title and text using the entity's spatialID.
-- Spatial ID gets set based on the entity's position in the world.
-- So if this position changes (Item shifter?) we'll lose our sign's saved info which is not ideal.
-- Later on I'll have to add a listener for item shifter changes so we can save again when position changes.
function SignInfoTitleKey()
return "signTitle".. self.spatialID
end
function SignInfoTextKey()
return "signText".. self.spatialID
end
-- This function gets called by my Enabled callback with a 5 second delay.
function LoadSignInfo()
--Calls the change sign info function with loaded data for the title and text
ChangeSignInfo(Data.LoadString(SignInfoTitleKey()),Data.LoadString(SignInfoTextKey()))
-- This function sends the sign info to others in the room.
SendSignInfoToOthers()
end
function SaveSignInfo()
-- Since our UI is in a global script we'll call this global script to close it when we save the sign info.
Game.CallGlobalFunction("SignCloseUI")
-- This method calls a function across the network for all players in the room including yourself.
-- We'll use this to call the ChangeSignInfo for everyone.
self.CallFunctionOnEveryone("ChangeSignInfo",signTitleInput.text,signTextInput.text)
end
function SendSignInfoToOthers()
-- This method calls a function across the network for other players in the room (not yourself).
-- We'll use this to call the ChangeSignInfo for all other players.
self.CallFunctionOnOthers("ChangeSignInfo",signInfo[SignInfoTitleKey()],signInfo[SignInfoTextKey()])
end
function ChangeSignInfo(title,text)
-- Here we'll set the interaction name of our trigger to be our sign's title,
-- or Sign if we don't have a title.
if (self.actionLua ~= nil) then
if (title ~= nil and title ~= "") then
self.actionLua.SetInteractionName(title)
else
self.actionLua.SetInteractionName("Sign")
end
end
-- We'll set our info in our signInfo table.
signInfo[SignInfoTextKey()] = text
signInfo[SignInfoTitleKey()] = title
-- Then if we're host we'll save our info using the Data.SaveString methods
if Game.IsHost() then
Data.SaveString(SignInfoTitleKey(),signInfo[SignInfoTitleKey()])
Data.SaveString(SignInfoTextKey(),signInfo[SignInfoTextKey()])
end
end
-- We'll use this function to open our UI
function OpenUI()
-- We'll update our title and text input to use our saved info and call our Open UI on the Sign UI script.
signTitleInput.text = signInfo[SignInfoTitleKey()]
signTextInput.text = signInfo[SignInfoTextKey()]
-- Since our UI is in a global script we'll call a global function to open it.
Game.CallGlobalFunction("SignOpenUI")
-- Here we'll retrieve the save button from our global UI script
saveButton = Game.CallGlobalFunction("GetSaveSignButton")
-- If the save button is not nil it has been retrieved sucessfully.
-- We will then unregister all callbacks and register a new one, to make sure we're only saving
-- the info on our own sign and not on other clones of it.
if (saveButton ~= nil) then
saveButton.UnregisterAllCallbacks()
saveButton.RegisterCallback(SaveSignInfo)
end
-- And here we'll tell the trigger that we're done with our trigger action.
actionLua.StopTrigger()
end