-
-
Save patricknelson/2696f245f3b744b7c8a1a26921701191 to your computer and use it in GitHub Desktop.
using UnityEngine; | |
using Valve.VR; | |
/// <summary> | |
/// Override the material and texture of the HTC Vive controllers, with your own material after SteamVR has loaded and | |
/// applied the original material. This is useful to help preserve interactions in the model itself. | |
/// | |
/// NOTE: This is only compatible with the default HTC vive controllers (see UpdateControllerMaterial() below). | |
/// | |
/// Modified by Patrick Nelson / chunk_split ([email protected]) from original "OverrideControllerTexture" class | |
/// by Mr_FJ (from https://steamcommunity.com/app/358720/discussions/0/357287304420388604/) to allow override of full | |
/// material instead of just textures and also utilize the latest SteamVR_Events model. | |
/// | |
/// See also: https://forum.unity.com/threads/changing-the-htc-vive-controller-model-with-a-custom-hand-model.395107/ | |
/// </summary> | |
public class OverrideControllerMaterial : MonoBehaviour | |
{ | |
#region Public variables | |
[Header("Variables")] | |
public Material defaultMaterial; | |
public bool fixTiling = true; // Check this to correct the texture orientation. | |
#endregion | |
void OnEnable () | |
{ | |
//Subscribe to the event that is called by SteamVR_RenderModel, when the controller and it's associated material has been loaded completely. | |
SteamVR_Events.RenderModelLoaded.Listen(OnControllerLoaded); | |
} | |
void OnDisable () | |
{ | |
//Unsubscribe to the event if this object is disabled. | |
SteamVR_Events.RenderModelLoaded.Remove(OnControllerLoaded); | |
} | |
/// <summary> | |
/// Override the material of each of the parts, with your custom material. | |
/// </summary> | |
/// <param name="newMaterial">Override material</param> | |
/// <param name="modelTransform">Transform of the gameobject, which has the SteamVR_RenderModel component.</param> | |
/// <param name="modelTransform">Correct the texture orientation (if it looks offset incorrectly)</param> | |
public void UpdateControllerMaterial(Material newMaterial, Transform modelTransform, bool fixTiling = true) | |
{ | |
if (fixTiling) { | |
// Internally aligns the textures so that they wrap properly around our models the same as the original | |
// "onepointfive" texture. Prevents you from having to manually flip/rotate the texture yourself in PhotoShop. | |
newMaterial.mainTextureScale = new Vector2(1, -1); | |
} | |
modelTransform.Find("body").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("button").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("led").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("lgrip").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("rgrip").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("scroll_wheel").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("sys_button").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("trackpad").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("trackpad_scroll_cut").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("trackpad_touch").GetComponent<MeshRenderer>().material = newMaterial; | |
modelTransform.Find("trigger").GetComponent<MeshRenderer>().material = newMaterial; | |
} | |
/// <summary> | |
/// Call this method, when the "RenderModelLoaded" event is triggered. | |
/// </summary> | |
/// <param name="controllerRenderModel"></param> | |
/// <param name="success"></param> | |
void OnControllerLoaded(SteamVR_RenderModel controllerRenderModel, bool success) | |
{ | |
UpdateControllerMaterial(defaultMaterial, controllerRenderModel.gameObject.transform, fixTiling); | |
} | |
} |
Now you have to add "using Valve.VR" instead of "using Steam.VR" at the top of the page to use it with new versions of the Steam VR plugin.
Ok @qmisslin: I haven't tested this but is that the only modification necessary? If so, I can drop that in.
Yes @patriknelson, that's it, juste add "using Valve.VR" at the top of the script. I was able to make it work without any problem with Universal Render Pipeline in Unity version 2019.3.2.
The only other detail I noticed is that you have to do a mirror (flip up with the bottom) of an image when you want to use it as an albedo texture for the controller. I made this modification for example on a skin downloaded from this reddit : https://www.reddit.com/r/Vive/wiki/skins#wiki_how_to_install_skins
Thank you for your work !
How would you write this to update a different material. Not the hand but an image of the controller in use with player instructions. A HUD or controller mapping screen that shows a Vive if the vive is connected or an Index (Knuckles) if that is the controller in use?