Сам по себе CharacterController имеет внутренний капсуль-коллайдер, который так-то не должен застревать внутри других объектов. Такое может происходить в случае неправильного использования (скрипты). Например, толкать персонажа внутрь коллайдера со слишком большой силой. Сделай вы так со стандартной связкой коллайдера и твёрдого тела, последний бы просто улетел от накопившихся внутренних напряжений. CharacterController же, в свою очередь, не то чтобы сдвинуть, даже телепортировать извне никак нельзя без его отключения.
Также такой баг теоретически может возникнуть при движении с использованием свойства velocity, словно это rigidbody. Если вы вдруг так делайте - используйте метод Move(Vector3).
Кроме того, ваш контроллер сам по себе не знаком с гравитацией. Есть также ненулевая вероятность, что стоя краешком на обрыве персонаж всё ещё считает себя стоящим на земле, и у вас не срабатывает код гравитации (если он вообще есть).
В любом случае, для более квалифицированой помощи рекомендую приложить скриншот, содержащий настройки персонажа и раскрытый вид иерархии персонажа, а также код движения.
Примерно вот так выглядит обычный скрипт персонажа с таким контроллером:
скрипт
using UnityEngine;
[RequireComponent(typeof(CharacterController))]
public class PlayerMove3D : MonoBehaviour {
CharacterController controller;
Vector3 input, velocity;
public float moveSpeed = 10f;
public float jumpPower = 10f;
public float gravity = 20f;
public Transform groundCheckPoint;
public float groundCheckRadius;
public LayerMask groundLayer;
private void Start() => controller = GetComponent<CharacterController>();
private void Update() {
input.x = Input.GetAxis("Horizontal");
input.z = Input.GetAxis("Vertical");
input = input.normalized;
bool grounded = Physics.CheckSphere(groundCheckPoint.position, groundCheckRadius, groundLayer);
if (grounded && velocity.y < 0)
velocity.y = -2f;
if (Input.GetKeyDown(KeyCode.Space) && grounded) {
Jump(Mathf.Sqrt(2f * gravity * jumpPower));
}
}
private void FixedUpdate() {
Vector3 moveVector = transform.right * input.x + transform.forward * input.z;
controller.Move(moveVector * moveSpeed * Time.fixedDeltaTime);
velocity.y -= gravity * Time.fixedDeltaTime;
controller.Move(velocity * Time.fixedDeltaTime);
}
private void OnControllerColliderHit(ControllerColliderHit hit) {
// TODO collisions
}
}