Jump to content
  • 0
Phodex Games

Changing position of physics object disables physics?

Question

So I think this is a bug. When I load a prefab with physics on, it works in the first place and my player can collide with the object (Collision set to scene and physics to rigid body). If I change the position however the physics is disabled and I can walk through the object. Changing the position again did sometimes turn the physics on again. This is some of the weird behavior I every now and then encounter with Leadwerks :(, especially with Prefabs. This did not happen when using the "Move" function instead of SetPosition. How could I fix this? I need to change the positon of an physics object during runtime...

Share this post


Link to post

39 answers to this question

Recommended Posts

  • 0

This seems like you either need to share a simpler version of your project with the community to look at or send your project to Josh.  Just one word of advice though: make sure you use physics commands with phsyics entities.  I'm surprised you said Move worked because I think that's supposed to be SetVelocity.  The occasional SetPosition should be fine and shouldn't break your collision.  This was much easier when the Entity documentation had a separate physics category.  🤔

Share this post


Link to post
  • 0

Could be difficult to share, but you can easily achieve the same error I guess when creating a simple box with physics, make it a prefab, load it and set the position of it on button press. Then you just need something to test the collsion (e.g FPS Player). At the start the physics should work but if you change the position you should be able to walk through the box. But sometimes the error does not occur so you may not be able to reproduce it. I currently will finish some other aspects of my project and will come back later to this bug. Hope to gather some information here. I will try some stuff when I have time and maybe share a setup where the problem appears, however thanks for you answer.

Share this post


Link to post
  • 0

Ok so I am just testing this. You can easily recreate this yourself. I created a csg box with following settings:

image.png.87c65ab2cb394b54cc0b809c880f12dc.png

And attached this script to it:

image.png.243c7f3e12b8c5edd0c7a620add0290e.png

(Its using my key manager so don't wonder) First my player collides with the csg box but after the SetPosition command I can walk through. I will try to work around the issue and examine this behavior. If I find a solution I will post it here.

 

EDIT 1: This does not happen when the object is set to prop physics AND has a mass (prop with 0 mass has the same behavior as scene). With scene physics & mass the object falls through the ground. But I NEED to move a scene object with static physics...

EDIT 2: I though Move was at least working, but if all this is not weird enough now if I use Move more then one time the physics get disabled again.

EDIT 3: So the idea now was to first set the entities mass to something greater than 0 and then change it back to 0. If other to expect this did not work, something more weird is need to be done to make this work. The code below did actually work and I can now set the physics object position, but because the mass reset to 0 happens one update later the object can move a tiny bit through physics (I could decrease this to a minimum by using a minimal mass).

function Script:UpdateWorld()
	if self.posChanged then self.entity:SetMass(0) end
	if keyHit.K then
		self.entity:SetMass(10)
		self.entity:SetPosition(15, 2, 0)
		self.posChanged = true
	end
end

 

Share this post


Link to post
  • 0
38 minutes ago, reepblue said:

There is also SetPhysicsPosition()

I can't find this in the documentation and it does not work, at least not with lua.

Share this post


Link to post
  • 0

If you are continually changing the position of an object each frame, it will break the physics simulation each time.

PhysicsSetPosition() was an old command that has been left in for backwards compatiblity, but is removed from the documentation because a better method has been implemented. The kinematic joint will allow you to precisely control the orientation of an object with physics forces:
https://www.leadwerks.com/learn?page=API-Reference_Object_Joint_Kinematic
https://www.leadwerks.com/learn?page=API-Reference_Object_Joint_SetTargetPosition
https://www.leadwerks.com/learn?page=API-Reference_Object_Joint_SetTargetRotation

Share this post


Link to post
  • 0
2 hours ago, Josh said:

The kinematic joint will allow you to precisely control the orientation of an object with physics forces

Ok I wonder how to use this for my purpose now. I tried this code but my object does not move at all:

function Script:Start()
	self.joint = Joint:Kinematic(0, 0, 0, self.entity)
	self.joint:EnableMotor()
end

function Script:UpdateWorld()
	if keyHit.K then
		self.joint:SetTargetPosition(150, 2, 0, 0)
	end
end

I don't really need continually change of an physics object. I am currently building a random dungeon generator and the systems loads in prefabs and sets them in place to generate a new room. All objects have Scene physics with no mass (And I think the joint does not work with 0 mass, does it?). I experienced that in some rooms some objects have no physics anymore (seems to be random). So the set position command is only used once after the prefab is loaded. The example shown here with the box was just to examine the behavior. So I need a solution how I can move my rooms & furnishings without losing the physics...

Share this post


Link to post
  • 0

There is no motor so you don't have to worry about that. 

Since you set the blend to 0 (the last parameter) then the change will be exactly 0% of the new destination you are setting. ;) Try setting this to 1.

Share this post


Link to post
  • 0
1 hour ago, Josh said:

There is no motor so you don't have to worry about that. 

Yeah I just tried that because it did not work. Hmm I still can't get it work. What am I doing wrong?

function Script:Start()
	self.joint = Joint:Kinematic(1, 1, 1, self.entity)
	self.joint:SetTargetPosition(300, 2, 0, 1)
end

Shouldn't this code change the position of my object? Could you give me an example code how to move a physics object with this? And does the object need a mass or specific collision setting?

Share this post


Link to post
  • 0
On 9/27/2018 at 10:23 PM, Josh said:

The above code should work

It somehow does not. This is what I have:

image.thumb.png.21c2dde8df0643019899fb3234de8979.png

This is what the attached code:

function Script:Start()
	self.joint = Joint:Kinematic(1, 1, 1, self.entity)
end

function Script:UpdateWorld()
	if keyHit.K then
		self.joint:SetTargetPosition(300, 2, 0, 1)
	end
end

It does not even move slightly, but even if. I just want to set the position of a static scene object. Why should I need to use a joint for that, I would expect set position to work for a static physics object. I really need this to work, otherwise you can just randomly walk through objects...

Share this post


Link to post
  • 0

Try....

-- entity is a 128x128x128 editor unit cube in air at 0,312.0,0
-- physics mode = 'rigid body', collision type = 'prop', mass = 1
-- with mass of 3 object will 'struggle' into position. With mass 4 object will move down to end position but not back up.
Script.startPos = nil
Script.joint = nil

function Script:Start()
	self.startPos = self.entity:GetPosition(true)	
	System:Print("pos x="..self.startPos.x.." y="..self.startPos.y.." z="..self.startPos.z)
	self.joint = Joint:Kinematic(self.startPos.x, self.startPos.y, self.startPos.z, self.entity)
	self.joint:SetFriction(1)
end

function Script:UpdateWorld()
	local window = Window:GetCurrent()
	if window:KeyHit(Key.K) then
		System:Print("KEY K HIT - MOVE TO END")
		self.joint:SetTargetPosition(self.startPos.x, 2, self.startPos.z, 1)
	end
	if window:KeyHit(Key.L) then
		System:Print("KEY L HIT - MOVE BACK")
		self.joint:SetTargetPosition(self.startPos.x, self.startPos.y, self.startPos.z, 1)
	end
end

Kinda frustratingly the end result is dependent on the mass so can appear not to work at all. Maybe this is dead obvious if you are familiar with physics engine problems (not me).

Set the mass to 1 or anything up to about 3 and you'll probably find it moves. Above 5 and my test CSG cube would actually drop to ground from start position it it was in air and was too heavy to lift.  Mass of 4 made it stay in position (in the air) but could not move it to second destination.

This is probably one of these things where if you understand what the 'hidden parameters' of the system are then it makes some sense but for someone not in the know is rather frustrating to figure out I reckon. 

 

Share this post


Link to post
  • 0

I think a simple downloadable example we can try ourselves would make it much easier to work this out.

Share this post


Link to post
  • 0

See attached files. I prefer editor examples than pure code examples as I personally I like to be sure it works in editor.  

Very standard scene CSG cube in air.   

Attach the joint.lua to the CSG cube in the air in the start map. Need a scene with FPS controller so FPS template is required as starter before copying the files in to avoid issues.

 

start.map

Joint.lua

Share this post


Link to post
  • 0

To be clear I'm not saying there is any problem here I am just providing example with reason for the previous attempt not working  - being that mass of 10 probably too great. Just saying that it can be a bit hard to know where issues are and I think there is no example in docs of Kinematic joint.

 

 

 

Share this post


Link to post
  • 0
6 hours ago, mdgunn said:

Try....

Thanks for the code, it actually works, but that is not what I actually want. This slowly moves the object in place. I just want to spawn a new object and set its position. And I also don't want to have a object with mass, or dynamic physics. I simply want to change the position of  a static object (scene physics and 0 mass). Imagine something like this:

function Script:SpawnObject()
	--the object has scene physics and 0 mass
  	self.obj = Prefab:Load("Prefabs/Object.pfb")
	self.obj:SetPosition(x,y,z)
end

The above code sometimes breaks the newly spawned objects physics as mentioned earlier. Using a joint does not seem to be an option. I dont want my object to slowly move towards its spawn position.

I could provide a test proejct, but the behavior can be reproduced so easily. Just take a csg brush, scene physics on, 0 mass. Now try to change its position & test the collision with a player controller.

Share this post


Link to post
  • 0

Yeah I did think that this was NOT what you ultimately wanted.  I was actually not expecting the object to move 'slowly' like that either.  Thought with that simple set-up it would actually just go there, more like you want. Still I can see where this nice simple movement might be a nice thing.

I have had some funny behavior with prefabs in the past. I think these issues went away when I made them full instances (e.g. tweak the prefab in the editor to make it become instance).  For you though this is not what you want due to dynamic nature of the dungeon building.

A few suggestions of things you've PROBABLY ALREADY TRIED:-

a) use System:Print out some position properties at key points

b) use some debugging child objects to see if it helps understand things. 

c) Make sure you're clear on when setting getting values with global or local coordinates

d) Always have the origin of your entity centered in the prefab (0,0,0 - or sitting on floor at 0,0,0) 

By b) I mean that recently while trying to understand some strangeness in editor vs running game I created some Model:Spheres as extra child objects in prefabs script at positions to help understand if something was off with where I thought the position of things were compared to where they actually appeared to be.

I feel your pain.  Sometimes it feels to me like prefabs are an area where things work out well in a demo/test scenario but when you try to use them in a non-demo project things sometimes feel like they are working against you. Workflow is not quite right it feels to me if you are developing original assets from 'white box' prefabs.

If I get a chance I'll see if I can take a look at and make any sense of your actual problem which really seems to relate to PREFABS which I agree isn't the setup I was showing.  

 

Share this post


Link to post
  • 0

Just wondering.... after loading your prefab in code have you tried instancing it rather than setting the prefab?

May seem wrong to have 2 'large' objects in memory but if I think due to the way instancing works it's probably the same memory.  You may need to turn of all the things you can so that the prefab version is essentially inert (hidden, not reacting to physics etc.).  You may also be able to remove the original prefab and retain the instance.   

Not tested this but it may  be when instanced things become clearer. May seem strange this but I think prefabs are not QUITE the same as an instance.  For example, I'm fairly sure that the prefab has an empty name attribute even if it's editor prefab has one (the name field in editor), but an instance of the prefab with a name set will have this when tested in code.  I think it was some time since I tested that but I think that a prefab and an instance may not be 100% as you might expect them to be.

 

Share this post


Link to post
  • 0

EDIT: The behaviour below I think is just me being silly.  Only 1 moving because it used up the key hit event.  Need some sort of state involved instead and using KeyDown so multiple key events (or use other methods).

 

3_prefabs-1_responds.thumb.jpg.fa26d256d24001ec8e3b114f23d01978.jpg

I tried making my cube with script a prefab and placing 3 on screen.  All 3 remain where I set them with a joint in operation(I can tell as I can rotate them around a bit but they are fixed at the spot).  HOWEVER, only the last one placed -  actually responds to key presses to move it. I don't fully understand why the rest don't - maybe bad logic in my script or maybe it relates to duplicated prefabs not being full instances.

I realise this still isn't what you want but thought I'd point out the strange behaviour of the proposed Kinematic solution.

 

 

 

 

 

Share this post


Link to post
  • 0
1 hour ago, mdgunn said:

actual problem which really seems to relate to PREFABS

Yeah I first thought Prefabs are the problem as well, BUT thats why I set up the test scene with a normally placed box with same conditions as my prefab objects (Scene physics and 0 mass). This is a summary of what I have tested and what happend, again this is a normal object placed in the editor. No Prefab. I think if I find a solution for moving this object I can use the same for my prefabs:

  • SetPosition breaks the collision of the object
  • Move breaks the collision of the object if used twice
  • Joint:Kinematic does not work for static physics objects (I also think it makes no sense to use a joint for a static object...)

I know Prefabs are a little weird sometimes, but currently its about a normal object, although I use prefabs in my actual situation. I wonder this problem didn't occur for sombody else yet, it think changing an objects position should be used every now and then...

The weird is that in my actual setup the physics just break for models, but not for csg brushes, under different circumstances however, which are a little hard to explain right now, the csg brushes physics broke aswell. 

Share this post


Link to post
  • 0

Right so also for non-prefabs.  OK.   Have you tried different ways of trying to reset physics at run-time.   I am fairly sure I've seen a standard script (maybe related to FPS controller, or projectiles) which seemed to do something odd like set the physics mode to one setting, set it to another mode, then back to the other as if trying to force a reset or re-evaluation of physics.  I think there are also some commands you can use to try to reset things but I forget which.  One other thing SetDebugPhysicsMode(true) on camera might show something but you've probably already tried that.   

 

Share this post


Link to post
  • 0
6 minutes ago, mdgunn said:

force a reset or re-evaluation of physics

That is exactly what I need...

7 minutes ago, mdgunn said:

One other thing SetDebugPhysicsMode(true) on camera might show something but you've probably already tried that. 

Yeah I tried that, the physics shapes are in the right place.

Share this post


Link to post
  • 0

Try the below.  You need more commands to further reset physics otherwise the item will retain some physics behaviour, so if moving fast will go back to position you want but will bounce away with previous velocity.  Check the fps player script and how it handles dead body physics and also moving and putting down items.  I think that might get you where you want? NOTE: I'm purposefully dropping object from small height to rule out any weirdness with physics starting intersecting already at start time. You may not need this but felt best to try to avoid this in the test.

 

Script.startPos = nil
Script.atStart = true

function Script:Start()
	self.startPos = self.entity:GetPosition(true)	
	System:Print("pos x="..self.startPos.x.." y="..self.startPos.y.." z="..self.startPos.z)
end

function Script:UpdateWorld()
	local window = Window:GetCurrent()
	if window:KeyDown(Key.K) and self.atStart == true then
		self.atStart = false
		self.entity:SetCollisionType(Collision.Prop)
		System:Print("KEY K HIT - MOVE TO END")
		self.entity:SetPosition(self.startPos.x + 1, self.startPos.y, self.startPos.z, true)
	end
	if window:KeyDown(Key.L) and self.atStart == false then
		self.atStart = true
		self.entity:SetCollisionType(Collision.Prop)
		System:Print("KEY L HIT - MOVE BACK")
		self.entity:SetPosition(self.startPos.x, self.startPos.y, self.startPos.z, true)
	end
end

 

 

Share this post


Link to post
  • 0
6 hours ago, Phodex Games said:

Yeah I first thought Prefabs are the problem as well, BUT thats why I set up the test scene with a normally placed box with same conditions as my prefab objects (Scene physics and 0 mass). This is a summary of what I have tested and what happend, again this is a normal object placed in the editor. No Prefab. I think if I find a solution for moving this object I can use the same for my prefabs:

  • SetPosition breaks the collision of the object
  • Move breaks the collision of the object if used twice
  • Joint:Kinematic does not work for static physics objects (I also think it makes no sense to use a joint for a static object...)

I know Prefabs are a little weird sometimes, but currently its about a normal object, although I use prefabs in my actual situation. I wonder this problem didn't occur for sombody else yet, it think changing an objects position should be used every now and then...

The weird is that in my actual setup the physics just break for models, but not for csg brushes, under different circumstances however, which are a little hard to explain right now, the csg brushes physics broke aswell. 

If you are using polygon collision then the object can't be physically dynamic. You need convex decomposition for that.

However, you can call SetPosition or Move once and the collision will work after that. If you are continuously calling it, it resets collision each frame.

Share this post


Link to post

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   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.

×
×
  • Create New...