Example Sign
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