Alternative to character controller? (Multiple CCs are mangling my framerate)

I've got a scene with about 200 NPCs in it. Each one has an example script attached to afford 'random' movement (courtesy of a Unity forum user):

var ground: Transform;
var gravity: Vector3;
var speed: float;

var motionDir: Vector3;
var ctrl: CharacterController;

function Start() {
    ctrl = GetComponent(CharacterController);
    NewDirection();
}

function Update () {
    ctrl.Move((motionDir * speed + gravity) * Time.deltaTime);
}

function OnControllerColliderHit(collision: ControllerColliderHit) {
    if (collision.transform != ground) {
        NewDirection();
    }
}

function NewDirection() {
    motionDir = (new Vector3(Random.value - 0.5, 0.0, Random.value - 0.5)).normalized;
    transform.rotation = Quaternion.LookRotation(motionDir);
}

There's a problem! Each NPC needs a Character Controller for this script to reference...but with 200 in the scene at once, play slows to a crawl. For a code noob: is there a less computationally-draining alternative to the Character Controller out there somewhere? Or, any suggestions for a script that produces similar results to this without needing a Character Controller?

Consider having NPCs outside the players view disabled.

It depends on what you're trying to get the character to do. Could you give more details?

If what you're looking for are steering algorithms to drive your characters, you could look into UnitySteer. However, depending on your level of experience, building up a controller from the various algorithms in the toolkit might seem complex.

Update: I just noticed that you're updating every character, every frame. Is that really necessary? You could have a round-robin mechanism where you only update a few objects per frame.

This is a problem best solved with code, or changing the problem.

Your best option is not having 200 characters in the scene, obviously.

Alternatively, it may be the Move() function is causing most of the slowdown, not the characterController itself. You can determine this in the profiler.

If that is the case, you could only call Move() on the characters that actually need to be moving, instead of on all 200 at once. Have the AI determine when a character should move, and only then call Move().

If this is some epic battle with 200 people running around - I don't think there will be a simple solution, your best bet is to start learning about the physics system, raycasts, triggers and so on.

It may not be the Character Controller see

http://forum.unity3d.com/viewtopic.php?t=39946

One simple optimization you can do to that script:

Store this value (motionDir * speed + gravity) in a Vector3, and update it only when "motionDir" or "speed" change.

So your code can be:

function Update () {
    ctrl.Move(motionVector * Time.deltaTime);
}

function NewDirection() {
    motionDir = (new Vector3(Random.value - 0.5, 0.0, Random.value - 0.5)).normalized;
    motionVector = motionDir * speed + gravity;
    transform.rotation = Quaternion.LookRotation(motionDir);
}