reepblue Posted October 1, 2015 Share Posted October 1, 2015 Hi, For the last few days, I've been trying to make my platforms/lifts perfect for both the player, and physical objects. I've thought I solved the issue explained here, but upon further investigation, I noticed a few problems. When the platform goes down, the physical object is put to sleep, and does not wake up when the platform goes back down. I've tried a bunch of things to keep it awake, but the box reacted to violently, and the overall result was bad. In the demo, I made a non-physics based script which worked for the demo, but when I went to use it in levels, the physics update did not update the player, and the player would just "fall through" the platform. I would just keep using the standard sliding door script as it solves both problems, but the platform itself reacts to physical impact. So in a case, a box can be falling for a few meters, and when it crashes on the platform, it sinks below the floor brush. I've made a script that prevents this when the platform is resting, but it can still be offset when the platform is moving. Collision Rules: --------------------------------------------------- --[[Collsion Defines: Make new Collision Rules ]]-- --------------------------------------------------- Collision.CharacterBlocker = 9 Collision.PropBlocker = 10 Collision.Clip = 11 Collision.PickInfo = 12 Collision.PickedUpProp = 13 Collision.Item = 14 Collision.JointObject = 15 Collision.PickInfoCrouch = 23 -- Props can activate triggers. Collision:SetResponse(Collision.Prop, Collision.Trigger, Collision.Trigger) -- Comment me out if you don't want this! -- CSG Collisions Collision:SetResponse(Collision.CharacterBlocker, Collision.Character, Collision.Collide) Collision:SetResponse(Collision.PropBlocker, Collision.Prop, Collision.Collide) Collision:SetResponse(Collision.PropBlocker, Collision.PickedUpProp, Collision.Collide) Collision:SetResponse(Collision.PropBlocker, Collision.VecBox, Collision.Collide) Collision:SetResponse(Collision.Clip, Collision.Character, Collision.Collide) Collision:SetResponse(Collision.Clip, Collision.Prop, Collision.Collide) Collision:SetResponse(Collision.Clip, Collision.PickedUpProp, Collision.Collide) -- Picked up objects can still collide with triggers, but never characters. Collision:SetResponse(Collision.PickedUpProp, Collision.Character, Collision.Collide) Collision:SetResponse(Collision.PickedUpProp, Collision.Scene, Collision.Collide) Collision:SetResponse(Collision.PickedUpProp, Collision.Prop, Collision.Collide) Collision:SetResponse(Collision.PickedUpProp, Collision.Trigger, Collision.Trigger) Collision:SetResponse(Collision.PickedUpProp, Collision.PickedUpProp, Collision.None) -- Items Collision:SetResponse(Collision.Item, Collision.Character, Collision.Trigger) Collision:SetResponse(Collision.Item, Collision.Scene, Collision.Collide) Collision:SetResponse(Collision.Item, Collision.Prop, Collision.Collide) Collision:SetResponse(Collision.Item, Collision.Trigger, Collision.Trigger) Collision:SetResponse(Collision.Item, Collision.PickedUpProp, Collision.None) -- PickInfo Collision:SetResponse(Collision.PickInfo, Collision.Scene, Collision.Collide) Collision:SetResponse(Collision.PickInfo, Collision.Prop, Collision.Collide) Collision:SetResponse(Collision.PickInfo, Collision.PickedUpProp, Collision.Collide) Collision:SetResponse(Collision.PickInfo, Collision.Trigger, Collision.None) Collision:SetResponse(Collision.PickInfo, Collision.Item, Collision.Collide) Collision:SetResponse(Collision.PickInfo, Collision.JointObject, Collision.None) Collision:SetResponse(Collision.PickInfoCrouch, Collision.Scene, Collision.Collide) Collision:SetResponse(Collision.PickInfoCrouch, Collision.Prop, Collision.Collide) Collision:SetResponse(Collision.PickInfoCrouch, Collision.PickedUpProp, Collision.None) Collision:SetResponse(Collision.PickInfoCrouch, Collision.Trigger, Collision.None) Collision:SetResponse(Collision.PickInfoCrouch, Collision.Item, Collision.Collide) Collision:SetResponse(Collision.PickInfoCrouch, Collision.JointObject, Collision.None) --JointObject Collision:SetResponse(Collision.JointObject, Collision.Character, Collision.Collide) Collision:SetResponse(Collision.VecBox, Collision.JointObject, Collision.Collide) Now here is my current platform code based off the sliding door script. import "Scripts/Functions/ReleaseTableObjects.lua" Script.enabled=true--bool "Enabled" Script.openstate=false--bool "Start Open" Script.distance=Vec3(0,0,0)--Vec3 "Distance" Script.movespeed=1--float "Move speed" 0,100,3 Script.opensoundfile=""--path "Open Sound" "Wav File (*wav):wav|Sound" Script.closesoundfile=""--path "Close Sound" "Wav File (*wav):wav|Sound" Script.loopsoundfile=""--path "Loop Sound" "Wav File (*wav):wav|Sound" Script.closedelay=-1 Script.opened=false function Script:Start() self.entity:SetGravityMode(false) if self.entity:GetMass()==0 then self.entity:SetMass(10) end self.sound={} self.sound.stop01 = Sound:Load("Sound/Gameplay/VecPlatform/platform_stop01.wav") self.sound.stop02 = Sound:Load("Sound/Gameplay/VecPlatform/platform_stop02.wav") -- Collision Fix self.entity:SetCollisionType(Collision.JointObject) self.protector= Model:Box(1,1,1) self.protector:SetPosition(self.entity:GetPosition(true)) self.protector:SetRotation(self.entity:GetRotation(true)) self.protector:SetQuaternion(self.entity:GetQuaternion(true)) self.protector:SetShape(self.entity:GetShape()) self.protector:SetShadowMode(0) -- Fix the shadow mode for the platform self.protector:SetGravityMode(false) self.protector:SetCollisionType(Collision.PropBlocker) self.protector:SetParent(self.entity) local material = Material:Load("Materials/Effects/Invisible.mat") self.protector:SetMaterial(material) material:Release() if self.opensoundfile~="" then self.sound.open = Sound:Load(self.opensoundfile) end if self.loopsoundfile~="" then self.sound.loop = Sound:Load(self.loopsoundfile) end if self.closesoundfile~="" then self.sound.close = Sound:Load(self.closesoundfile) end if self.sound.loop~=nil then self.loopsource = Source:Create() self.loopsource:SetSound(self.sound.loop) self.loopsource:SetLoopMode(true) self.loopsource:SetRange(50) end self.opentime=0 --Create a motorized slider joint local position=self.entity:GetPosition(true) local pin=self.distance:Normalize() self.joint=Joint:Slider(position.x,position.y,position.z,pin.x,pin.y,pin.z,self.entity,nil) if self.openstate then self.openangle=0 self.closedangle=self.distance:Length() else self.openangle=self.distance:Length() self.closedangle=0 end self.joint:EnableMotor() self.joint:SetMotorSpeed(self.movespeed) local e = self.entity:CountChildren() for n=1,e do --System:Print(n) cl = n - 1 local c = self.entity:GetChild(cl) --c:SetColor(1,1,1,0) c:SetShadowMode(Light.Dynamic) end --This will move, so have the shadowmode dynamic. self.entity:SetShadowMode(Light.Dynamic) end function Script:Toggle()--in if self.enabled then if self.openstate then self:Close() else self:Open() end end end function Script:Open()--in if self.enabled then self.opentime = Time:GetCurrent() if self.openstate==false then if self.sound.open then self.entity:EmitSound(self.sound.open) end self.joint:EnableMotor() self.protector:Hide() self.joint:SetAngle(self.openangle) self.openstate=true self.component:CallOutputs("Open") if self.loopsource~=nil then self.loopsource:SetPosition(self.entity:GetPosition(true)) if self.loopsource:GetState()==Source.Stopped then self.loopsource:Play() end end end end end function Script:Close()--in if self.enabled then if self.openstate then if self.sound.close then self.entity:EmitSound(self.sound.close) end self.joint:EnableMotor() self.joint:SetAngle(self.closedangle) self.openstate=false if self.loopsource~=nil then self.loopsource:SetPosition(self.entity:GetPosition(true)) if self.loopsource:GetState()==Source.Stopped then self.loopsource:Play() end end self.component:CallOutputs("Close") end end end function Script:UpdatePhysics() end function Script:Disable()--in self.enabled=false self.joint:DisableMotor() self.component:CallOutputs("Disable") end function Script:Enable()--in self.enabled=true self.joint:EnableMotor() self.component:CallOutputs("Enable") end function Script:UpdatePhysics() --Disable loop sound local angle if self.openstate then angle = self.openangle else angle = self.closedangle end if math.abs(self.joint:GetAngle()-angle)<0.1 then if self.sound.loop~=nil then if self.loopsource:GetState()~=Source.Stopped then self.loopsource:Stop() end end if self.openstate==false then if self.opened==true then self.protector:Show() self.component:CallOutputs("OnFullyClosed") self.opened=false self.entity:EmitSound(self.sound.stop02) System:Print("Fully Closed") end else if self.opened==false then self.component:CallOutputs("OnFullyOpened") System:Print("Fully Opened") self.entity:EmitSound(self.sound.stop01) self.opened=true end end else if self.sound.loop~=nil then if self.loopsource:GetState()==Source.Stopped then self.loopsource:Resume() end end self.component:CallOutputs("onresume") end if self.sound.loop~=nil then if self.loopsource:GetState()==Source.Playing then self.loopsource:SetPosition(self.entity:GetPosition(true)) end end --Automatically close the door after a delay if self.closedelay>0 then if self.openstate then local time = Time:GetCurrent() if time-self.opentime>self.closedelay then self:Close() end end end end function Script:Release() ReleaseTableObjects(self.sound) if self.loopsource then self.loopsource:Release() self.loopsource=nil end self.sound=nil end Is there a better way of making a platform that updates physics and the player but does not react to heavy objects, or objects with momentum? I really don't want to take any shortcuts as I don't want any puzzles to be limited/gimped depending on platforms. If you need/want any more of my attempts/code, I'll happy supply it. Thanks. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
tjheldna Posted October 2, 2015 Share Posted October 2, 2015 I would just keep using the standard sliding door script as it solves both problems, but the platform itself reacts to physical impact. I had the same issue here, what I did was create a custom collision type for the platform which only collides with the character. I don't know if that solution will work for you but it might. Quote Link to comment Share on other sites More sharing options...
Einlander Posted October 2, 2015 Share Posted October 2, 2015 I had one that every few cycles sets the physics positions. This forces the physics to update when you want it. Quote Link to comment Share on other sites More sharing options...
reepblue Posted October 2, 2015 Author Share Posted October 2, 2015 I had the same issue here, what I did was create a custom collision type for the platform which only collides with the character. I don't know if that solution will work for you but it might. No it wouldn't because I need both player's and objects to lift up. I made a strange script before that it's not pushing the object up that's the problem, it's getting the object to fall down with the platform when it goes down. Right now I'm thinking about porting my first platform code, and fully testing that. If it's only the player that's the issue, I think I can fix it. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Einlander Posted October 4, 2015 Share Posted October 4, 2015 I'll see if I can extract my platform code to be standalone. It's not physics based. Quote Link to comment Share on other sites More sharing options...
Josh Posted October 28, 2015 Share Posted October 28, 2015 A moving object should automatically wake up its neighbors. I will need a runnable map to test if this is not working. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted October 30, 2015 Author Share Posted October 30, 2015 Here is a quick map I did in the Advanced First Person Template. The left platform uses the advertised way of making platforms, while the right uses the Move() function. Note using SetPostition each pass also makes similar results. If you were to increase the barrels mass to something like 20, the platform on the left will break. I fixed this thanks to Einlander's script, and I talked about it here. Making a model or CSG move and react to physics much like the func_door entity from Source should not be this convoluted. If the jointed object much how the sliding door script is set up did not react to an objects weight, the issue would be solved. PlatformTest.zip Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! 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.