mirror of
https://github.com/muskit/H3VR-TNH-Quality-of-Life-Improvements.git
synced 2026-06-02 20:24:26 -07:00
Initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 909a2b7b1c734764287b9acd96752fc7
|
||||
folderAsset: yes
|
||||
timeCreated: 1640643655
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,181 @@
|
||||
// Adapted from https://gist.github.com/kalineh/ad5135946f2009c36f755eea0a880998
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
#if H3VR_IMPORTED
|
||||
using FistVR;
|
||||
#endif
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class EnumPickerWindow : EditorWindow
|
||||
{
|
||||
private static GUIStyle _regularStyle;
|
||||
private static GUIStyle _selectedStyle;
|
||||
|
||||
private string _enumName;
|
||||
private string _filter;
|
||||
|
||||
private Action<string> _onSelectCallback;
|
||||
|
||||
private EditorWindow _parent;
|
||||
private Vector2 _scroll;
|
||||
private List<string> _valuesFiltered;
|
||||
private List<string> _valuesRaw;
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
GUILayout.Label(string.Format("Enum Type: {0}", _enumName));
|
||||
|
||||
GUI.SetNextControlName("filter");
|
||||
var filterUpdate = GUILayout.TextField(_filter);
|
||||
if (filterUpdate != _filter)
|
||||
FilterValues(filterUpdate);
|
||||
|
||||
// always focused
|
||||
GUI.FocusControl("filter");
|
||||
|
||||
_scroll = GUILayout.BeginScrollView(_scroll);
|
||||
|
||||
for (var i = 0; i < _valuesFiltered.Count; ++i)
|
||||
{
|
||||
var value = _valuesFiltered[i];
|
||||
var style = i == 0 ? _selectedStyle : _regularStyle;
|
||||
var rect = GUILayoutUtility.GetRect(new GUIContent(value), style);
|
||||
|
||||
var clicked = GUI.Button(rect, value);
|
||||
if (clicked)
|
||||
{
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
_onSelectCallback(value);
|
||||
Close();
|
||||
_parent.Repaint();
|
||||
_parent.Focus();
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Return)
|
||||
{
|
||||
if (_valuesFiltered.Count > 0)
|
||||
_onSelectCallback(_valuesFiltered[0]);
|
||||
|
||||
Close();
|
||||
_parent.Repaint();
|
||||
_parent.Focus();
|
||||
}
|
||||
|
||||
if (Event.current.type == EventType.KeyDown && Event.current.keyCode == KeyCode.Escape)
|
||||
{
|
||||
Close();
|
||||
_parent.Repaint();
|
||||
_parent.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnLostFocus()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
public void ShowCustom(string enumName, List<string> values, Rect rect, Action<string> onSelect)
|
||||
{
|
||||
_regularStyle = new GUIStyle(EditorStyles.label);
|
||||
_regularStyle.active = _regularStyle.normal;
|
||||
|
||||
_selectedStyle = new GUIStyle(EditorStyles.label);
|
||||
_selectedStyle.normal = _selectedStyle.focused;
|
||||
_selectedStyle.active = _selectedStyle.focused;
|
||||
|
||||
_enumName = enumName;
|
||||
_valuesRaw = new List<string>(values);
|
||||
_valuesFiltered = new List<string>(values);
|
||||
_filter = "";
|
||||
_onSelectCallback = onSelect;
|
||||
|
||||
_parent = focusedWindow;
|
||||
|
||||
var screenRect = rect;
|
||||
var screenSize = new Vector2(400, 400);
|
||||
|
||||
screenRect.position = GUIUtility.GUIToScreenPoint(screenRect.position);
|
||||
|
||||
ShowAsDropDown(screenRect, screenSize);
|
||||
Focus();
|
||||
|
||||
GUI.FocusControl("filter");
|
||||
}
|
||||
|
||||
private void FilterValues(string filterUpdate)
|
||||
{
|
||||
_filter = filterUpdate;
|
||||
var filterLower = _filter.ToLower();
|
||||
_valuesFiltered.Clear();
|
||||
foreach (var value in from value in _valuesRaw
|
||||
let lower = value.ToLower()
|
||||
where lower.Contains(filterLower)
|
||||
select value)
|
||||
_valuesFiltered.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
public class EnumPicker : PropertyDrawer
|
||||
{
|
||||
private EnumPickerWindow _window;
|
||||
|
||||
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
|
||||
{
|
||||
Array valuesRaw = null;
|
||||
Type enumType = fieldInfo.FieldType;
|
||||
if (enumType.IsArray) enumType = enumType.GetElementType(); //this turns the enum array into just the enum to prevent issues with arrays of enums
|
||||
|
||||
valuesRaw = Enum.GetValues(enumType);
|
||||
if (valuesRaw.Length <= 0)
|
||||
return;
|
||||
var valuesStr = new List<string>();
|
||||
for (var i = 0; i < valuesRaw.Length; ++i)
|
||||
{
|
||||
object raw = valuesRaw.GetValue(i);
|
||||
var str = raw.ToString();
|
||||
valuesStr.Add(str);
|
||||
}
|
||||
string enumName = enumType.Name;
|
||||
string currentName = Enum.GetName(enumType, property.intValue);
|
||||
EditorGUI.PrefixLabel(position, label);
|
||||
GUI.SetNextControlName(property.propertyPath);
|
||||
var fieldRect = new Rect(position.x + EditorGUIUtility.labelWidth, position.y,
|
||||
position.width - EditorGUIUtility.labelWidth, position.height);
|
||||
if (GUI.Button(fieldRect, currentName, EditorStyles.popup))
|
||||
{
|
||||
_window = EditorWindow.GetWindow<EnumPickerWindow>();
|
||||
Action<string> callback = str =>
|
||||
{
|
||||
var index = (int) Convert.ChangeType(Enum.Parse(enumType, str), enumType);
|
||||
property.serializedObject.Update();
|
||||
property.intValue = index;
|
||||
property.serializedObject.ApplyModifiedProperties();
|
||||
};
|
||||
_window.ShowCustom(enumName, valuesStr, fieldRect, callback);
|
||||
_window.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if H3VR_IMPORTED
|
||||
[CustomPropertyDrawer(typeof(FireArmMagazineType))]
|
||||
[CustomPropertyDrawer(typeof(FireArmClipType))]
|
||||
[CustomPropertyDrawer(typeof(FireArmRoundClass))]
|
||||
[CustomPropertyDrawer(typeof(ItemSpawnerObjectDefinition.ItemSpawnerCategory))]
|
||||
[CustomPropertyDrawer(typeof(ItemSpawnerID.EItemCategory))]
|
||||
[CustomPropertyDrawer(typeof(ItemSpawnerID.ESubCategory))]
|
||||
[CustomPropertyDrawer(typeof(FireArmRoundType))]
|
||||
[CustomPropertyDrawer(typeof(SosigEnemyID))]
|
||||
public class EnumDrawers : EnumPicker
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27e4b73d795c232439cf3aee1d6ed3ba
|
||||
timeCreated: 1628222780
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,70 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
[CustomEditor(typeof(IconCamera))]
|
||||
[CanEditMultipleObjects]
|
||||
public class IconCameraEditor : Editor {
|
||||
|
||||
|
||||
Texture2D previewTexture = null;
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
serializedObject.Update();
|
||||
|
||||
var property = serializedObject.GetIterator();
|
||||
if (!property.NextVisible(true)) return;
|
||||
do EditorGUILayout.PropertyField(property, true);
|
||||
while (property.NextVisible(false));
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
IconCamera iconCamera = serializedObject.targetObject as IconCamera;
|
||||
iconCamera.thisCamera.depthTextureMode = iconCamera.CameraDepthMode;
|
||||
|
||||
if (previewTexture != null)
|
||||
{
|
||||
GUILayout.BeginVertical("Box");
|
||||
|
||||
GUIStyle style = new GUIStyle();
|
||||
style.alignment = TextAnchor.UpperCenter;
|
||||
style.fixedWidth = Screen.width - 50;
|
||||
style.fixedHeight = Screen.width - 50;
|
||||
GUILayout.Label(previewTexture, style);
|
||||
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (GUILayout.Button("Update Preview"))
|
||||
{
|
||||
if (iconCamera.renderTexture != null)
|
||||
{
|
||||
RenderTexture temp = RenderTexture.active;
|
||||
RenderTexture.active = iconCamera.renderTexture;
|
||||
Texture2D texture = new Texture2D(iconCamera.renderTexture.width, iconCamera.renderTexture.height);
|
||||
texture.ReadPixels(new Rect(0, 0, iconCamera.renderTexture.width, iconCamera.renderTexture.height), 0, 0);
|
||||
texture.Apply();
|
||||
RenderTexture.active = temp;
|
||||
|
||||
texture = iconCamera.FlipTexture(texture);
|
||||
|
||||
if (iconCamera.background != null)
|
||||
{
|
||||
texture = iconCamera.AddBackground(texture, iconCamera.background);
|
||||
}
|
||||
|
||||
previewTexture = texture;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (GUILayout.Button("Take Picture"))
|
||||
{
|
||||
Selection.activeGameObject.GetComponent<IconCamera>().Capture();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4607bcf07fdb67428d41b6bd2f9b2fb
|
||||
timeCreated: 1640645560
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class PrefabLoader : EditorWindow
|
||||
{
|
||||
private AssetBundle _bundle;
|
||||
private string[] _assets = new string[0];
|
||||
private int _selectedAsset = 0;
|
||||
|
||||
[MenuItem("MeatKit/Asset Bundle/Prefab Loader")]
|
||||
private static void Init()
|
||||
{
|
||||
GetWindow<PrefabLoader>().Show();
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (GUILayout.Button("Select Asset Bundle"))
|
||||
{
|
||||
// If there's already a bundle loaded, unload it.
|
||||
if (_bundle) _bundle.Unload(false);
|
||||
|
||||
// Ask for the new bundle, load it, and get its assets
|
||||
string assetBundlePath = EditorUtility.OpenFilePanel("Select Asset Bundle", string.Empty, string.Empty);
|
||||
_bundle = AssetBundle.LoadFromFile(assetBundlePath);
|
||||
_assets = _bundle.GetAllAssetNames();
|
||||
_selectedAsset = 0;
|
||||
}
|
||||
|
||||
if (_assets.Length > 0)
|
||||
{
|
||||
_selectedAsset = EditorGUILayout.Popup(_selectedAsset, _assets);
|
||||
if (GUILayout.Button("Spawn")) Instantiate(_bundle.LoadAsset(_assets[_selectedAsset]));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4d4b78186f45453aa4abc82dc1364363
|
||||
timeCreated: 1637988640
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf9dd0c01456ee745baa552ed8b66182
|
||||
folderAsset: yes
|
||||
timeCreated: 1641758894
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2cc9af527c35194481307c551f26f04
|
||||
folderAsset: yes
|
||||
timeCreated: 1641758894
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,230 @@
|
||||
#if H3VR_IMPORTED
|
||||
using FistVR;
|
||||
#endif
|
||||
using MeatKit;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
public class GunRipperWindow : EditorWindow
|
||||
{
|
||||
|
||||
public GameObject SelectedGameObject;
|
||||
public string ExportPath = "Meatkit/Tools/GunRipper/Export";
|
||||
|
||||
|
||||
[MenuItem("Tools/Gun Ripper")]
|
||||
public static void Open()
|
||||
{
|
||||
GetWindow<GunRipperWindow>("Gun Ripper").Show();
|
||||
}
|
||||
|
||||
#if H3VR_IMPORTED
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUILayout.LabelField("Selected GameObject", EditorStyles.boldLabel);
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
SelectedGameObject = EditorGUILayout.ObjectField(SelectedGameObject, typeof(GameObject), true) as GameObject;
|
||||
|
||||
if (string.IsNullOrEmpty(ExportPath)) ExportPath = "Meatkit/Tools/GunRipper/Export";
|
||||
ExportPath = EditorGUILayout.TextField(ExportPath);
|
||||
|
||||
if (!SelectedGameObject)
|
||||
{
|
||||
GUILayout.Label("Please select a game object");
|
||||
return;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
FVRFireArm firearmComp = SelectedGameObject.GetComponent<FVRFireArm>();
|
||||
FVRFireArmMagazine magazineComp = SelectedGameObject.GetComponent<FVRFireArmMagazine>();
|
||||
FVRFireArmAttachment attachment = SelectedGameObject.GetComponent<FVRFireArmAttachment>();
|
||||
|
||||
if (firearmComp != null && firearmComp.AudioClipSet != null && GUILayout.Button("Rip Firearm Audio"))
|
||||
{
|
||||
Debug.Log("Ripping Audio!");
|
||||
RipAudio(firearmComp.AudioClipSet, "AudioSet");
|
||||
}
|
||||
|
||||
if (magazineComp != null && magazineComp.Profile != null && GUILayout.Button("Rip Magazine Audio"))
|
||||
{
|
||||
Debug.Log("Ripping Audio!");
|
||||
RipAudio(magazineComp.Profile, "AudioSet");
|
||||
}
|
||||
|
||||
if(attachment != null && (attachment.AudClipAttach != null || attachment.AudClipDettach != null) && GUILayout.Button("Rip Attachment Audio"))
|
||||
{
|
||||
if(attachment.AudClipAttach != null)
|
||||
{
|
||||
Debug.Log("Ripping Audio!");
|
||||
RipAudio(attachment.AudClipAttach, "AudioAttach");
|
||||
}
|
||||
|
||||
if (attachment.AudClipDettach != null)
|
||||
{
|
||||
Debug.Log("Ripping Audio!");
|
||||
RipAudio(attachment.AudClipDettach, "AudioDettach");
|
||||
}
|
||||
}
|
||||
|
||||
if (firearmComp != null && (firearmComp.RecoilProfile != null || firearmComp.RecoilProfileStocked != null) && GUILayout.Button("Rip Firearm Recoil"))
|
||||
{
|
||||
if(firearmComp.RecoilProfile != null)
|
||||
{
|
||||
Debug.Log("Ripping Stockless Recoil!");
|
||||
RipRecoil(firearmComp.RecoilProfile, "Recoil");
|
||||
}
|
||||
|
||||
if(firearmComp.RecoilProfileStocked != null)
|
||||
{
|
||||
Debug.Log("Ripping Stocked Recoil!");
|
||||
RipRecoil(firearmComp.RecoilProfileStocked, "RecoilStocked");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void RipAudio(AudioEvent audioEvent, string suffix)
|
||||
{
|
||||
string exportFolderPath = "Assets/" + ExportPath.Trim('/');
|
||||
string destinationFolderName = SelectedGameObject.name + "_Rip";
|
||||
string destinationFolderPath = exportFolderPath + "/" + destinationFolderName;
|
||||
|
||||
if (!AssetDatabase.IsValidFolder(destinationFolderPath))
|
||||
{
|
||||
AssetDatabase.CreateFolder(exportFolderPath, destinationFolderName);
|
||||
}
|
||||
|
||||
RipAudioClips(audioEvent, destinationFolderPath);
|
||||
}
|
||||
|
||||
|
||||
private void RipAudio(FVRFirearmAudioSet audioSet, string suffix)
|
||||
{
|
||||
string exportFolderPath = "Assets/" + ExportPath.Trim('/');
|
||||
string destinationFolderName = SelectedGameObject.name + "_Rip";
|
||||
string destinationFolderPath = exportFolderPath + "/" + destinationFolderName;
|
||||
string audioPath = destinationFolderPath + "/" + SelectedGameObject.name + "_" + suffix + ".asset";
|
||||
|
||||
if (!AssetDatabase.IsValidFolder(destinationFolderPath))
|
||||
{
|
||||
AssetDatabase.CreateFolder(exportFolderPath, destinationFolderName);
|
||||
}
|
||||
|
||||
FVRFirearmAudioSet audioCopy = CreateInstance<FVRFirearmAudioSet>();
|
||||
CopyFields(audioCopy, audioSet);
|
||||
RipAudioClips(audioCopy, destinationFolderPath);
|
||||
|
||||
AssetDatabase.DeleteAsset(audioPath);
|
||||
AssetDatabase.CreateAsset(audioCopy, audioPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
private void RipRecoil(FVRFireArmRecoilProfile recoil, string suffix)
|
||||
{
|
||||
string exportFolderPath = "Assets/" + ExportPath.Trim('/');
|
||||
string destinationFolderName = SelectedGameObject.name + "_Rip";
|
||||
string destinationFolderPath = exportFolderPath + "/" + destinationFolderName;
|
||||
string recoilPath = destinationFolderPath + "/" + SelectedGameObject.name + "_" + suffix + ".asset";
|
||||
|
||||
if (!AssetDatabase.IsValidFolder(destinationFolderPath))
|
||||
{
|
||||
AssetDatabase.CreateFolder(exportFolderPath, destinationFolderName);
|
||||
}
|
||||
|
||||
FVRFireArmRecoilProfile recoilCopy = CreateInstance<FVRFireArmRecoilProfile>();
|
||||
CopyFields(recoilCopy, recoil);
|
||||
|
||||
AssetDatabase.DeleteAsset(recoilPath);
|
||||
AssetDatabase.CreateAsset(recoilCopy, recoilPath);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void CopyFields(UnityEngine.Object copyAsset, UnityEngine.Object origAsset, bool allowMismatch = false)
|
||||
{
|
||||
Type type = origAsset.GetType();
|
||||
if (!allowMismatch && type != copyAsset.GetType())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default;
|
||||
PropertyInfo[] pinfos = type.GetProperties(flags);
|
||||
foreach (var pinfo in pinfos)
|
||||
{
|
||||
|
||||
if (pinfo.CanWrite)
|
||||
{
|
||||
try
|
||||
{
|
||||
pinfo.SetValue(copyAsset, pinfo.GetValue(origAsset, null), null);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
FieldInfo[] finfos = type.GetFields(flags);
|
||||
foreach (var finfo in finfos)
|
||||
{
|
||||
finfo.SetValue(copyAsset, finfo.GetValue(origAsset));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void RipAudioClips(System.Object asset, string exportPath)
|
||||
{
|
||||
Type type = asset.GetType();
|
||||
BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Default;
|
||||
|
||||
FieldInfo[] finfos = type.GetFields(flags);
|
||||
foreach (var finfo in finfos)
|
||||
{
|
||||
Debug.Log("Field: " + finfo.Name + ", Type: " + finfo.FieldType);
|
||||
|
||||
if(finfo.GetValue(asset) is List<AudioClip>)
|
||||
{
|
||||
Debug.Log("List!");
|
||||
|
||||
List<AudioClip> audioList = finfo.GetValue(asset) as List<AudioClip>;
|
||||
|
||||
for (int i = 0; i < audioList.Count; i++)
|
||||
{
|
||||
AudioClip clip = audioList[i];
|
||||
if(clip != null)
|
||||
{
|
||||
Debug.Log("Audio Clip! " + clip.name);
|
||||
audioList[i] = SavWav.Save(exportPath, clip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(finfo.FieldType == typeof(AudioEvent))
|
||||
{
|
||||
Debug.Log("Audio Event!");
|
||||
RipAudioClips(finfo.GetValue(asset), exportPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 80429e2d9786fda44b01ab04cadd4b75
|
||||
timeCreated: 1641758895
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,190 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Allows for saving audio clips to wav file.
|
||||
/// Code found here: https://gist.github.com/darktable/2317063
|
||||
/// </summary>
|
||||
public static class SavWav
|
||||
{
|
||||
|
||||
const int HEADER_SIZE = 44;
|
||||
struct ClipData
|
||||
{
|
||||
|
||||
public int samples;
|
||||
public int channels;
|
||||
public float[] samplesData;
|
||||
|
||||
}
|
||||
|
||||
public static AudioClip Save(string path, AudioClip clip)
|
||||
{
|
||||
var assetPath = path.Trim('/') + "/" + clip.name + ".wav";
|
||||
var filepath = Directory.GetParent(Application.dataPath) + "/" + path.Trim('/') + "/" + clip.name + ".wav";
|
||||
|
||||
Debug.Log(filepath);
|
||||
Debug.Log(assetPath);
|
||||
|
||||
AssetDatabase.DeleteAsset(assetPath);
|
||||
|
||||
// Make sure directory exists if user is saving to sub dir.
|
||||
ClipData clipdata = new ClipData();
|
||||
clipdata.samples = clip.samples;
|
||||
clipdata.channels = clip.channels;
|
||||
float[] dataFloat = new float[clip.samples * clip.channels];
|
||||
clip.GetData(dataFloat, 0);
|
||||
clipdata.samplesData = dataFloat;
|
||||
|
||||
using (var fileStream = CreateEmpty(filepath))
|
||||
{
|
||||
MemoryStream memstrm = new MemoryStream();
|
||||
ConvertAndWrite(memstrm, clipdata);
|
||||
memstrm.WriteTo(fileStream);
|
||||
WriteHeader(fileStream, clip);
|
||||
}
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
return (AudioClip)AssetDatabase.LoadAssetAtPath(assetPath, typeof(AudioClip));
|
||||
}
|
||||
|
||||
public static AudioClip TrimSilence(AudioClip clip, float min)
|
||||
{
|
||||
var samples = new float[clip.samples];
|
||||
|
||||
clip.GetData(samples, 0);
|
||||
|
||||
return TrimSilence(new List<float>(samples), min, clip.channels, clip.frequency);
|
||||
}
|
||||
|
||||
public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz)
|
||||
{
|
||||
return TrimSilence(samples, min, channels, hz, false, false);
|
||||
}
|
||||
|
||||
public static AudioClip TrimSilence(List<float> samples, float min, int channels, int hz, bool _3D, bool stream)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < samples.Count; i++)
|
||||
{
|
||||
if (Mathf.Abs(samples[i]) > min)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
samples.RemoveRange(0, i);
|
||||
|
||||
for (i = samples.Count - 1; i > 0; i--)
|
||||
{
|
||||
if (Mathf.Abs(samples[i]) > min)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
samples.RemoveRange(i, samples.Count - i);
|
||||
|
||||
var clip = AudioClip.Create("TempClip", samples.Count, channels, hz, _3D, stream);
|
||||
|
||||
clip.SetData(samples.ToArray(), 0);
|
||||
|
||||
return clip;
|
||||
}
|
||||
|
||||
static FileStream CreateEmpty(string filepath)
|
||||
{
|
||||
var fileStream = new FileStream(filepath, FileMode.Create);
|
||||
byte emptyByte = new byte();
|
||||
|
||||
for (int i = 0; i < HEADER_SIZE; i++) //preparing the header
|
||||
{
|
||||
fileStream.WriteByte(emptyByte);
|
||||
}
|
||||
|
||||
return fileStream;
|
||||
}
|
||||
|
||||
static void ConvertAndWrite(MemoryStream memStream, ClipData clipData)
|
||||
{
|
||||
float[] samples = new float[clipData.samples * clipData.channels];
|
||||
|
||||
samples = clipData.samplesData;
|
||||
|
||||
Int16[] intData = new Int16[samples.Length];
|
||||
|
||||
Byte[] bytesData = new Byte[samples.Length * 2];
|
||||
|
||||
const float rescaleFactor = 32767; //to convert float to Int16
|
||||
|
||||
for (int i = 0; i < samples.Length; i++)
|
||||
{
|
||||
intData[i] = (short)(samples[i] * rescaleFactor);
|
||||
//Debug.Log (samples [i]);
|
||||
}
|
||||
Buffer.BlockCopy(intData, 0, bytesData, 0, bytesData.Length);
|
||||
memStream.Write(bytesData, 0, bytesData.Length);
|
||||
}
|
||||
|
||||
static void WriteHeader(FileStream fileStream, AudioClip clip)
|
||||
{
|
||||
|
||||
var hz = clip.frequency;
|
||||
var channels = clip.channels;
|
||||
var samples = clip.samples;
|
||||
|
||||
fileStream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
Byte[] riff = System.Text.Encoding.UTF8.GetBytes("RIFF");
|
||||
fileStream.Write(riff, 0, 4);
|
||||
|
||||
Byte[] chunkSize = BitConverter.GetBytes(fileStream.Length - 8);
|
||||
fileStream.Write(chunkSize, 0, 4);
|
||||
|
||||
Byte[] wave = System.Text.Encoding.UTF8.GetBytes("WAVE");
|
||||
fileStream.Write(wave, 0, 4);
|
||||
|
||||
Byte[] fmt = System.Text.Encoding.UTF8.GetBytes("fmt ");
|
||||
fileStream.Write(fmt, 0, 4);
|
||||
|
||||
Byte[] subChunk1 = BitConverter.GetBytes(16);
|
||||
fileStream.Write(subChunk1, 0, 4);
|
||||
|
||||
UInt16 two = 2;
|
||||
UInt16 one = 1;
|
||||
|
||||
Byte[] audioFormat = BitConverter.GetBytes(one);
|
||||
fileStream.Write(audioFormat, 0, 2);
|
||||
|
||||
Byte[] numChannels = BitConverter.GetBytes(channels);
|
||||
fileStream.Write(numChannels, 0, 2);
|
||||
|
||||
Byte[] sampleRate = BitConverter.GetBytes(hz);
|
||||
fileStream.Write(sampleRate, 0, 4);
|
||||
|
||||
Byte[] byteRate = BitConverter.GetBytes(hz * channels * 2); // sampleRate * bytesPerSample*number of channels, here 44100*2*2
|
||||
fileStream.Write(byteRate, 0, 4);
|
||||
|
||||
UInt16 blockAlign = (ushort)(channels * 2);
|
||||
fileStream.Write(BitConverter.GetBytes(blockAlign), 0, 2);
|
||||
|
||||
UInt16 bps = 16;
|
||||
Byte[] bitsPerSample = BitConverter.GetBytes(bps);
|
||||
fileStream.Write(bitsPerSample, 0, 2);
|
||||
|
||||
Byte[] datastring = System.Text.Encoding.UTF8.GetBytes("data");
|
||||
fileStream.Write(datastring, 0, 4);
|
||||
|
||||
Byte[] subChunk2 = BitConverter.GetBytes(samples * channels * 2);
|
||||
fileStream.Write(subChunk2, 0, 4);
|
||||
|
||||
// fileStream.Close();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16f4f028d3b75704fbc40b3122b0c568
|
||||
timeCreated: 1641758895
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 67b0d6a5c1b85824bbcb13aefd6b9879
|
||||
folderAsset: yes
|
||||
timeCreated: 1640644671
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7390fd4499410bb4da9b31d5f5773db7
|
||||
folderAsset: yes
|
||||
timeCreated: 1640720511
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.5 KiB |
@@ -0,0 +1,76 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95d557f2518a98942b8b75fb4c572df2
|
||||
timeCreated: 1640801294
|
||||
licenseType: Free
|
||||
TextureImporter:
|
||||
fileIDToRecycleName: {}
|
||||
serializedVersion: 4
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 1
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
filterMode: -1
|
||||
aniso: -1
|
||||
mipBias: -1
|
||||
wrapMode: 1
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spritePixelsToUnits: 100
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 8
|
||||
textureShape: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
platformSettings:
|
||||
- buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
- buildTarget: Standalone
|
||||
maxTextureSize: 2048
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
spritePackingTag:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2c6465d11669fe48a03a5e0a4858961
|
||||
folderAsset: yes
|
||||
timeCreated: 1640644677
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,86 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!21 &2100000
|
||||
Material:
|
||||
serializedVersion: 6
|
||||
m_ObjectHideFlags: 0
|
||||
m_PrefabParentObject: {fileID: 0}
|
||||
m_PrefabInternal: {fileID: 0}
|
||||
m_Name: BlackWhiteEffect
|
||||
m_Shader: {fileID: 4800000, guid: ca1ad64f6fe2663418174309f73c9ec5, type: 3}
|
||||
m_ShaderKeywords:
|
||||
m_LightmapFlags: 4
|
||||
m_EnableInstancingVariants: 0
|
||||
m_DoubleSidedGI: 0
|
||||
m_CustomRenderQueue: -1
|
||||
stringTagMap: {}
|
||||
disabledShaderPasses: []
|
||||
m_SavedProperties:
|
||||
serializedVersion: 3
|
||||
m_TexEnvs:
|
||||
- _BumpMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailAlbedoMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailMask:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _DetailNormalMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _EmissionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MainTex:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _MetallicGlossMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _OcclusionMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
- _ParallaxMap:
|
||||
m_Texture: {fileID: 0}
|
||||
m_Scale: {x: 1, y: 1}
|
||||
m_Offset: {x: 0, y: 0}
|
||||
m_Floats:
|
||||
- _BumpScale: 1
|
||||
- _ClipDistance: 10
|
||||
- _ColorBands: 2
|
||||
- _Cutoff: 0.5
|
||||
- _DetailNormalMapScale: 1
|
||||
- _DstBlend: 0
|
||||
- _GlossMapScale: 1
|
||||
- _Glossiness: 0.5
|
||||
- _GlossyReflections: 1
|
||||
- _LightToNormalFactor: 0.366
|
||||
- _MaxBrightness: 9.34
|
||||
- _Metallic: 0
|
||||
- _MinBrightness: -1.57
|
||||
- _Mode: 0
|
||||
- _NormalCutoff: 0.548
|
||||
- _NormalMultiplier: 11.1
|
||||
- _NormalPower: 4.08
|
||||
- _OcclusionStrength: 1
|
||||
- _Parallax: 0.02
|
||||
- _SmoothnessTextureChannel: 0
|
||||
- _SpecularHighlights: 1
|
||||
- _SrcBlend: 1
|
||||
- _UVSec: 0
|
||||
- _ZWrite: 1
|
||||
m_Colors:
|
||||
- _BrightColor: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _Color: {r: 1, g: 1, b: 1, a: 1}
|
||||
- _DarkColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
- _EmissionColor: {r: 0, g: 0, b: 0, a: 1}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95bd255dc1046994d88a5333bd4df105
|
||||
timeCreated: 1640641178
|
||||
licenseType: Free
|
||||
NativeFormatImporter:
|
||||
mainObjectFileID: 2100000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3d764943143e36d439f718a1ba9ad47c
|
||||
folderAsset: yes
|
||||
timeCreated: 1640644682
|
||||
licenseType: Free
|
||||
DefaultImporter:
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,83 @@
|
||||
Shader "Image/BlackWhiteEffect"
|
||||
{
|
||||
Properties
|
||||
{
|
||||
_MainTex ("Texture", 2D) = "white" {}
|
||||
_MinBrightness("Min Brightness", Float) = 0
|
||||
_MaxBrightness("Max Brightness", Float) = 1
|
||||
_ColorBands("Color Bands", Float) = 1000
|
||||
_DarkColor("Dark Color", Color) = (0, 0, 0, 1)
|
||||
_BrightColor("Bright Color", Color) = (1, 1, 1, 1)
|
||||
_LightToNormalFactor("Light To Normal Factor", Range(0, 1)) = 1
|
||||
}
|
||||
SubShader
|
||||
{
|
||||
// No culling or depth
|
||||
Cull Off ZWrite Off ZTest Always
|
||||
|
||||
Pass
|
||||
{
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata
|
||||
{
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f
|
||||
{
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
float remap(float value, float from1, float to1, float from2, float to2) {
|
||||
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
|
||||
}
|
||||
|
||||
|
||||
v2f vert (appdata v)
|
||||
{
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = v.uv;
|
||||
return o;
|
||||
}
|
||||
|
||||
sampler2D _MainTex, _CameraDepthNormalsTexture;
|
||||
float _MinBrightness, _MaxBrightness, _ColorBands, _LightToNormalFactor;
|
||||
fixed4 _DarkColor, _BrightColor;
|
||||
|
||||
fixed4 frag (v2f i) : SV_Target
|
||||
{
|
||||
float4 depthnormal = tex2D(_CameraDepthNormalsTexture, i.uv);
|
||||
fixed4 col = tex2D(_MainTex, i.uv);
|
||||
|
||||
//decode depthnormal
|
||||
float3 normal;
|
||||
float depth;
|
||||
DecodeDepthNormal(depthnormal, depth, normal);
|
||||
|
||||
//Get the luminance and process it
|
||||
fixed normalLuminance = Luminance(fixed3(normal.b, normal.b, normal.b));
|
||||
fixed lightLuminance = Luminance(fixed3(col.r, col.g, col.b));
|
||||
|
||||
fixed luminance = lerp(normalLuminance, lightLuminance, _LightToNormalFactor);
|
||||
|
||||
luminance = remap(luminance, 0, 1, _MinBrightness, _MaxBrightness);
|
||||
luminance = floor(luminance * _ColorBands) / _ColorBands;
|
||||
|
||||
float depthFactor = 1 - step(1, depth);
|
||||
fixed4 output = lerp(_DarkColor, _BrightColor, luminance);
|
||||
output = fixed4(output.r, output.g, output.b, depthFactor);
|
||||
|
||||
return output;
|
||||
}
|
||||
ENDCG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ca1ad64f6fe2663418174309f73c9ec5
|
||||
timeCreated: 1640641164
|
||||
licenseType: Free
|
||||
ShaderImporter:
|
||||
defaultTextures: []
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,204 @@
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
[ExecuteInEditMode]
|
||||
public class IconCamera : MonoBehaviour
|
||||
{
|
||||
[Header("Hover over variables to show additional tooltips.")]
|
||||
[Tooltip("Use this to trigger the capture of an icon IN PLAYMODE ONLY!")]
|
||||
public KeyCode iconCaptureKey;
|
||||
|
||||
[Tooltip("Use this checkbox like a button to trigger the capture of an icon (Editor or Playmode).")]
|
||||
public bool iconCaptureButton;
|
||||
|
||||
[Tooltip("Path to icons folder (without \"Assets\" in the beginning).")]
|
||||
public string path = "Icons";
|
||||
|
||||
[Tooltip("Name of the generated Icon without a file extension (no \".png\" required).")]
|
||||
public string iconName = "ExampleIcon";
|
||||
|
||||
[Tooltip("The depth texture mode of the camera. Some effects will require either DepthNormals or Depth to work correctly")]
|
||||
public DepthTextureMode CameraDepthMode = DepthTextureMode.DepthNormals;
|
||||
|
||||
[Tooltip("Material that determines the post effect of the image")]
|
||||
public Material effectMaterial;
|
||||
|
||||
[Tooltip("The background image that will be applied in areas with full transparency")]
|
||||
public Texture2D background;
|
||||
|
||||
[HideInInspector]
|
||||
public RenderTexture renderTexture;
|
||||
|
||||
|
||||
public Camera thisCamera
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_camera)
|
||||
{
|
||||
_camera = this.gameObject.GetComponent<Camera>();
|
||||
}
|
||||
|
||||
return _camera;
|
||||
}
|
||||
}
|
||||
private Camera _camera;
|
||||
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetKeyDown(iconCaptureKey))
|
||||
{
|
||||
Capture();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void OnRenderImage(RenderTexture source, RenderTexture destination)
|
||||
{
|
||||
if(renderTexture != null)
|
||||
{
|
||||
RenderTexture.ReleaseTemporary(renderTexture);
|
||||
}
|
||||
|
||||
if (effectMaterial != null)
|
||||
{
|
||||
Graphics.Blit(source, destination, effectMaterial);
|
||||
}
|
||||
else
|
||||
{
|
||||
Graphics.Blit(source, destination);
|
||||
}
|
||||
|
||||
renderTexture = RenderTexture.GetTemporary(source.width, source.height);
|
||||
Graphics.Blit(destination, renderTexture);
|
||||
}
|
||||
|
||||
public void Capture()
|
||||
{
|
||||
Debug.Log("Say Cheese!");
|
||||
|
||||
//Manually calling render on the camera caused editor lockup with larger resolutions
|
||||
//thisCamera.Render();
|
||||
|
||||
RenderTexture.active = renderTexture;
|
||||
Texture2D texture = new Texture2D(renderTexture.width, renderTexture.height);
|
||||
texture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0);
|
||||
texture.Apply();
|
||||
|
||||
texture = FlipTexture(texture);
|
||||
|
||||
if(background != null)
|
||||
{
|
||||
texture = AddBackground(texture, background);
|
||||
}
|
||||
|
||||
|
||||
byte[] bytes = texture.EncodeToPNG();
|
||||
|
||||
string imagePath = Application.dataPath + "/" + path + "/" + iconName + ".png";
|
||||
string assetPath = "Assets" + "/" + path + "/" + iconName + ".png";
|
||||
File.WriteAllBytes(imagePath, bytes);
|
||||
|
||||
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
|
||||
|
||||
|
||||
TextureImporter importer = (TextureImporter)TextureImporter.GetAtPath(assetPath);
|
||||
|
||||
importer.isReadable = true;
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.spriteImportMode = SpriteImportMode.Single;
|
||||
importer.alphaSource = TextureImporterAlphaSource.FromInput;
|
||||
importer.alphaIsTransparency = true;
|
||||
importer.mipmapEnabled = false;
|
||||
importer.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
EditorUtility.SetDirty(importer);
|
||||
importer.SaveAndReimport();
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns a flipped copy of the given texture
|
||||
/// Taken from this forum: https://forum.unity.com/threads/flipping-texture2d-image-within-unity.35974/
|
||||
/// </summary>
|
||||
/// <param name="original"></param>
|
||||
/// <returns></returns>
|
||||
public Texture2D FlipTexture(Texture2D original)
|
||||
{
|
||||
Texture2D flipped = new Texture2D(original.width, original.height);
|
||||
|
||||
int origWidth = original.width;
|
||||
int origHeight = original.height;
|
||||
|
||||
for (int x = 0; x < origWidth; x++)
|
||||
{
|
||||
for (int y = 0; y < origHeight; y++)
|
||||
{
|
||||
flipped.SetPixel(x, origHeight - y - 1, original.GetPixel(x, y));
|
||||
}
|
||||
}
|
||||
flipped.Apply();
|
||||
|
||||
return flipped;
|
||||
}
|
||||
|
||||
|
||||
public Texture2D AddBackground(Texture2D original, Texture2D background)
|
||||
{
|
||||
Texture2D result = new Texture2D(original.width, original.height);
|
||||
|
||||
int origWidth = original.width;
|
||||
int origHeight = original.height;
|
||||
int backWidth = background.width;
|
||||
int backHeight = background.height;
|
||||
|
||||
for (int x = 0; x < origWidth; x++)
|
||||
{
|
||||
for (int y = 0; y < origHeight; y++)
|
||||
{
|
||||
Color originalPixel = original.GetPixel(x, y);
|
||||
|
||||
if(originalPixel.a == 0)
|
||||
{
|
||||
int backX = (int)Remap(x, 0, origWidth, 0, backWidth);
|
||||
int backY = (int)Remap(y, 0, origHeight, 0, backHeight);
|
||||
result.SetPixel(x, y, background.GetPixel(backX, backY));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.SetPixel(x, y, originalPixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Apply();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a given value from one range to another
|
||||
/// Taken from this forum: https://forum.unity.com/threads/re-map-a-number-from-one-range-to-another.119437/
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="from1"></param>
|
||||
/// <param name="to1"></param>
|
||||
/// <param name="from2"></param>
|
||||
/// <param name="to2"></param>
|
||||
/// <returns></returns>
|
||||
public float Remap(float value, float from1, float to1, float from2, float to2)
|
||||
{
|
||||
return (value - from1) / (to1 - from1) * (to2 - from2) + from2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dcb72b0d9a9ea3b43a48a22b952f43c5
|
||||
timeCreated: 1637536229
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user