Skip to content

Instantly share code, notes, and snippets.

@patricknelson
Last active May 15, 2021 22:08
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save patricknelson/2696f245f3b744b7c8a1a26921701191 to your computer and use it in GitHub Desktop.
Save patricknelson/2696f245f3b744b7c8a1a26921701191 to your computer and use it in GitHub Desktop.
Override the material and texture of default SteamVR HTC Vive controllers in Unity.
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 (pat@catchyour.com) 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);
}
}
@HawkenKing
Copy link

Add “using Steam.VR” at the top to use with newer versions of the Steam VR plugin

@Giantbean
Copy link

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?

@qmisslin
Copy link

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.

@patricknelson
Copy link
Author

Ok @qmisslin: I haven't tested this but is that the only modification necessary? If so, I can drop that in.

@qmisslin
Copy link

qmisslin commented Apr 1, 2020

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 !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment