Jump to content

Help with Platforms


reepblue
 Share

Recommended Posts

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.

 

shot1.png

 

 

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.

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

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.

trindieprod.png?dl=0spacer.png?dl=0steam-icon.png?dl=0twitter-icon.png?dl=0spacer.png?dl=0
Link to comment
Share on other sites

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.

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

  • 4 weeks later...

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

Cyclone - Ultra Game System - Component PreprocessorTex2TGA - Darkness Awaits Template (Leadwerks)

If you like my work, consider supporting me on Patreon!

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...