CharacterController "breaks" collision, goes haywire

Setup: I have a 2D XZ planed world that my character controller moves around in (top-down view). I have a tilemap with many mesh colliders (rectangular).

Question: Whenever I place polygonal colliders in the world (of any type) my character can seemingly “break” through them. When I push up against them for long enough, my character just “snaps” and starts rotating rapidly around the Y axis (3D space), or goes invisible. How do I prevent this?

What I’ve already tried: I’ve tried increasing the collider depth of all objects involved in these scenarios, I have attached a rigidbody and locked rotation on the X and Z axes, and locked position on the Y axis, and I have manually tried updating the EulerAngles every frame by setting the Y rotation to 0 every frame. This appears to help somewhat, yet still the character “breaks”.

I find this sort of humorous, if the character tries hard enough, he can somehow break the rules of programming, and enter into the 3D world…VERY frustrating.

Here’s the character script, if it helps:

using UnityEngine;
using System.Collections;

public class DungeonPlayerBehaviorScript : MonoBehaviour {
	private const float VELOCITY = 40;
	private const float ROTATION_SPEED = 1024.0f;  // Degrees per second
	
	private CharacterController controller;
	private Vector3 direction;
	private tk2dSpriteAnimator animator;
	
	private Quaternion qTo;
	
	private bool joystickConnected;
	
	void Start () {
		//ONLY FOR TESTING PURPOSES
		//TODO: Make multiplayer-compatible joystick and input system
		if (Input.GetJoystickNames ().Length > 0) {
			joystickConnected = true;
		} else {
			joystickConnected = false;
		}
		
		animator = GetComponent<tk2dSpriteAnimator>();
		
		Light2D.RegisterEventListener (LightEventListenerType.OnEnter, onBeamEnter);
	}
	
	void Update () {
		updateFrameVariables();
		
		if (joystickConnected) {
			joystickMovementUpdate();
		} else {
			keyboardMovementUpdate();
		}
		
		if (controller.velocity.sqrMagnitude > 0) {
			animator.Play ("forward");
		} else {
			animator.Play ("idle");
		}
	}
	
	private void joystickMovementUpdate() {
		if (direction.sqrMagnitude > 0.1f) {
			qTo = Quaternion.LookRotation(direction);
			qTo.eulerAngles = new Vector3(90, qTo.eulerAngles.y + 90, 0);
		}
		transform.eulerAngles = new Vector3(90, transform.eulerAngles.y,0);
		transform.rotation = Quaternion.RotateTowards(transform.rotation, qTo, ROTATION_SPEED * Time.smoothDeltaTime);
		controller.Move (new Vector3(Input.GetAxis ("Left Joystick Horizontal") * VELOCITY, 0, -Input.GetAxis ("Left Joystick Vertical") * VELOCITY) * Time.smoothDeltaTime);
	}
	
	private void keyboardMovementUpdate()  {
		transform.LookAt (Camera.main.ScreenToWorldPoint (Input.mousePosition));
		controller.Move (new Vector3(Input.GetAxis ("Keyboard Horizontal") * VELOCITY, 0, Input.GetAxis ("Keyboard Vertical") * VELOCITY) * Time.smoothDeltaTime);
	}
	
	private void updateFrameVariables() {
		controller = GetComponent<CharacterController>();
		direction = new Vector3(Input.GetAxis ("Right Joystick Horizontal"), 0, Input.GetAxis ("Right Joystick Vertical"));
	}
	
	void onBeamEnter(Light2D light, GameObject go) {
		Debug.Log (go.tag);
		if (go.CompareTag ("Mob One")) {
			go.GetComponent<MobOneBehaviorScript> ().State = 1;
		}
	}
	
	void LateUpdate()
	{
		Camera.main.transform.position = new Vector3(transform.position.x, 2, transform.position.z);
	}
}

Sounds like an extra rigidbody on the player is causing the problem. Generally RBs and CC’s on the same object fight each other.

Unlike a rigidbody “physics object”, a characterController will never decide to just spin (your “rapidly spin around y” issue.) Rotation is completely controlled by the particular script, and most of them are pretty boring – they rotate a fixed rate L/R based on arrow keys.

The problem was that my CharacterController height was not high enough, and my player was “stepping” over the other object :slight_smile: