Troubles making custom 3D character controller (for platformer)

By using Unity’s character controller I had troubles implementing features like moving platforms and rotating platforms which needs to move/push and rotate players in expected way. I was not satisfied with the attemps I made with the Unity’s character controller (and rigidbody as well) so I’ve decided to make my own.

So I’m basically not asking how to implement specific thing , just am I at the right way.

So , when I was developing the custom character controller I found out that you can’t manually check collisions and get Collision data in regular way. I found the only options were functions like Physics.OverlapCapsule which returns the Colliders (which are objects) with which the virtual capsule has collided. One of the problems which has occured is that I cannot get the Collision point which I need to check is the platform ground or ceiling, if it is ground I move player upwards otherwise downwards.
I was expermenting with Collider.ClosestPoint but it doesn’t work for non-convex meshes, and levels are obviosly not convex.

So my questions are next:

  1. Am I too optimistic with creating custom character controller (Is it a good idea).
  2. Am I creating the custom character controller the right way (by using OverlapCapsule)
  3. If it is a good idea how to get collision point of collisions which happens with OverlapCapsule
  4. And if it isn’t a good idea what is the better way to implement 3D platformer and moving / rotating platforms

Just to get the right feeling what I am trying, I will put some parts of the my character controller.

public bool PlayerCollisionCheck()
{  
     return Physics.CheckCapsule(transform.position + Vector3.down*0.5f, transform.position + Vector3.up * 0.5f, 0.5f);
}
//this solves if player is in ground or in ceiling
  public void PlayerYCollision(float oldVelY)
     {
         int counter = 0;
         while (PlayerCollisionCheck() && counter++ < 100)
         {
             ySpeed = 0;
             if (oldVelY < 0)
             {
                 transform.Translate(Vector3.up * 0.01f, Space.World);
                 isGrounded = true;
             }
             else
             {
                 transform.Translate(Vector3.up * -0.01f, Space.World);
             }
         }
     }

Because of this way I cannot use the events(messages) like OnCollisionEnter, because I cannot solve them when more than one collisions occurs at the same frame.

The current version I made, have problems when you’re touching ceiling and ground at the same time , you get teleported to top of the ceiling.

It’s not trivial and not something you do with an engine unless you understand it fairly well and know about physics, kinematic motion etc. The fact that you’re using a simple OverlapCapsule and don’t seem to be aware of CapsuleCast would suggest that you’re not that familiar with Unity physics so it’ll be a learning curve for you for sure, which isn’t necessarily a bad thing.

Getting contacts points and solving them for all edge-cases will be your journey into starting to understand how difficult writing a solver, even a simple one can be. Simplpe movement is easy, interaction with dynamic elements in the world makes it harder.

I cannot answer all your questions on approaches and likely other would have suggestions. By far the best way would be to look at the code of existing solutions out there.

Good luck though!