R, 153 135135 113 bytes
function(s){S=el(strsplit,S=utf8ToInt(s,""))
S[S=="_"]=letters[1+2^{S[S==95]=2^(4:0)%*%matrix(grepl("[A-Z]",S[greplS[S%in%c("[a-zA-Z]"65:90,S)]97:122)]<95,5)]+97
cat(tolower(intToUtf8(S),sep=""))}
Issues some warnings with the use of matrix
but that shouldn't affect the result. Also issues warnings as [<-
assignment will remove extraneous assigned objects by default.
Thanks to @JayCe for knocking off a whopping 18 bytes, by pointing out that truncating the encoded chars is unnecessary.40(!) bytes down thanks to JayCe's improvements