EPIC WIN:
The problem is solved, I share it so anybody can have the same level of flexibility.
Why using this instead of character controller?
It gives you more data about your collision and how you want to process them. Rigidbodies return a structure that return all collision around the collider, it allow you to process angle of collision for example from multiple collision. If you want you character to be aware of the world around him (putting his hand on wall while still moving along them) it's the faster way. Collision is more solid too and feel better. Other solution may involve listening to get and listen to every collider you where in collision with, and ven with that you may not be able to listen more than one collision with one collider. For world like mesh, it's the better way.
How does it work?
Currently My code is organize like this:
UPDATE loop
-state selection (process input and state transition)
-update output
FIXEDUPDATE
-reset the collision position based on last collision
-Call collision and process motion code based on state
-perform motion into space
OnCOLLISIONstay listener
-create collision structure to pass to collision processing
Details:
I have (oups click post instead of preview ... wait)
//Collision
Collision collision;
Rigidbody body;
Vector3 Displace;
First I have I declare some variable to use and pass collision information. You need a type
collision to hold the structure of collision data. Rigidbody is the physic controller that will return the collision data. Displace is the virtual position of your motion processing. I also use a sphereCollider but any collider is fine.
void OnCollisionStay(Collision col)
{
this.collision=col;
}
In OnCOLLISIONstay you put a code to gather collision data and pass it to your custom collision handling with the member collision you created. You need this as you can't access easily collision data from anywhere else.
[Type] TestCollisions()
{
//variable to process data
...
//check if the structure exist
//It won't be create until there is a collision
if (collision != null)
{
foreach (ContactPoint contact in this.collision.contacts)
{
//access elements of contact structure
//process here each data (local collision) and passed it with some variable
}
}
//here process the result from the loop you passed (overall collision)
return result
}
Collision data is then process in a testCollision method. Result is then passed to outside world through direct manipulation of member data and return. In my case I return a OnGround bool and manipulate some motion and alignment data. Why this code is not in OncollisionStay? Because I want it to run even when there is no collision.
ON fixed Update
//reset position to last collision position
this.Displace=this.transform.position;
I have a code that reset the virtual position to the current real position. When I move the object to the next position, I don't know if there is a collision. But I use a particular unity command who truncate any movement, as soon it detect a collision, to the collision point. In order to keep the custom space and the real space in check I need that.
void Motion ()// collision handle and aplication of movement in space
{
//test out collisions with scenery since last update.
//if so set the alignement
this.collisionTest = this.TestCollisions();
//Now, just move
//to the new position
//based on it's speed
Vector3 MoveController;
if (this.collisionTest)//for different flag data
{
this.Align();
//some other code
...
//adapt to controller May alter
MoveController=new Vector3 (this.Motion_Speed * Time.deltaTime * [some other data]);
MoveEntity(body,MoveController);
}
}
Then I move the rigidbody into real space by converting the virtual space based on some flags.
void MoveEntity (Rigidbody body, Vector3 MoveController)//move the custom space in to unity space
{
MoveController= this.body.transform.TransformDirection(MoveController);
this.Displace=MoveController + this.Displace;
this.body.MovePosition(this.Displace);
}
MoveEntity is a custom method that handle the conversion from one space to another. It add the virtual motion (moveController) to real space (displace) with TransformDirection and let unity truncate the real movement with MovePosition (which is update with the reset code). Generally Virtual space are made respective to some object space and handle through align to current object space.
//take input data and turn it into speed, friction and direction control along motion vector
void Handle()
{}
Then I process Motion code in my custom space. and the loop start again.
Why it's better
It allow you to have physics along cylinder or spline (or any warp space you can imagine) and still interact with original unity physics.
You can have very precise physics that are tied to the bound you want and non physical or natural movement.
It's stronger than Character controller and allow more precise control and interaction with scenery.
With iskinetic flag you no longer detect collision but other collider still react to the collider, cool for going through floor and still influence the scenery along your path.
It allow you to switch to unity physics on the fly.
No noise from unwanted physic influence. You can discard any data that does not fit the desired behavior.