bansama Posted January 6, 2015 Share Posted January 6, 2015 Reference: http://www.leadwerks.com/werkspace/topic/8462-how-to-pass-variables-between-scripts-lua/ As a follow on to what I was doing in the above topic, I notice that a later update to Leadwerks resulted in my solution breaking a bit. I'm now trying to find a better way to do things. But I have noticed some strange behaviour which I'd like to try and resolve. The following is the basic collision script I am using: Script.entered = false Script.exited = false Script.hadCollision = false Script.Target = nil --entity Script.Enabled = true --bool function Script:UpdatePhysics() if self.entered then if self.hadCollision == false then if self.exited == false then self.exited = true self.component:CallOutputs("OnExit") -- command for enabling placed here self.entered = false end end end self.hadCollision = false end function Script:Collision(entity, position, normal) -- speed self.hadCollision = true self.component:CallOutputs("OnCollide") if self.entered == false then if self.Enabled == true then self.component:CallOutputs("OnEnter") self.entered = true self.exited = false end end end The basic idea is that on detecting collision, the trigger activates and performs what I need it to do. In this case, it's a teleport. As such, it also needs to disable the script for the receiving end. But when entering the receiver a second time, it should allow the player to return to the original teleport. My problem is, the script detects the player as "exiting" as soon as the player stops moving. Thus, the script activates when the player moves again (either when they walk, or change where they are facing). This can cause a loop where the player rapidly moves from one pad to the other. As such, I'm trying to find a good way to ensure the script only resets to its default active state when the player really does "exit" the entity the script is attached to. The solution I thought of trying was to have an outer pad and an inner pad for both teleporters. These would be separate entities of course. Imagine something like: <Pad a [Pad b]> <Pad c [Pad d]> Pad a and c are the outer pads, these I would want to use to enable the scripts connected to Pad b and d respectively. Pad b and d are the actual teleports, they will move the player to the linked pad [b to d, d to b]. But these scripts need to disable themselves as soon as a teleport has finished. The aim being that the player will not then re-teleport until they have actually left the pad (ie, made contact with pad a or c). Could someone suggest a good way to do this? I was thinking of importing the script attached to the teleport pad into the script attached to the outer pad, but could then not work out how to actually interact with the variables from the imported script. All help and suggestions will be greatly appreciated! Quote Link to comment Share on other sites More sharing options...
Thirsty Panther Posted January 6, 2015 Share Posted January 6, 2015 Rick did a nice video on teleporting http://youtu.be/dTaSP1fKD7c He uses this script http://leadwerks.wikidot.com/wiki:collision-enter-exit Quote Link to comment Share on other sites More sharing options...
bansama Posted January 6, 2015 Author Share Posted January 6, 2015 Yeah, that's the script mine is based on. It has the same problem with it detecting an "exit" as soon as you stop moving even though you're still on the entity. Quote Link to comment Share on other sites More sharing options...
josk Posted January 6, 2015 Share Posted January 6, 2015 Could you not just make a switch which is near the teleporter that you have to press that turns the teleporter on. Afetr one use the switch is automatically set back to off. This might interrupt the flow of the game, depends what you are going for. Another idea is to use Entity:GetDistance that will switch the teleporter back on when you have moved so far away. 1 Quote Elite Cobra Squad Link to comment Share on other sites More sharing options...
bansama Posted January 6, 2015 Author Share Posted January 6, 2015 Could you not just make a switch which is near the teleporter that you have to press that turns the teleporter on. Afetr one use the switch is automatically set back to off. This might interrupt the flow of the game, depends what you are going for. Another idea is to use Entity:GetDistance that will switch the teleporter back on when you have moved so far away. The first suggestion is not going to work, no. I am using the teleports as a way to move players around without their knowledge, so having them specifically hit a button isn't going to work in all situations. The second idea might work, thanks. But again, I could use some help on how best to access variables from an imported script, as half the time I try, they cannot be found (I get the usual attempt to access nil value error). Quote Link to comment Share on other sites More sharing options...
Rick Posted January 6, 2015 Share Posted January 6, 2015 My problem is, the script detects the player as "exiting" as soon as the player stops moving. Really? I don't recall that happening at all. Are you saying when you get teleported and you move slightly but are still inside the trigger it'll say you've exited? If you don't move at all after teleportation does it do anything? [EDIT] You know what I recall doing. In my video I recall linking each teleporter via a script variable so that I can manipulate the other teleporters script variables because when you teleport over to the other one you have to set it's variable to prevent what you are talking about, and getting telported back. Did you watch the video because I think I go over that in there. I haven't watched it in some time but I recall having to do something like that. Linking each teleporter to each other, but I don't see that in your script. Quote Link to comment Share on other sites More sharing options...
bansama Posted January 6, 2015 Author Share Posted January 6, 2015 Really? I don't recall that happening at all. Are you saying when you get teleported and you move slightly but are still inside the trigger it'll say you've exited? If you don't move at all after teleportation does it do anything? Yep. The script acts as if an "exit" is detected when you stop moving and then move again. I.e., teleport and jump, etc. I can solve that by not allowing the script to enable itself, but that makes the teleport one-way. If I then move away from the teleport and re-enter, it won't send me back to the original teleport. The script above is what I think I should work from for the outer pads (the ones I want to use to enable the teleports. The script I am using on each of the actual teleports is as follows: Script.entered = false Script.exited = false Script.hadCollision = false Script.Target = nil --entity Script.Enabled = true --bool function Script:UpdatePhysics() if self.entered then if self.hadCollision == false then if self.exited == false then self.exited = true self.component:CallOutputs("OnExit") --System:Print("Exited") --self.Enabled = true ** this can also be self.Target.script.Enabled = true, doesn't matter it will have the same effect ** self.entered = false end end end self.hadCollision = false end function Script:Collision(entity, position, normal) -- speed self.hadCollision = true self.component:CallOutputs("OnCollide") if self.entered == false then if self.Enabled == true then self.component:CallOutputs("OnEnter") --System:Print("Entered") self.Target.script.Enabled = false --entity:SetPosition(self.Target:GetPosition()) -- Teleports if entity:GetKeyValue("name") == "Player" then EntPlayerCoord = entity:GetPosition():ToString() --System:Print("Player "..EntPlayerCoord) EntPadCoord = self.entity:GetPosition():ToString() --System:Print("Send Pad "..EntPadCoord) TarPadCoord = self.Target:GetPosition():ToString() --System:Print("Targ Pad "..TarPadCoord) end PlayerTable = split(EntPlayerCoord, ", ") --for key,value in ipairs(PlayerTable) do -- System:Print( key .. " has value " .. value) --end SendPadTable = split(EntPadCoord, ", ") --for key,value in ipairs(SendPadTable) do -- System:Print( key .. " has value " .. value) --end TarPadTable = split(TarPadCoord, ", ") --for key,value in ipairs(TarPadTable) do -- System:Print( key .. " has value " .. value) --end -- Will need to use checks like this -- to help cope with minus numbers, etc., when teleporting BaseValue = "0" -- Need to set this to avoid error if SendPadTable[1] < BaseValue then OffsetX = PlayerTable[1] - SendPadTable[1] --System:Print("LT X " .. OffsetX) end if SendPadTable[2] < BaseValue then OffsetY = PlayerTable[2] - SendPadTable[2] --OffsetYa = SendPadTable[2] + OffsetY --System:Print("LT Y " .. OffsetY) end if SendPadTable[3] < BaseValue then OffsetZ = PlayerTable[3] - SendPadTable[3] --System:Print("LT Z " .. OffsetZ) end if SendPadTable[1] >= BaseValue then OffsetX = PlayerTable[1] - SendPadTable[1] --System:Print("GT X " .. OffsetX) end if SendPadTable[2] >= BaseValue then OffsetY = PlayerTable[2] - SendPadTable[2] --OffsetYa = SendPadTable[2] + OffsetY --System:Print("GT Y " .. OffsetY) end if SendPadTable[3] >= BaseValue then OffsetZ = PlayerTable[3] - SendPadTable[3] --System:Print("GT Z " .. OffsetZ) end TargetX = TarPadTable[1] + OffsetX TargetY = TarPadTable[2] + OffsetY TargetZ = TarPadTable[3] + OffsetZ --System:Print ("XYZ: " .. TargetX .. ", " .. TargetY .. ", " .. TargetZ) entity:SetPosition(TargetX, TargetY, TargetZ) end self.entered = true self.exited = false end end function split(s, delimiter) result = {} for match in (s..delimiter):gmatch("(.-)"..delimiter) do table.insert(result, match) end return result end Don't mind the system:prints, I just used those while coding to check what the script was doing. The section commented with ** is where enabling the teleport again is likely causing the problem. This is why I need to work out how best to enable the script again from a different entity. Does this make any sense? Quote Link to comment Share on other sites More sharing options...
Rick Posted January 6, 2015 Share Posted January 6, 2015 So I took the script above and remove it to just be the below and it works fine for me. When I teleport and if I'm still touching the trigger I can move very small increments inside the trigger and stop and nothing happens. I then move out of the trigger and back in and I get teleported. I don't get what the problem is. In my example and what I did is make a pivot and set it as the player (collision type of character and physics mode of character controller, and attach the FPSPlayer.lua script to it). Are you doing something different maybe that's causing an issue? Script.entered = false Script.exited = false Script.hadCollision = false Script.Target = nil --entity Script.Enabled = true --bool function Script:UpdatePhysics() if self.entered then if self.hadCollision == false then if self.exited == false then self.exited = true self.component:CallOutputs("OnExit") self.Enabled = true self.entered = false end end end self.hadCollision = false end function Script:Collision(entity, position, normal) -- speed self.hadCollision = true self.component:CallOutputs("OnCollide") if self.entered == false then if self.Enabled == true then self.component:CallOutputs("OnEnter") self.Target.script.Enabled = false entity:SetPosition(self.Target:GetPosition()) -- Teleports end self.entered = true self.exited = false end end Quote Link to comment Share on other sites More sharing options...
bansama Posted January 7, 2015 Author Share Posted January 7, 2015 So I took the script above and remove it to just be the below and it works fine for me. When I teleport and if I'm still touching the trigger I can move very small increments inside the trigger and stop and nothing happens. I then move out of the trigger and back in and I get teleported. I don't get what the problem is. In my example and what I did is make a pivot and set it as the player (collision type of character and physics mode of character controller, and attach the FPSPlayer.lua script to it). Are you doing something different maybe that's causing an issue? Even with that stripped down script, the result is the same. The only difference is likely that I am using the default FPSPlayer.pfb. But that has the same Physics mode, Collision type, and script that you are adding to a pivot, so it shouldn't be acting any different. Have you tried your script using the FPSPlayer.pfb? I've tried making a brand new map, using a pivot as the character and again, the same problem occurs. Just in case, I've attached a rar of the new map I just knocked together, along with the script I attached. _temp.rar Quote Link to comment Share on other sites More sharing options...
Rick Posted January 7, 2015 Share Posted January 7, 2015 When I run your map I don't have any trigger objects. The scene only has: Directional Light 2 Box 1 Pad 1 Pad 2 Pivot 2 Quote Link to comment Share on other sites More sharing options...
bansama Posted January 7, 2015 Author Share Posted January 7, 2015 When I run your map I don't have any trigger objects. The scene only has: Directional Light 2 Box 1 Pad 1 Pad 2 Pivot 2 You probably need to add the included script to Pad 1 and Pad 2, linking to the other pad respectively. The forum was being a pain while I was trying to attach the files. Quote Link to comment Share on other sites More sharing options...
Rick Posted January 7, 2015 Share Posted January 7, 2015 The script is attached to the pads but nothing is happening. Note that what you are doing isn't exactly what I do in my video. In my video I have separate cylinder csg in the middle of the pads set to trigger that act as the collision and transporter and the pads are just for visual. My advice is to follow my video linked above exactly and see if you see the issue. There might be something with collision callback when using scene vs trigger and moving/stopping. At least that is something for you try and test to keep debugging. Quote Link to comment Share on other sites More sharing options...
randomkeyhits Posted January 7, 2015 Share Posted January 7, 2015 The way I would do this would be to default all teleporters to disabled. Create a torus, make it a trigger object and give it an invisible material. Link the trigger collision to a CallOutputs("Enable") and use flowchart to tie it the teleporter so it can enable it. When the collision on the teleporter is triggered also have the script disable the teleporter as standard. This way the teleporters only work when you pass through the triggering torus first. The only caveat is that the inside edge of the torus needs to be over one full character body distance away from the teleporters hit box so you don't get an activate and teleport trigger at the same time on leaving the teleporter. 2 Quote content over form, game play over all. Link to comment Share on other sites More sharing options...
Rick Posted January 7, 2015 Share Posted January 7, 2015 @randomkeyhits As far as I know there is no torus csg, which is why I just use a cylinder in the center, but yes the rest of what you said is basically how I made it in the video. @bansama I'm not sure if you watched my video but your map is not like what I did in the video so you might not get the same results. (It's failing to load the script let me reset it and try) [EDIT] OK, yes this happens now, but all I can tell you is if you follow what I have in my video it works. If you change the pads to trigger and raise them off the ground a little so it's not touching the ground then it works just fine. So something with scene collision and the player that causes the Collision() callback to be called differently than a trigger. 1 Quote Link to comment Share on other sites More sharing options...
bansama Posted January 7, 2015 Author Share Posted January 7, 2015 I have tried exactly as your video, making trigger objects on the pads and adding the script to the triggers. In that case nothing happens. That is, I collide with the trigger and don't teleport. If I add the script to the pads without the teleport, they work as long as their collision type is not trigger (but with the behaviour mentioned at the start of this topic). In short, the Trigger collision type is not working for me. Quote Link to comment Share on other sites More sharing options...
Rick Posted January 7, 2015 Share Posted January 7, 2015 Note that I don't think your csg trigger can be touching anything. In your test scene if the pad is level with the ground setting to Trigger didn't work, but if I raised the pad so it's floating in air, it worked. Quote Link to comment Share on other sites More sharing options...
bansama Posted January 7, 2015 Author Share Posted January 7, 2015 Note that I don't think your csg trigger can be touching anything. In your test scene if the pad is level with the ground setting to Trigger didn't work, but if I raised the pad so it's floating in air, it worked. Yeah, I just found this. It only works if I make the trigger object really tall. Perhaps this is connected to the height of the player? This now appears to be working again. I would still like to work out how to use a separate entity to toggle this though just in case something else breaks it again in the future (and it could probably be useful for other things too). That is, to be able to access the variable for enabling/disabling with an imported script. I think I have an idea of how to try this. I just need to wrap my head around self and local variables... Thanks everyone for all the help and ideas thus far. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.