First Person Shooter - How to change color of enemy red or green if it's in or out of range?

How can I make a ray change the color of the object it hits first or use a boxcollider trigger instead?

No matter what i do with the function "OnTriggerEnter" or anything similar i get non satisfying results.

I would like it if when I point at an object in a (first person shooter) and it is in range then it turns green other wise red. I would like to manipulate the object if it is in range.

Any advice would be great, Thanks a ton!!

Okay, this is a fairly complex question but it piqued my interest :-)

You need to do this using Physics.Raycast to cast a ray from the centre of the screen (assuming that this is a standard first person shooter with a fixed crosshair in the centre of the screen).

You then need to make sure any targets have colliders, because the raycast will only detect objects with colliders. You'll also want to make sure all your targets have a certain tag (such as "Enemy") so that you don't go round turning your scenery green or red!

Because only one object at a time will be coloured, we can use a single variable ("originalColor") to store the original colour of the object, so that we can re-set it when it leaves the target area or when another object is detected.

Below, I have split up the functionality into a few different functions.

  • the main Update() function (executed every frame), which casts the ray and checks if an enemy was detected.

  • the CheckObject() function, which determines whether it is a new object, whether it is in or out of range, and changes the colour.

  • the ResetLastObject() function, which turns the last detected object back to its original colour. This is in a separate function because it's called from a number of places.

And here's the code:

var range = 40;              // objects nearer than this are green
var rayLength = 200;         // objects beyond this are not detected at all

private var ray : Ray;
private var hit : RaycastHit;
private var lastObj : Transform;
private var originalColor : Color;

function Update() {

    // get a ray corresponding to the current camera's screen centre:
    ray = Camera.main.ScreenPointToRay (Vector3(Screen.width/2,Screen.height/2));

    // cast the ray and check if any enemies detected
    if (Physics.Raycast (ray, hit, rayLength)) {
        if (hit.transform.tag == "Enemy") {
            CheckObject(hit); // enemy!
        } else {
            ResetLastObject(); // non-enemy under cursor
        }
    } else {
        ResetLastObject(); // nothing under cursor
    }
}

// this function determines whether to paint the object green or red
function CheckObject(hit : RaycastHit)
{
    if (hit.transform != lastObj) {
        // a new object detected
        ResetLastObject();

        // record original colour of new object
        originalColor = hit.transform.renderer.material.color;
        lastObj = hit.transform;
    }

    if (hit.distance < range) {
        hit.transform.renderer.material.color = Color.Lerp(originalColor, Color.green, 0.5);
    } else {
        hit.transform.renderer.material.color = Color.Lerp(originalColor, Color.red, 0.5);
    }
}

// this function restores the last detected object to its original colour
function ResetLastObject() {
    if (lastObj != null) {
        lastObj.renderer.material.color = originalColor;
        lastObj = null;
    }
}