- Home /
Making Colliders/Triggers or Rigidbodies move a Character Controller
There seams to be a general consensus that the preferred way to affect a character by either animated colliders or rigidbodies is to not use a character controller at all. Unfortunately at this stage of the project, many of the developed character scripts have been specifically based on the constraints and behavior of a character controller. Further, implementing a rigidbody controller setup from scratch is not feasible at this point.
We are exploring alternatives and looking for opinions on this topic, so please feel welcome to add your input and comment any ideas or suggestions you feel are relevant. Here are our possible solutions:
1) Set an animation state which is triggered during collision with tagged moving objects, eg. an opening door, moving traffic etc, causing the character to fall or be moved aside via animation.
2) Switch to rag doll upon collision, creating rigidbody collisions, before blending back to the animated character.
3) Add a rigidbody component to the character controller and have it add force to the collision objects, except making the force value negative.
4) Parenting the character upon collision (similar to the technique used for moving platforms), and perhaps having the unparenting controlled by a timer. This solution has not been looked into extensively and is merely an idea at this point.
If you have prior experience in similar character setups or interactions please comment which suggestion you feel is the most useful, or supply your alternative instead.
From the team, thank you.
[1]: http://answers.unity3d.com/questions/212557/making-a-character-controller-push-another-charact.html
Answer by thorbrian · Nov 22, 2011 at 11:27 PM
If I were you, I'd forget about character controller entirely. Personally I think the character controller driven models look terrible.
I'd recommend using blends animations from the artists for character movement, driving the speed of the animations based on move speed. Where you want a ragdoll for collisions and stuff, I'd suggest jumping into ragdoll on collision, and then transitioning out of ragdoll by interpolating the model into the start frame of one of a few "get up" animations.
If you want to see an example of a (non-unity) game that uses the same approach, check out wolfire game's overgrowth: http://blog.wolfire.com/2011/04/Overgrowth-a126-video-changelog
Thanks for the link. This system seams similar to the Advanced RagDoll system developed for Unity: http://www.youtube.com/watch?v=c48LgED93iw.
Currently, we are considering the ragdoll solution as the most probable answer because of the realistic results it creates. The only potential problem we see with this is managing the interpolation from ragdoll to animated character. In a scenario where an animated object (eg. a moving vehicle/s) can potentially collide with the character controller, there seams to be almost an infinite number of possibilities in how the two objects can interact since both are moving. How does one decide when to transition from the ragdoll back to the character (based on a timer system, or if the ragdoll is no longer being collided with?)? While the ragdoll is in this transition there is also the possibility that another collision may occur forcing the transition to be reset, which if the collisions kept occurring, could potentially cause an infinite transition loop could it not?
Interpolating the ragdoll joints and blending these movements with the characters key framed animation seems to be the best solution so far. A full rag doll character setup was presented at Unite, however I haven't found any documentation on how this was achieved.
For simplicity sake, I think you'd want to be in one of 3 states - full ragdoll or fully animated character or transitioning from ragdoll to the first frame of an animation - any time I've seen a system that tried to partially animate and partially ragdoll (like Die by the Sword for instance), it got strange and unnatural results, the animations of one bone usually make no sense out of the context of the rest of the pose (imagine somebody pushing off the ground with their wrist bent back by the ground - if ragdoll pulled the arm out from under the char, the bent back wrist would look freaky). So for the problem of when to transition - say for a character being hit by a car - you'd probably want to have light hits either push the character or trigger a bumped by car animation, and then any hit that crosses the threshold, jump straight to full ragdoll (this is what Grand Theft Auto does, btw). For the trigger to go back to animated, I would say you'd want to look at some kind of physics settling criteria.
Very interesting. We aren't trying to achieve a system similar to any particular game, but the fact that what you suggest is already being implemented definitely makes it sound more promising :)
One final question (I tried asking this previously but I think it got jumbled by my other questions, apologies): when in a full ragdoll state we are worried about the lack of control we will have in deter$$anonymous$$ing the pose of the character after the collision, when it is lying/crumbled on the ground. How does one prevent this final crumbled pose from being a complete jumbled mess, since it seems the physics engine will have sole control over this, and naturally, it will look very unrealistic trying to interpolate from such an awkward pose. The only solution we can see is a custom ragdoll setup with tested, specific joint limits set to prevent this. Thank you again for you insightful response!
Answer by Owen-Reynolds · Nov 23, 2011 at 01:00 AM
This has the virtue of being local to your characterScript. It works, but not sure if it can be tuned to look nice. Toss a slightly larger triggerbox on your character, then:
Vector3 pushAmt; // global "pushed by RBs" accumulator
void OnTriggerEnter(Collider cc) {
Rigidbody rb = cc.rigidbody;
if(rb!=null) {
pushAmt += rb.velocity*0.5f;
}
}
PushAmt is added to the final move in FixedUpdate:
moveDirection += pushAmt;
pushAmt*=0.95f; // fake friction
Other options (untested) are to have OnTriggerStay also do it, so an object can give a continuous push instead of only a shove. The animation could be triggered by the final move -- walking backwards might look the same if we were gently shoved, or doing it on purpose. Could have OnTrigger also play a "flinch" for sufficiently large new pushes.
Also the option of checking for specific tags ("doors" objects always shove you directly away from them, at speed X, say.)
Yes, this is the simplest solution we were hoping for. As you mentioned, the only issue here being of course how realistic it can be made to look. I am guessing that the above set up assumes a rigidbody is attached to the character controller? Also, would it be possible to have the trigger boxes attached to the colliding objects ins$$anonymous$$d, and have them trigger the "pushing" script when colliding with the character controller? Thank you for your answer.
I used only a charController and a triggerBox. The trigger was because (AFAI$$anonymous$$,) charControllers aren't notified when things hit them.
Should be possible to have all other colliders (the ones with RBs,) check for collision with the player and call cc.getComponent<playerscript>().doPush(rigidbody.velocity)
or something. That seems like a lot of work, through, to modifiy everyone else that way.
Ok, so the rigidbody component would only need to be added to the "collision object" correct? We have previously made some simple experiments with this (on a triggered, animated swinging door) and we found that during the animation the door would detach from it's hinges and either go for a wander or fall through the ground. If I remember correctly, the only way we could avoid this with a RB, was to set it to 'is kinematic'?
And yes, it would be more work for sure. At this stage though we would like to keep the character as "clean" as possible, since we will most likely be implementing a multiple trigger setup for the combat system, and so the less triggers on the character before that process the better :) Thank you very much for this example, we are very excited about trying out this setup.
It's a problem, no matter what the method, of knowing if you hit the player. I assumed you had objects moving using physics/rigidbodies. They fire CollisionEnter when they hit a charCont (but not when a charCont hits them. Argg.)
Objects moving with either a kinematic RB, or none, won't fire OnCollision with a CharCont. Only way I know is to add a triggerBox to the other moving object.
Ok, I am trying to implement the script you suggested above, but it doesn't seem to be working for me. I have made a separate question about this here for clarity. Would you $$anonymous$$d having a look and letting me know where I am going wrong please?
Answer by Pilot · Mar 13, 2012 at 07:19 PM
For those people still interested in moving a character controller via an impact based collision system, I would highly recommend looking at the old third person shooter demo.
There is a script on the Hero character which moves the character a specified distance whenever they are struck via raycast by the enemy bot. Maybe someone can take this and turn it into a more useful onTriggerEnter/OnCollisionEnter script. That's all it would take.
Answer by Bunny83 · Nov 22, 2011 at 10:50 PM
Well, the only advantage beside the many disadvantages a CharacterController has is that it's NOT invluenced by other objects. A CharacterController is not a phyics-controlled object.
It strongly depends on how much you want to put the control of your character to something else. If you move it manually it propably doesn't look "real".
This is hard to do because you in most cases the movement depends on the relative position to the other object. A rotating door moves faster outside than near the hinge.
I don't see how this should work. If you turn your character into a rag doll every part of your character moves on it's own. The model will "fall" out of it's CharacterController-GameObject. Rigidbodies are always simulated in worldspace.
I don't get the negative thing... What force you want to invert and apply to what object?
This can work out in some cases but generally can produce very strange behaviour.
If you really want to stick with your CharacterController you have to decide in each case what's the best way. The most general way is using a Rigidbody :D That's why we have a physics system.
However in our Hack&Slash game we also used the CharacterController. We also have a special case where the character is under foreign control (a push attack). This effect is integrated in everything (to prevent player movement and to apply the push force). It's not a very nice solution but most of time we're happy with the nature of the CharacterController. We also thought about using a Rigidbody controller, but we had even more problems so we stick with the CC.
Well some thing doesn't work very well, like the slopelimit, but we have a custom solution for that ;). All in all the CharacterController is not that bad but if you want a mixture of direct control and physics you propably should use a Rigidbody.
Just to be clear: There's nothing that can't be done. It's always a matter of effort you put into it. You don't have to use PhysX, you're free to calculate everything on your own if you know how ;)
Finally i'd like to say that i'm not sure what you expect as answer. It seems that this "question" tries to start a discussion which is something that should be posted on the forums instead. UnityAnswers is for clear "questions that can be answered".
Thank you for your input. It is always helpful receiving responses as thorough as this. In regards to your first question concerning the negative force, we were exploring a seesaw script posted almost a year ago: http://answers.unity3d.com/questions/33765/see-saw-affected-by-character-controller.html , it may be obsolete as of now but we have not yet had the chance to test it for our purposes.
The crux of the issue remains character interaction between animated objects in the scene and vice versa. I used the door example as it illustrates the problem in the most simplest scenario (in reality, the interactions we are working with are much more complex); this problem being that during the period of an objects animation (eg. a door opening or closing), irrespective of whether it has a collider or not, it will pass through a moving or stationary character. While when not animating, the same objects collider will block a character controllers movement through it.
We have posted a similar question as this in the forums, however there have been no replies. For this reason, even though this is a discussion question, we have posted here. Through our research we have found this issue quite popular among the Unity community, however with few workable solutions. We believe this discussion will benefit many more Unity members seeking similar answers to our $$anonymous$$m. :)
Answer by Pilot · Mar 13, 2012 at 07:02 PM
Would just like to add here, for those using the character controller <---> ragdoll setup, a good way to transition from ragdoll back to the animated character is to animate the ragdoll into a transition animation. To do this one can turn the ragdoll rigidbodies to kinematic and then animate them the usual way until in a position to switch back to the CC.
Hope that helps.