Last active
May 15, 2021 22:08
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
} |
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
Ok @qmisslin: I haven't tested this but is that the only modification necessary? If so, I can drop that in.