Cool thanks Jon, didn’t know you could get a list of all materials. But would this work with an alpha blended terrain shader? (forgive my lack of shader knowledge).
Anyway, for the vertex color idea, I just whipped up a script to do that.
It’s in C#, but pretty well abstracted. It currently has the debug run still set (to remove it, delete the Update() block)
using UnityEngine;
using System;
using System.Collections;
public class GroundType : MonoBehaviour
{
public Transform characterTransform = null; //if left unset, it will use the current object's transform
public Color[] groundTypeColors = null; //the colors we want to use to specify our ground types
public Vector3 raycastDirection = Vector3.down;
public float raycastDistance = 10.0F;
private RaycastHit hit;
private int triIdx;
private Vector3[] vertices;
private int[] tris;
private Color[] colors;
private Color p0, p1, p2;
void Start()
{
if (characterTransform == null)
characterTransform = transform;
}
void Update()
{
Debug.Log(GetGroundColor().ToString());
}
public int GetGroundColor()
{
if (Physics.Raycast(characterTransform.position, raycastDirection, out hit, raycastDistance))
{
//set up the mesh data
MeshCollider meshCollider = hit.collider as MeshCollider;
if (meshCollider == null || meshCollider.sharedMesh == null)
return -1; //error
Mesh mesh = meshCollider.sharedMesh;
vertices = mesh.vertices;
tris = mesh.triangles;
colors = mesh.colors;
//now check the vertex colors
triIdx = hit.triangleIndex;
p0 = colors[tris[triIdx * 3 + 0]];
p1 = colors[tris[triIdx * 3 + 1]];
p2 = colors[tris[triIdx * 3 + 2]];
for (int i = 0, iLength = groundTypeColors.Length; i < iLength; i++)
{
for (int x = 0, xLength = vertices.Length; x < xLength; x++)
{
//currently only checks one point of the triangle, if you need to test all 3, do the same test for p1 and p2 as well
if (Mathf.Approximately(p0.r, (float)groundTypeColors[i].r) Mathf.Approximately(p0.g, (float)groundTypeColors[i].g) Mathf.Approximately(p0.b, (float)groundTypeColors[i].b))
{
//Debug.Log(i.ToString());
return i;
}
}
}
}
return -1;
}
}
Put this on some object and set the following vars in the inspector:
-Character Transform = drag your character to this slot if this script is not on your character. Otherwise leave blank and the raycast will be fired from the position of the object this script is placed on.
-Ground Type Colors = is an array of all the vertex colors you want to test against. Set size to the amount of colors you want to test against, and set them accordingly.
Raycast Direction = set to Vector3.down (0, -1, 0), you should be able to leave this alone.
Raycast Direction = the distance to fire the raycast. Set to 10 which should be fine, but if your character is not finding any colors, this may need to be set larger.
It will print the index of the color it found in the console at the bottom (returned values explained below)
The function GetGroundColor() returns a number which tells you what color (if any) it hit. The returned number is an index to that Ground Type Colors array we set earlier, so a returned index of 1 would be the “Element 1” color.
GetGroundColor() will return -1 if none of the colors match.
please note This currently only checks against 1 vertex of the hit triangle. If you need to make sure all 3 points have the same color, modify the code where I commented.
I am sure there is a nicer way to do it, but it works. 
You should also be able to convert this to JS easy enough.
HTH,
-Jeremy