Rendering Order

How would I go about changing the order an object is rendered to the screen? I have a crosshair sprite that is drawn -120 units down the Z axis of the player ship, but I'd like it to be rendered after everything else on the scene so it is always on top.

Note that, due to the camera following the ship smoothly and not exactly, I cannot put the crosshair on the GUI as it will be very inaccurate.

No need to modify the shader, you can set Material.renderQueue instead.

[EDIT] In my project, I've added a render queue enum that I use to manage queues project-wide. Various bits of code around the project use this enum to set material.renderQueue. I use the convention of indenting my in-between layers. (A lot of materials stay at their defaults, this is just when I need procedural control.)

// RenderQueue provides ID's for Unity render queues. These can be applied to sub-shader tags,
// but it's easier to just set material.renderQueue. Static class instead of enum because these
// are int's, so this way client code doesn't need to use typecasting.
// From the documentation:
//      For special uses in-between queues can be used. Internally each queue is represented
//      by integer index; Background is 1000, Geometry is 2000, Transparent is 3000 and
//      Overlay is 4000.
// NOTE: Keep these in numerical order for ease of understanding. Use plurals for start of
// a group of layers.
public static class RenderQueue
    public const int Background = 1000;

        // Mid-ground.
        public const int ParallaxLayers = Background + 100;       // +1, 2, 3, ... for additional layers

        // Lines on the ground.
        public const int GroundLines = Background + 200;

        public const int Tracks = GroundLines + 0;
        public const int Routes = GroundLines + 1;
        public const int IndicatorRings = GroundLines + 2;

    public const int Geometry = 2000;

    public const int Transparent = 3000;

        // Lines on the screen. (Over world, but under GUI.)
        public const int ScreenLines = Transparent + 100;

    public const int Overlay = 4000;

In your shader use the appriopriate tag that defines the rendering order (subshader tags):

Tags {"Queue" = "Overlay" }

Although you already got a good answer, I was wondering why you dismiss placing the crosshair using the GUI layer (or a sprite manager on a orthographic camera). With:

Camera.WorldToScreenPoint(position : Vector3) : Vector3

you could get the screen coordinates of your target and get pinpoint precision placing it on screen without worrying about scaling and lighting effects you could get when placing a mesh in the scene (although both are solvable).

If you can create a new layer in the Cross Hair Inspector’s Sprite Renderer you can then assign the Crosshair the new layer and it should render “last”, and that means in the foreground.