"SendMessage SetSpeed has no receiver!" error. FPS tutorial AI. (Img)

Im’ going to try this question once again.

Hey! Iv’e got a real strange problem here that i can’t figure out at all. Help me out here!

So the problem is that iv’e got a couple of characters following a AI script (The one from the FPS tutorial), until they are selected, then you control them using the keyboard, then when deselected it follows the AI instead.

My intention is to make the character keep following the waypoints.

Iv’e made a small painting of my own below, the red it’s route and where it stops, maybe it help… I get error “SendMessage SetSpeed has no receiver!”, on line 53 in the script. (Marked it)

The image: ImageShack - Best place for all of your image hosting and image sharing needs

It stops right there, eaven if you remove the waypoints with blue above it, so it hasn’t got something to do with them.

The code (AI):
var speed = 3.0;
var rotationSpeed = 5.0;
var shootRange = 15.0;
var attackRange = 30.0;
var shootAngle = 4.0;
var dontComeCloserRange = 5.0;
var delayShootTime = 0.35;
var pickNextWaypointDistance = 2.0;
var target : Transform;
//static var larsan = target;
var objektnamn : GameObject;
private var lastShot = -10.0;

// Make sure there is always a character controller
@script RequireComponent (CharacterController)

//function Awake() {
// target = transform;
//}

function Start () {
if (!this.enabled) return;

    // Auto setup player as target through tags
    if (target == null && GameObject.FindWithTag("Player"))
        target = GameObject.FindWithTag("Player").transform;

    Patrol();
}

function Patrol () {
if (!this.enabled) return;

    var curWayPoint = AutoWayPoint.FindClosest(transform.position);
    while (true) {
        var waypointPosition = curWayPoint.transform.position;
        // Are we close to a waypoint? -> pick the next one!
        if (Vector3.Distance(waypointPosition, transform.position) < pickNextWaypointDistance)
            curWayPoint = PickNextWaypoint (curWayPoint);

        // Attack the player and wait until
        // - player is killed
        // - player is out of sight     
        if (CanSeeTarget ())
            yield StartCoroutine("AttackPlayer");

        // Move towards our target
        MoveTowards(waypointPosition);  //Error here!

        yield;
    }
}


function CanSeeTarget () : boolean {
if (!this.enabled) return;

    if (Vector3.Distance(transform.position, target.position) > attackRange)
        return false;

    var hit : RaycastHit;
    if (Physics.Linecast (transform.position, target.position, hit))
        return hit.transform == target;

    return false;
}

function Shoot () {
if (!this.enabled) return;

    // Start shoot animation
    animation.CrossFade("shoot", 0.3);

    // Wait until half the animation has played
    yield WaitForSeconds(delayShootTime);

    // Fire gun
    BroadcastMessage("Fire");

    // Wait for the rest of the animation to finish
    yield WaitForSeconds(animation["shoot"].length - delayShootTime);
}

function AttackPlayer () {
if (!this.enabled) return;

    var lastVisiblePlayerPosition = target.position;
    while (true) {
        if (CanSeeTarget ()) {
            // Target is dead - stop hunting
            if (target == null)
                return;

            // Target is too far away - give up 
            var distance = Vector3.Distance(transform.position, target.position);
            if (distance > shootRange * 3)
                return;

            lastVisiblePlayerPosition = target.position;
            if (distance > dontComeCloserRange)
                MoveTowards (lastVisiblePlayerPosition);
            else
                RotateTowards(lastVisiblePlayerPosition);

            var forward = transform.TransformDirection(Vector3.forward);
            var targetDirection = lastVisiblePlayerPosition - transform.position;
            targetDirection.y = 0;

            var angle = Vector3.Angle(targetDirection, forward);

            // Start shooting if close and play is in sight
            if (distance < shootRange && angle < shootAngle)
                yield StartCoroutine("Shoot");
        } else {
            yield StartCoroutine("SearchPlayer", lastVisiblePlayerPosition);
            // Player not visible anymore - stop attacking
            if (!CanSeeTarget ())
                return;
        }

        yield;
    }
}

function SearchPlayer (position : Vector3) {
if (!this.enabled) return;

    // Run towards the player but after 3 seconds timeout and go back to Patroling
    var timeout = 3.0;
    while (timeout > 0.0) {
        MoveTowards(position);

        // We found the player
        if (CanSeeTarget ())
            return;

        timeout -= Time.deltaTime;
        yield;
    }
}

function RotateTowards (position : Vector3) {
if (!this.enabled) return;

    SendMessage("SetSpeed", 0.0);

    var direction = position - transform.position;
    direction.y = 0;
    if (direction.magnitude < 0.1)
        return;

    // Rotate towards the target
    transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);
}

function MoveTowards (position : Vector3) {
if (!this.enabled) return;

    var direction = position - transform.position;
    direction.y = 0;
    if (direction.magnitude < 0.5) {
        SendMessage("SetSpeed", 0.0);
        return;
    }

    // Rotate towards the target
    transform.rotation = Quaternion.Slerp (transform.rotation, Quaternion.LookRotation(direction), rotationSpeed * Time.deltaTime);
    transform.eulerAngles = Vector3(0, transform.eulerAngles.y, 0);

    // Modify speed so we slow down when we are not facing the target
    var forward = transform.TransformDirection(Vector3.forward);
    var speedModifier = Vector3.Dot(forward, direction.normalized);
    speedModifier = Mathf.Clamp01(speedModifier);

    // Move the character
    direction = forward * speed * speedModifier;
    GetComponent (CharacterController).SimpleMove(direction);

    SendMessage("SetSpeed", speed * speedModifier, SendMessageOptions.DontRequireReceiver);
}

function PickNextWaypoint (currentWaypoint : AutoWayPoint) {
if (!this.enabled) return;

    // We want to find the waypoint where the character has to turn the least

    // The direction in which we are walking
    var forward = transform.TransformDirection(Vector3.forward);

    // The closer two vectors, the larger the dot product will be.
    var best = currentWaypoint;
    var bestDot = -10.0;
    for (var cur : AutoWayPoint in currentWaypoint.connected) {
        var direction = Vector3.Normalize(cur.transform.position - transform.position);
        var dot = Vector3.Dot(direction, forward);
        if (dot > bestDot && cur != currentWaypoint) {
            bestDot = dot;
            best = cur;
        }
    }

    return best;
}

You are sending a message to the same GameObject that contains this script. This mean that this GameObject must have attached some other script that contains a function named SetSpeed so the message could be delivered. Something like this:

function SetSpeed(value : float)
    {
    speed = value;
    }

So the most probable cause for that error is that you forgot to add some other script to the GameObject. Or maybe you should just add the previous function to the script where the character variables are defined (speed, rotationSpeed, etc).

If you are sure that you don’t need to use the SetSpeed message, then you can make all the SendMessage functions not to require a receiver:

SendMessage("SetSpeed", 0, SendMessageOptions.DontRequireReceiver);