- Home /
Prevent movement into a collider whilst using custom movement script
Hey guys,
I have a movement script that moves a capsule(containing the camera) but does so via rotations and movements of it's parent objects. The movements are working fine, but now I would like to introduce collisions to the camera so it can't go through various scenery.
My problem is that I want to prevent the capsule from making any movement that would cause a collision, however it won't know it's going to collide until it does so, thus leaving the capsule in the scenery.
I initially tried completing the movement and then checking my collision flag, if a collision occurred then reverse the movement, obviously this solution produces a camera vibration and is terrible. My next thought is to have a "test" capsule that completes the movement, checks for collision, if yes then reverse the movement, if no then have the camera capsule match it's location.
But this is starting to sound rather hacky and I'm wondering if there is a simpler way?
Many thanks in advance.
couple ways you can do this. Use a raycast with a short length that will mkae your object stop moving when the raycast hits, or you could add a larger parent object to one of them, remove the mesh renderer but keep the collider so that it will collide with this invisible barrier ins$$anonymous$$d of the actual object inside of it
Vice_Versa, that's a couple of great ideas thanks. I might give the larger collider mesh as parent a go first and if I ever get into trouble with it I'll Raycast out.
So much simpler than the mess I was making, many thanks :)
Hmm, ok so I'm still a bit stuck.
If I use the larger collider I'm still in the same situation; I make a movement via the parent objects, the collision happens (with the larger collider), and only then can I react to it, I can easily competely prevent further movement from this point (as im already colliding) but how do I get the camera unstuck?
As for Raycasting, I'm moving around in 3 dimensions so that becomes tricky as I don't know where to fire it. I found SweepTest which would seem to be the thing to use ins$$anonymous$$d of single Raycasts. However, I come up against the problem of having to put my movement into FixedUpdate (i think) as the physics updates slower than normal Update, which makes it jerky as heck.
$$anonymous$$y biggest issue is that my capsule is the rigidbody collider, but my parent object is doing the moving.
Answer by zach-r-d · Jun 22, 2015 at 08:47 PM
Before moving the object, use Physics.CapsuleCast with the same direction and length that the capsule would be moving without collision. It works very much like a raycast, the only difference is that instead of moving a point through space to see if it hits anything, it moves an entire capsule through space.
If CapsuleCast returns false, then it didn't hit anything so the capsule is fine moving the entire distance it wanted to. Otherwise, using the information stored in the RaycastHit (the out parameter), it will be possible to respond to the collision however you wish.
So the issue I have is that my capsule is moved by the parent, so I can't input the vector3 for CapsuleCast as I don't actually know it. I only know the rotation and position change of the parent object which will result in a change of the capsules Transform.
The other thing I find is that to use this method of checking it relies on the physics engine which doesn't run each step (Does all collision checking rely on the physics engine? I assume so). I believe that this forces me to put my movement script into FixedUpdate, which produces jerky movement, I'm assu$$anonymous$$g I have to delve into movement smoothing to get away from the "jerkyness".
Thanks for the help though, much appreciated.
It can be calculated, though. If it is too difficult to manually create and multiply the matrices to calculate it, then one workaround is to update the parent transforms while ignoring collisions, get the transform.position of the capsule, then set the parent transforms back to what they were. Assu$$anonymous$$g none of these parents are scaling the capsule, then the height and radius remain the same.
CapsuleCast, like Raycast, returns immediately. It does not need to be used inside of FixedUpdate. In any case, camera updates are best performed in LateUpdate.
Sure, using a dummy capsule is the same as the workaround I described except using multiple objects rather than the same objects. If it's easier to think about in those terms, go for it.
Regarding the edit: the quote is true, but the conclusion is not. In this case, the physics engine is being queried, but not perfor$$anonymous$$g the actual movement; I assume there are no rigidbodies on the camera or its parents, and the transforms are being manually changed in scripting anyway. Plus, FixedUpdate will be run between one LateUpdate and the next, in most cases multiple times.
Interesting. The good news is that I have collisions thanks to your help, currently I have placed my code in FixedUpdate and used Rigidbody.$$anonymous$$ovePosition and Rigidbody.$$anonymous$$oveRotation to acheive my smooth movement.
The code; makes the move of a "ghostCapsule", gets the vector and it's magnitude from the current camera position and the ghostCapsule, plugs that vector into Physics.CapsuleCast and depending on the result, either matches the camera to the ghost, or reverts the movement made.
I still want to try and do this in a cleaner way so I will remove the rigidbody from the capsule and pop it into LateUpdate as you suggested.
You've more than answered my questions though so thank you kindly, I will mark it as answered even though I'll keep going to get a cleaner solution.
Ohh, I see. There's probably no harm in leaving camera movement in FixedUpdate, I just like doing camera positioning in LateUpdate since that way the camera can respond to any sudden changes that might have happened in scripting during regular Update this frame before rendering happens.
Thanks, BlueFireHearth. Best wishes for finding a clean solution!
Your answer
Follow this Question
Related Questions
Box collider (with Rigidbody attached) gets stuck into another Box Collider 0 Answers
How to get character movement done with box collider 2d? 2 Answers
Transforming position for different colliders for repeating background? 0 Answers
How to stop a character from moving out of player's control? 0 Answers
How to move a Game Object from a script not attached to it. 1 Answer