/// <summary> /// Serializes a Material into a SL_Material. /// </summary> /// <param name="mat">The material to serialize.</param> /// <returns>Serialized SL_Material.</returns> public static SL_Material ParseMaterial(Material mat) { var holder = new SL_Material() { Name = CustomItemVisuals.GetSafeMaterialName(mat.name), ShaderName = mat.shader.name, Properties = CustomTextures.GetProperties(mat).ToArray(), Keywords = mat.shaderKeywords, }; var list = new List <TextureConfig>(); foreach (var texName in mat.GetTexturePropertyNames()) { if (mat.GetTexture(texName) is Texture2D tex) { list.Add(new TextureConfig() { TextureName = texName, MipMapBias = tex.mipMapBias, UseMipMap = (tex.mipmapCount > 0), }); } } holder.TextureConfigs = list.ToArray(); return(holder); }
/// <summary> /// Apply the SL_ItemVisual prefab to the Item. /// </summary> /// <param name="item">The Item to set to.</param> public void ApplyToItem(Item item) { if (CustomItemVisuals.GetOrigItemVisuals(item, Type) is Transform origPrefab) { bool setPrefab = false; // Check for AssetBundle Prefabs first if (!string.IsNullOrEmpty(Prefab_SLPack) && SL.GetSLPack(Prefab_SLPack) is SLPack pack) { if (pack.AssetBundles.ContainsKey(Prefab_AssetBundle)) { var newVisuals = pack.AssetBundles[Prefab_AssetBundle].LoadAsset <GameObject>(Prefab_Name); origPrefab = SetCustomVisualPrefab(item, this.Type, newVisuals.transform, origPrefab).transform; SL.Log("Loaded custom visual prefab: " + newVisuals.name); setPrefab = true; } } // Not using AssetBundle, check for ResourcesPrefabPath. else if (!string.IsNullOrEmpty(ResourcesPrefabPath)) { // Only set this if the user has defined a different value than what exists on the item. bool set = false; switch (Type) { case VisualPrefabType.VisualPrefab: set = item.VisualPrefabPath == ResourcesPrefabPath; break; case VisualPrefabType.SpecialVisualPrefabDefault: set = item.SpecialVisualPrefabDefaultPath == ResourcesPrefabPath; break; case VisualPrefabType.SpecialVisualPrefabFemale: set = item.SpecialVisualPrefabFemalePath == ResourcesPrefabPath; break; } if (!set) { // Get the original visual prefab to clone from var orig = ResourcesPrefabManager.Instance.GetItemVisualPrefab(ResourcesPrefabPath); if (!orig) { SL.Log("SL_ItemVisual: Could not find an Item Visual at the Resources path: " + ResourcesPrefabPath); } else { CustomItemVisuals.CloneAndSetVisuals(item, orig.gameObject, Type); switch (Type) { case VisualPrefabType.VisualPrefab: At.SetField(item, "m_visualPrefabPath", ResourcesPrefabPath); break; case VisualPrefabType.SpecialVisualPrefabDefault: At.SetField(item, "m_specialVisualPrefabDefaultPath", ResourcesPrefabPath); break; case VisualPrefabType.SpecialVisualPrefabFemale: At.SetField(item, "m_specialVisualPrefabFemalePath", ResourcesPrefabPath); break; } setPrefab = true; } } } // If we didn't change the Visual Prefab in any way, clone the original to avoid conflicts. if (!setPrefab) { origPrefab = CustomItemVisuals.CloneVisualPrefab(item, Type).transform; } // Get the actual visuals (for weapons and a lot of items, this is not the base prefab). Transform actualVisuals = origPrefab.transform; if (this.Type == VisualPrefabType.VisualPrefab) { if (origPrefab.childCount > 0) { foreach (Transform child in origPrefab) { if (child.gameObject.activeSelf && child.GetComponent <BoxCollider>() && child.GetComponent <MeshRenderer>()) { actualVisuals = child; break; } } } } if (actualVisuals) { var visualComp = origPrefab.GetComponent <ItemVisual>(); ApplyItemVisualSettings(visualComp, actualVisuals); } } }
internal GameObject SetCustomVisualPrefab(Item item, VisualPrefabType type, Transform newVisuals, Transform oldVisuals) { SL.Log($"Setting the {type} for {item.Name}"); var basePrefab = GameObject.Instantiate(oldVisuals.gameObject); GameObject.DontDestroyOnLoad(basePrefab); basePrefab.SetActive(false); var visualModel = UnityEngine.Object.Instantiate(newVisuals.gameObject); UnityEngine.Object.DontDestroyOnLoad(visualModel.gameObject); if (type == VisualPrefabType.VisualPrefab) { // At the moment, the only thing we replace on ItemVisuals is the 3d model, everything else is a clone. foreach (Transform child in basePrefab.transform) { // the real 3d model will always have boxcollider and meshrenderer. this is the object we want to replace. if (child.GetComponent <BoxCollider>() && child.GetComponent <MeshRenderer>()) { child.gameObject.SetActive(false); visualModel.transform.position = child.position; visualModel.transform.rotation = child.rotation; visualModel.transform.parent = child.parent; break; } } basePrefab.name = visualModel.name; CustomItemVisuals.SetVisualPrefabLink(item, basePrefab, type); SL.Log("Setup visual prefab link: " + item.Name + " -> " + basePrefab.name); return(basePrefab); } else { if (!visualModel.GetComponent <ItemVisual>() && basePrefab.GetComponent <ItemVisual>() is ItemVisual itemVisual) { if (itemVisual is ArmorVisuals) { var armorV = visualModel.AddComponent <ArmorVisuals>(); armorV.ArmorExtras = new ArmorVisualExtra[0]; } else { visualModel.AddComponent <ItemVisual>(); } } visualModel.transform.position = basePrefab.transform.position; visualModel.transform.rotation = basePrefab.transform.rotation; visualModel.gameObject.SetActive(false); // we no longer need the clone for these visuals. we should clean it up. UnityEngine.Object.DestroyImmediate(basePrefab.gameObject); CustomItemVisuals.SetVisualPrefabLink(item, visualModel, type); SL.Log("Setup visual prefab link: " + item.Name + " -> " + visualModel.name); return(visualModel); } }