Genesis Game Client Project Setup
This commit is contained in:
@@ -0,0 +1,247 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class BodyShapeModifier : MonoBehaviour
|
||||
{
|
||||
private OutfitSystem system;
|
||||
|
||||
public string shapeName;
|
||||
public string sorting;
|
||||
|
||||
public bool useScale;
|
||||
public float scaleValue = 1;
|
||||
public float xScaleValue = 1;
|
||||
public float yScaleValue = 1;
|
||||
public float zScaleValue = 1;
|
||||
public BodyShapeModifier[] counterScale;
|
||||
private Vector3 counterValue;
|
||||
public Dictionary<string, Vector3> counterSources = new Dictionary<string, Vector3>();
|
||||
|
||||
public bool useXScale;
|
||||
public bool useYScale;
|
||||
public bool useZScale;
|
||||
public bool linkScaleAxis;
|
||||
|
||||
public Vector2 scaleRange = new Vector2(0.5f, 2f);
|
||||
|
||||
public bool usePosition;
|
||||
private Vector3 initalPosition;
|
||||
private Vector3 initalMirrorPosition;
|
||||
public float posValue = 0;
|
||||
public float xPosValue = 0;
|
||||
public float yPosValue = 0;
|
||||
public float zPosValue = 0;
|
||||
public bool useXPos;
|
||||
public bool useYPos;
|
||||
public bool useZPos;
|
||||
public Vector2 posRange = new Vector2(-0.02f, 0.02f);
|
||||
|
||||
public bool useRotation;
|
||||
public float rotation;
|
||||
public Vector3 rotationAxis;
|
||||
public Vector2 rotRange = new Vector2(-90f, 90f);
|
||||
|
||||
[SerializeField] bool MirrorTransform;
|
||||
private Transform mirror;
|
||||
|
||||
private bool initalized;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
Init();
|
||||
}
|
||||
|
||||
public void Init()
|
||||
{
|
||||
if (initalized) return;
|
||||
system = GetComponentInParent<OutfitSystem>();
|
||||
initalPosition = transform.localPosition;
|
||||
|
||||
if (!system)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (MirrorTransform)
|
||||
{
|
||||
var boneName = name;
|
||||
boneName = boneName.Replace("_l", "_r");
|
||||
var bones = system.GetBones();
|
||||
|
||||
mirror = bones[boneName];
|
||||
initalMirrorPosition = mirror.localPosition;
|
||||
}
|
||||
|
||||
initalized = true;
|
||||
}
|
||||
|
||||
public void SetScale(float x, float y, float z, float v)
|
||||
{
|
||||
xScaleValue = x;
|
||||
yScaleValue = y;
|
||||
zScaleValue = z;
|
||||
scaleValue = v;
|
||||
ApplyScale();
|
||||
}
|
||||
|
||||
public void SetScale(float value)
|
||||
{
|
||||
scaleValue = value;
|
||||
ApplyScale();
|
||||
}
|
||||
|
||||
public void SetPosition(float x, float y, float z)
|
||||
{
|
||||
xPosValue = x;
|
||||
yPosValue = y;
|
||||
zPosValue = z;
|
||||
|
||||
ApplyPosition();
|
||||
}
|
||||
|
||||
public void SetRotation(float value)
|
||||
{
|
||||
rotation = value;
|
||||
ApplyRotation();
|
||||
}
|
||||
|
||||
public void Apply()
|
||||
{
|
||||
if (!initalized) Init();
|
||||
|
||||
if (usePosition) ApplyPosition();
|
||||
if (useRotation) ApplyRotation();
|
||||
if (useScale) ApplyScale();
|
||||
}
|
||||
|
||||
public void ApplyScale()
|
||||
{
|
||||
scaleValue = Mathf.Clamp(scaleValue, scaleRange.x, scaleRange.y);
|
||||
xScaleValue = Mathf.Clamp(xScaleValue, scaleRange.x, scaleRange.y);
|
||||
yScaleValue = Mathf.Clamp(yScaleValue, scaleRange.x, scaleRange.y);
|
||||
zScaleValue = Mathf.Clamp(zScaleValue, scaleRange.x, scaleRange.y);
|
||||
|
||||
var xSca = 1f;
|
||||
var ySca = 1f;
|
||||
var zSca = 1f;
|
||||
|
||||
if (linkScaleAxis)
|
||||
{
|
||||
if (useXScale) xSca = scaleValue;
|
||||
if (useYScale) ySca = scaleValue;
|
||||
if (useZScale) zSca = scaleValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (useXScale) xSca = xScaleValue;
|
||||
if (useYScale) ySca = yScaleValue;
|
||||
if (useZScale) zSca = zScaleValue;
|
||||
}
|
||||
|
||||
var scale = new Vector3(xSca, ySca, zSca);
|
||||
var counter = new Vector3(xSca - 1, ySca - 1, zSca - 1);
|
||||
|
||||
counterValue = Vector3.zero;
|
||||
foreach (var item in counterSources.Values)
|
||||
{
|
||||
counterValue += item;
|
||||
}
|
||||
|
||||
transform.localScale = scale - counterValue;
|
||||
if (mirror) mirror.localScale = scale - counterValue;
|
||||
|
||||
foreach (var item in counterScale)
|
||||
{
|
||||
if (!item) continue;
|
||||
item.counterSources[this.name] = counter; item.ApplyScale();
|
||||
}
|
||||
}
|
||||
|
||||
public void ApplyPosition()
|
||||
{
|
||||
xPosValue = Mathf.Clamp(xPosValue, posRange.x, posRange.y);
|
||||
yPosValue = Mathf.Clamp(yPosValue, posRange.x, posRange.y);
|
||||
zPosValue = Mathf.Clamp(zPosValue, posRange.x, posRange.y);
|
||||
|
||||
var xPos = 0f;
|
||||
var yPos = 0f;
|
||||
var zPos = 0f;
|
||||
|
||||
if (useXPos) xPos = xPosValue;
|
||||
if (useYPos) yPos = yPosValue;
|
||||
if (useZPos) zPos = zPosValue;
|
||||
|
||||
var position = new Vector3(xPos, yPos, zPos);
|
||||
var mirrorPosition = new Vector3(-xPos, yPos, zPos);
|
||||
|
||||
|
||||
transform.localPosition = position + initalPosition;
|
||||
if (mirror) mirror.localPosition = mirrorPosition + initalMirrorPosition;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void ApplyRotation()
|
||||
{
|
||||
rotation = Mathf.Clamp(rotation, rotRange.x, rotRange.y);
|
||||
|
||||
var rot = new Vector3(rotation * rotationAxis.x, rotation * rotationAxis.y, rotation * rotationAxis.z);
|
||||
|
||||
transform.localRotation = Quaternion.Euler(rot);
|
||||
if (mirror) mirror.localRotation = Quaternion.Euler(-rot);
|
||||
}
|
||||
|
||||
public BodyModData GetData()
|
||||
{
|
||||
var data = new BodyModData();
|
||||
|
||||
data.scaleValue = scaleValue;
|
||||
data.scale = new Vector3(xScaleValue, yScaleValue, zScaleValue);
|
||||
|
||||
data.posValue = posValue;
|
||||
data.position = new Vector3(xPosValue, yPosValue, zPosValue);
|
||||
|
||||
data.rotation = rotation;
|
||||
return data;
|
||||
}
|
||||
|
||||
public void SetData(BodyModData data)
|
||||
{
|
||||
|
||||
scaleValue = data.scaleValue;
|
||||
xScaleValue = data.scale.x;
|
||||
yScaleValue = data.scale.y;
|
||||
zScaleValue = data.scale.z;
|
||||
|
||||
posValue = data.posValue;
|
||||
xPosValue = data.position.x;
|
||||
yPosValue = data.position.y;
|
||||
zPosValue = data.position.z;
|
||||
|
||||
rotation = data.rotation;
|
||||
|
||||
Apply();
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class BodyModData
|
||||
{
|
||||
public float scaleValue = 1;
|
||||
public Vector3 scale;
|
||||
|
||||
public float posValue = 1;
|
||||
public Vector3 position;
|
||||
|
||||
public float rotation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8039adc7b05144b4d913dc2c1c09d964
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4dadfeb97bd4ca74bb9ef661700702c5
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,339 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public static class BMAC_SaveSystem
|
||||
{
|
||||
public static string filePath = Application.persistentDataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves";
|
||||
public static string iconFilePath = Application.persistentDataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves/Icons";
|
||||
public static string assetPath = "Assets/BoZo_ModularAnimeCharacters/CharacterSaves/Resources/";
|
||||
public static string iconAssetPath = "Assets/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/";
|
||||
|
||||
public static void SaveCharacter(OutfitSystem outfitSystem, string saveName, Texture2D icon = null)
|
||||
{
|
||||
var data = GetCharacterData(outfitSystem);
|
||||
|
||||
data.characterName = saveName;
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
var CharacterSave = ScriptableObject.CreateInstance<CharacterObject>();
|
||||
CharacterSave.data = data;
|
||||
CharacterSave.icon = icon;
|
||||
AssetDatabase.CreateAsset(CharacterSave, assetPath + "/" + saveName + ".asset");
|
||||
AssetDatabase.Refresh();
|
||||
#endif
|
||||
|
||||
string saveData = JsonUtility.ToJson(data);
|
||||
System.IO.File.WriteAllText(filePath + "/" + saveName + ".json", saveData);
|
||||
Debug.Log("Character Saved:" + filePath + "/" + saveName + ".json");
|
||||
}
|
||||
|
||||
public static CharacterData GetCharacterData(OutfitSystem outfitSystem)
|
||||
{
|
||||
if (outfitSystem.mergedMode) return outfitSystem.data;
|
||||
|
||||
var data = new CharacterData();
|
||||
|
||||
//Saving BlendShapes
|
||||
var bodyShapeValues = outfitSystem.GetBodyShapeValues();
|
||||
data.bodyIDs = bodyShapeValues.Keys.ToList();
|
||||
data.bodyShapes = bodyShapeValues.Values.ToList();
|
||||
|
||||
var faceShapeValues = outfitSystem.GetFaceShapeValues();
|
||||
data.faceIDs = faceShapeValues.Keys.ToList();
|
||||
data.faceShapes = faceShapeValues.Values.ToList();
|
||||
|
||||
//Saving Body Mods
|
||||
var modData = new List<BodyModData>();
|
||||
var modKeys = outfitSystem.bodyModifiers.Keys.ToList();
|
||||
for (int i = 0; i < modKeys.Count; i++)
|
||||
{
|
||||
var mod = outfitSystem.bodyModifiers[modKeys[i]].GetData();
|
||||
modData.Add(mod);
|
||||
}
|
||||
data.bodyMods = modData;
|
||||
data.bodyModsKeys = modKeys;
|
||||
|
||||
//Saving Outfits
|
||||
var outfits = outfitSystem.GetOutfits();
|
||||
var outfitDataList = new List<OutfitData>();
|
||||
|
||||
for (int i = 0; i < outfits.Count; i++)
|
||||
{
|
||||
if (outfits[i] == null) continue;
|
||||
outfitDataList.Add(outfits[i].GetOutfitData());
|
||||
}
|
||||
|
||||
data.stance = outfitSystem.stance;
|
||||
data.outfitDatas = outfitDataList;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public static async Task LoadCharacter(OutfitSystem outfitSystem, CharacterData characterObject = null, bool manualShapeApply = false, bool async = false)
|
||||
{
|
||||
|
||||
CharacterData loadData = characterObject;
|
||||
|
||||
|
||||
//Loading Outfits
|
||||
|
||||
bool hasBody = false;
|
||||
List<Outfit> outfits = new List<Outfit>();
|
||||
|
||||
if (async)
|
||||
{
|
||||
outfits = await LoadOutfits(loadData.outfitDatas);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var item in loadData.outfitDatas)
|
||||
{
|
||||
outfits.Add(Resources.Load<Outfit>(item.outfit));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
outfitSystem.RemoveAllOutfits();
|
||||
|
||||
for (int i = 0; i < loadData.outfitDatas.Count; i++)
|
||||
{
|
||||
var outfitData = loadData.outfitDatas[i];
|
||||
var outfit = outfits[i];
|
||||
|
||||
|
||||
if (outfit == null)
|
||||
{
|
||||
Debug.LogWarning("Outfit Path: " + outfitData.outfit + " returns null make sure Prefab is named correctly");
|
||||
continue;
|
||||
}
|
||||
//Check If Outfit is the same
|
||||
|
||||
var inst = outfitSystem.InstantiateOutfit(outfit);
|
||||
|
||||
|
||||
|
||||
//Checking For Old Data
|
||||
if (outfit.Type.name == "Body") hasBody = true;
|
||||
|
||||
inst.Attach();
|
||||
|
||||
if (inst.customShader)
|
||||
{
|
||||
inst.SetSwatch(outfitData.swatch);
|
||||
inst.SetColor(outfitData.color);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int c = 0; c < 9; c++)
|
||||
{
|
||||
|
||||
if (outfitData.colors.Count > c)
|
||||
{
|
||||
inst.SetColor(outfitData.colors[c], c + 1);
|
||||
}
|
||||
|
||||
if(c + 1 <= 2 && outfitData.decal != "")
|
||||
{
|
||||
inst.SetDecalColor(outfitData.decalColors[c], c + 1);
|
||||
}
|
||||
if (c + 1 <= 2 && outfitData.pattern != "")
|
||||
{
|
||||
inst.SetPatternColor(outfitData.patternColors[c], c + 1);
|
||||
}
|
||||
}
|
||||
|
||||
var decal = Resources.Load<Texture>(outfitData.decal);
|
||||
inst.SetDecal(decal);
|
||||
inst.SetDecalSize(outfitData.decalScale);
|
||||
|
||||
var pattern = Resources.Load<Texture>(outfitData.pattern);
|
||||
inst.SetPattern(pattern);
|
||||
inst.SetPatternSize(outfitData.patternScale);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//LEGACY Loading Body
|
||||
if(!hasBody)
|
||||
{
|
||||
var body = outfitSystem.GetOutfit("Body");
|
||||
if(body == null)
|
||||
{
|
||||
var bodyPrefab = Resources.Load<Outfit>("Body/Body_BasicBody");
|
||||
body = outfitSystem.InstantiateOutfit(bodyPrefab);
|
||||
}
|
||||
|
||||
for (int i = 0; i < loadData.bodyData.colors.Count; i++)
|
||||
{
|
||||
body.SetColor(loadData.bodyData.colors[i], i + 1);
|
||||
}
|
||||
|
||||
var bodyDecal = Resources.Load<Texture>(loadData.bodyData.decal);
|
||||
|
||||
body.SetDecal(bodyDecal);
|
||||
for (int i = 0; i < loadData.bodyData.decalColors.Count; i++)
|
||||
{
|
||||
body.SetDecalColor(loadData.bodyData.decalColors[i], i + 1);
|
||||
}
|
||||
|
||||
var bodyPattern = Resources.Load<Texture>(loadData.bodyData.pattern);
|
||||
|
||||
body.SetPattern(bodyPattern);
|
||||
for (int i = 0; i < loadData.bodyData.patternColors.Count; i++)
|
||||
{
|
||||
body.SetPatternColor(loadData.bodyData.patternColors[i], i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Loading Body Morphs
|
||||
|
||||
for (int i = 0; i < loadData.bodyIDs.Count; i++)
|
||||
{
|
||||
outfitSystem.SetShape(loadData.bodyIDs[i], loadData.bodyShapes[i]);
|
||||
}
|
||||
|
||||
for (int i = 0; i < loadData.faceIDs.Count; i++)
|
||||
{
|
||||
outfitSystem.SetShape(loadData.faceIDs[i], loadData.faceShapes[i]);
|
||||
}
|
||||
|
||||
if(!manualShapeApply) LoadBodyMods(outfitSystem, loadData);
|
||||
|
||||
|
||||
outfitSystem.animator.Rebind();
|
||||
outfitSystem.SetStance(loadData.stance);
|
||||
}
|
||||
|
||||
public static void LoadBodyMods(OutfitSystem outfitSystem, CharacterData loadData)
|
||||
{
|
||||
for (int i = 0; i < loadData.bodyModsKeys.Count; i++)
|
||||
{
|
||||
outfitSystem.bodyModifiers[loadData.bodyModsKeys[i]].SetData(loadData.bodyMods[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static CharacterData GetDataFromID(string saveName)
|
||||
{
|
||||
CharacterData loadData;
|
||||
Debug.Log("Attempted Load at: " + filePath + "/" + saveName + ".json");
|
||||
if (!System.IO.File.Exists(filePath + "/" + saveName + ".json"))
|
||||
{
|
||||
Debug.LogWarning($"Save ID: {saveName} does not exist. Make sure input matches an existing Save");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
string data = System.IO.File.ReadAllText(filePath + "/" + saveName + ".json");
|
||||
loadData = JsonUtility.FromJson<CharacterData>(data);
|
||||
return loadData;
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetJsonFromID(string saveName)
|
||||
{
|
||||
Debug.Log("Attempted Load at: " + filePath + "/" + saveName + ".json");
|
||||
if (!System.IO.File.Exists(filePath + "/" + saveName + ".json"))
|
||||
{
|
||||
Debug.LogWarning($"Save ID: {saveName} does not exist. Make sure input matches an existing Save");
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
string data = System.IO.File.ReadAllText(filePath + "/" + saveName + ".json");
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<List<Outfit>> LoadOutfits(List<OutfitData> outfitDatas)
|
||||
{
|
||||
var loadTasks = outfitDatas.Select(data => LoadResourceAsync<Outfit>(data.outfit));
|
||||
return (await Task.WhenAll(loadTasks)).ToList();
|
||||
}
|
||||
|
||||
public static async Task<T> LoadResourceAsync<T>(string path) where T : UnityEngine.Object
|
||||
{
|
||||
ResourceRequest request = Resources.LoadAsync<T>(path);
|
||||
var tcs = new TaskCompletionSource<T>();
|
||||
|
||||
request.completed += operation =>
|
||||
{
|
||||
if (request.asset == null)
|
||||
{
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
else if (request.asset is not T result)
|
||||
{
|
||||
tcs.SetResult(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
tcs.SetResult(result);
|
||||
}
|
||||
};
|
||||
|
||||
return await tcs.Task;
|
||||
}
|
||||
|
||||
public static void DeleteCharacter(string characterName)
|
||||
{
|
||||
System.IO.File.Delete(filePath + "/" + characterName + ".json");
|
||||
System.IO.File.Delete(iconFilePath + "/" + characterName + ".png");
|
||||
System.IO.File.Delete(assetPath + "/" + characterName + ".asset");
|
||||
System.IO.File.Delete(assetPath + "/" + characterName + ".meta");
|
||||
System.IO.File.Delete(iconAssetPath + characterName + ".png");
|
||||
System.IO.File.Delete(iconAssetPath + characterName + ".meta");
|
||||
#if UNITY_EDITOR
|
||||
AssetDatabase.Refresh();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class CharacterData
|
||||
{
|
||||
public string characterName;
|
||||
public List<string> bodyIDs;
|
||||
public List<float> bodyShapes;
|
||||
public List<string> faceIDs;
|
||||
public List<float> faceShapes;
|
||||
public List<string> bodyModsKeys;
|
||||
public List<BodyModData> bodyMods;
|
||||
public List<OutfitData> outfitDatas;
|
||||
public OutfitData bodyData;
|
||||
public float stance;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class OutfitData
|
||||
{
|
||||
public string outfit;
|
||||
public List<Color> colors;
|
||||
|
||||
public string decal;
|
||||
public List<Color> decalColors;
|
||||
public Vector4 decalScale;
|
||||
|
||||
public string pattern;
|
||||
public List<Color> patternColors;
|
||||
public Vector4 patternScale;
|
||||
|
||||
//Custom Shader Data
|
||||
public Color color = Color.white;
|
||||
public int swatch;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b719335614062204d9ab42ec5bfab351
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/BMAC_SaveSystem.cs
|
||||
uploadId: 853356
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 64cef876055435e43aba052093527416
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/BoZoCharacterOptimizer.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,37 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
public class BoZo_Links : MonoBehaviour
|
||||
{
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
#if !UNITY_EDITOR
|
||||
Destroy(this.gameObject);
|
||||
#endif
|
||||
}
|
||||
public void Documentation()
|
||||
{
|
||||
Application.OpenURL("https://docs.google.com/document/d/1kf1KGT-OqV3Ecvnej0mpmgIOkc-_e7UJp-BkGuZfuN4/edit?usp=sharing");
|
||||
}
|
||||
|
||||
public void Discord()
|
||||
{
|
||||
Application.OpenURL("https://discord.gg/UCbRjUy7m7");
|
||||
}
|
||||
|
||||
public void Twitter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Youtube()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf7b6117bf8d6a6489dcc7b01c90a2be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/BoZo_Links.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,117 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class BodyShapeSliders : MonoBehaviour
|
||||
{
|
||||
private OutfitSystem system;
|
||||
private BodyShapeModifier bodyShape;
|
||||
[SerializeField] TMP_Text title;
|
||||
[SerializeField] Transform scaleContainer;
|
||||
[SerializeField] Slider scaleSlider;
|
||||
[SerializeField] Slider xScaleSlider;
|
||||
[SerializeField] Slider yScaleSlider;
|
||||
[SerializeField] Slider zScaleSlider;
|
||||
|
||||
[SerializeField] Transform positionContainer;
|
||||
[SerializeField] Slider xPositionSlider;
|
||||
[SerializeField] Slider yPositionSlider;
|
||||
[SerializeField] Slider zPositionSlider;
|
||||
|
||||
[SerializeField] Transform rotationContainer;
|
||||
[SerializeField] Slider rotationSlider;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if(system != null && bodyShape != null)
|
||||
{
|
||||
Init(system, bodyShape);
|
||||
}
|
||||
}
|
||||
|
||||
public void Init(OutfitSystem system, BodyShapeModifier mod)
|
||||
{
|
||||
this.system = system;
|
||||
bodyShape = mod;
|
||||
title.text = mod.shapeName;
|
||||
|
||||
if (bodyShape.useScale)
|
||||
{
|
||||
if (bodyShape.linkScaleAxis)
|
||||
{
|
||||
xScaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
yScaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
zScaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!bodyShape.useXScale) xScaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
if (!bodyShape.useYScale) yScaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
if (!bodyShape.useZScale) zScaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
scaleSlider.transform.parent.gameObject.SetActive(false);
|
||||
scaleSlider.onValueChanged.AddListener(SetScale);
|
||||
}
|
||||
scaleSlider.onValueChanged.AddListener(SetScale);
|
||||
xScaleSlider.onValueChanged.AddListener(SetScale);
|
||||
yScaleSlider.onValueChanged.AddListener(SetScale);
|
||||
zScaleSlider.onValueChanged.AddListener(SetScale);
|
||||
|
||||
scaleSlider.minValue = bodyShape.scaleRange.x; scaleSlider.maxValue = bodyShape.scaleRange.y;
|
||||
xScaleSlider.minValue = bodyShape.scaleRange.x; xScaleSlider.maxValue = bodyShape.scaleRange.y;
|
||||
yScaleSlider.minValue = bodyShape.scaleRange.x; yScaleSlider.maxValue = bodyShape.scaleRange.y;
|
||||
zScaleSlider.minValue = bodyShape.scaleRange.x; zScaleSlider.maxValue = bodyShape.scaleRange.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
scaleContainer.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (bodyShape.usePosition)
|
||||
{
|
||||
if (!bodyShape.useXPos) xPositionSlider.transform.parent.gameObject.SetActive(false);
|
||||
if (!bodyShape.useYPos) yPositionSlider.transform.parent.gameObject.SetActive(false);
|
||||
if (!bodyShape.useZPos) zPositionSlider.transform.parent.gameObject.SetActive(false);
|
||||
|
||||
xPositionSlider.minValue = bodyShape.posRange.x; xPositionSlider.maxValue = bodyShape.posRange.y;
|
||||
yPositionSlider.minValue = bodyShape.posRange.x; yPositionSlider.maxValue = bodyShape.posRange.y;
|
||||
zPositionSlider.minValue = bodyShape.posRange.x; zPositionSlider.maxValue = bodyShape.posRange.y;
|
||||
|
||||
xPositionSlider.onValueChanged.AddListener(SetPosition);
|
||||
yPositionSlider.onValueChanged.AddListener(SetPosition);
|
||||
zPositionSlider.onValueChanged.AddListener(SetPosition);
|
||||
}
|
||||
else
|
||||
{
|
||||
positionContainer.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
if (bodyShape.useRotation)
|
||||
{
|
||||
rotationSlider.onValueChanged.AddListener(SetRotation);
|
||||
rotationSlider.minValue = bodyShape.rotRange.x; rotationSlider.maxValue = bodyShape.rotRange.y;
|
||||
}
|
||||
else
|
||||
{
|
||||
rotationContainer.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScale(float v)
|
||||
{
|
||||
bodyShape.SetScale(xScaleSlider.value, yScaleSlider.value, zScaleSlider.value, scaleSlider.value);
|
||||
}
|
||||
|
||||
public void SetPosition(float v)
|
||||
{
|
||||
bodyShape.SetPosition(xPositionSlider.value, yPositionSlider.value, zPositionSlider.value);
|
||||
}
|
||||
|
||||
public void SetRotation(float v)
|
||||
{
|
||||
bodyShape.SetRotation(rotationSlider.value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5e1babcebe207f94b9aa4a53a2626694
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/BodyShapeSliders.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,99 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class CameraController : MonoBehaviour
|
||||
{
|
||||
Camera cam;
|
||||
float position;
|
||||
public float scrollSpeed;
|
||||
public Transform startPosition;
|
||||
public Transform endPosition;
|
||||
public Vector2 fov;
|
||||
public Slider slider;
|
||||
|
||||
public float tweenSpeed;
|
||||
|
||||
float tweenTimer;
|
||||
float currentPosition;
|
||||
float targetPosition;
|
||||
|
||||
[SerializeField] CameraPositions[] cameraPositions;
|
||||
Dictionary<OutfitType, CameraPositions> camPos = new Dictionary<OutfitType, CameraPositions>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
cam = Camera.main;
|
||||
foreach (var item in cameraPositions)
|
||||
{
|
||||
camPos.Add(item.type, item);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (Input.GetAxis("Mouse ScrollWheel") > 0f) // forward
|
||||
{
|
||||
position += scrollSpeed;
|
||||
tweenTimer = -1;
|
||||
}
|
||||
else if (Input.GetAxis("Mouse ScrollWheel") < 0f) // backwards
|
||||
{
|
||||
position -= scrollSpeed;
|
||||
tweenTimer = -1;
|
||||
}
|
||||
|
||||
slider.value = position;
|
||||
position = Mathf.Clamp(position, 0, 1);
|
||||
|
||||
if (tweenTimer >= 0)
|
||||
{
|
||||
position = Mathf.Lerp(targetPosition, currentPosition, tweenTimer);
|
||||
tweenTimer -= Time.deltaTime * tweenSpeed;
|
||||
}
|
||||
|
||||
cam.transform.position = Vector3.Lerp(startPosition.position, endPosition.position, position);
|
||||
cam.transform.rotation = Quaternion.Lerp(startPosition.rotation, endPosition.rotation, position);
|
||||
cam.fieldOfView = Mathf.Lerp(fov.x, fov.y, position);
|
||||
}
|
||||
|
||||
public void SetPosition(float value)
|
||||
{
|
||||
position = value;
|
||||
}
|
||||
|
||||
public void tweenPosition(float value)
|
||||
{
|
||||
tweenTimer = 1;
|
||||
targetPosition = value;
|
||||
currentPosition = position;
|
||||
}
|
||||
|
||||
public void TweenPosition(OutfitType type)
|
||||
{
|
||||
CameraPositions settings = null;
|
||||
if(!camPos.TryGetValue(type, out settings)) { settings = cameraPositions[0]; }
|
||||
startPosition = settings.ZoomOutPos;
|
||||
endPosition = settings.ZoomInPos;
|
||||
fov.x = settings.fovOut;
|
||||
fov.y = settings.fovIn;
|
||||
|
||||
tweenTimer = 1;
|
||||
targetPosition = settings.startingPosition;
|
||||
currentPosition = position;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
private class CameraPositions
|
||||
{
|
||||
public OutfitType type;
|
||||
public Transform ZoomOutPos;
|
||||
public Transform ZoomInPos;
|
||||
public float fovOut;
|
||||
public float fovIn;
|
||||
public float startingPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8de4c66bd7f475d4faab94d46d62a3f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/CameraController.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,471 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using TMPro;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class CharacterCreator : MonoBehaviour
|
||||
{
|
||||
[Header("Creator Dependencies")]
|
||||
public OutfitSystem character;
|
||||
[SerializeField] ColorPickerControl colorPickerControl;
|
||||
[SerializeField] CharacterSpinner Spinner;
|
||||
[SerializeField] Camera iconCamera;
|
||||
[SerializeField] RenderTexture iconTexture;
|
||||
public OutfitType[] outfitTypes;
|
||||
|
||||
[Header("Outfit Dependencies")]
|
||||
private Dictionary<string, Outfit> OutfitDataBase = new Dictionary<string, Outfit>();
|
||||
[SerializeField] OutfitSelector outfitSelectorObject;
|
||||
private List<OutfitSelector> outfitSelectors = new List<OutfitSelector>();
|
||||
[SerializeField] Transform outfitContainer;
|
||||
|
||||
[Header("Texture Dependencies")]
|
||||
[SerializeField] TextureSelector textureSelectorObject;
|
||||
private List<TextureSelector> textureSelectors = new List<TextureSelector>();
|
||||
[SerializeField] Transform decalContainer;
|
||||
[SerializeField] Transform patternContainer;
|
||||
|
||||
[Header("BodyShape Dependencies")]
|
||||
[SerializeField] BlendSlider blendSliderObject;
|
||||
private List<BlendSlider> blendSliders = new List<BlendSlider>();
|
||||
private List<BlendSlider> faceBlendSliders = new List<BlendSlider>();
|
||||
|
||||
[SerializeField] BodyShapeSliders modSliderObject;
|
||||
private List<BodyShapeSliders> ModSliders = new List<BodyShapeSliders>();
|
||||
|
||||
[SerializeField] Transform bodyShapeContainer;
|
||||
[SerializeField] Transform bodyModContainer;
|
||||
[SerializeField] Transform faceShapeContainer;
|
||||
[SerializeField] Transform faceModContainer;
|
||||
|
||||
[SerializeField] GameObject currentPage;
|
||||
private GameObject previousPage;
|
||||
|
||||
private Dictionary<string, List<GameObject>> outfits = new Dictionary<string, List<GameObject>>();
|
||||
private List<TexturePackage> textures = new List<TexturePackage>();
|
||||
|
||||
[Header("Save Dependencies")]
|
||||
[SerializeField] SaveSelector saveSelector;
|
||||
[SerializeField] Dictionary<string, SaveSelector> saveSlots = new Dictionary<string, SaveSelector>();
|
||||
[SerializeField] Transform saveContainer;
|
||||
[SerializeField] GameObject DeleteConfirmWindow;
|
||||
[SerializeField] TMP_Text loadedCharacterNameText;
|
||||
[SerializeField] TMP_Text DeleteCharacterNameText;
|
||||
|
||||
|
||||
private OutfitType type;
|
||||
|
||||
[Header("Save Options")]
|
||||
public TMP_InputField CharacterName;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
outfits.Clear();
|
||||
OutfitDataBase.Clear();
|
||||
|
||||
var ob = Resources.LoadAll<Outfit>("");
|
||||
var textureObjects = Resources.LoadAll<TexturePackage>("");
|
||||
foreach (var item in ob)
|
||||
{
|
||||
if (!item.showCharacterCreator) continue;
|
||||
OutfitDataBase.Add(item.name, item.GetComponent<Outfit>());
|
||||
}
|
||||
foreach (var item in textureObjects)
|
||||
{
|
||||
textures.Add(item.GetComponent<TexturePackage>());
|
||||
}
|
||||
|
||||
GenerateOutfitSelection();
|
||||
GenerateTextureSelection();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
character.OnOutfitChanged += OnOutfitUpdate;
|
||||
character.OnRigChanged += OnRigUpdate;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
character.OnOutfitChanged -= OnOutfitUpdate;
|
||||
character.OnRigChanged -= OnRigUpdate;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
GetBodyBlends();
|
||||
GetFaceBlends();
|
||||
GetBodyMods();
|
||||
SwitchCatagory("Top");
|
||||
|
||||
UpdateCharacterSaves();
|
||||
|
||||
}
|
||||
|
||||
public void GenerateOutfitSelection()
|
||||
{
|
||||
var outfits = OutfitDataBase.Values.ToArray();
|
||||
foreach (var item in outfits)
|
||||
{
|
||||
var selector = Instantiate(outfitSelectorObject, outfitContainer);
|
||||
selector.Init(item, this);
|
||||
outfitSelectors.Add(selector);
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateTextureSelection()
|
||||
{
|
||||
foreach (var item in textures)
|
||||
{
|
||||
Transform container = null;
|
||||
|
||||
if (item.type == TextureType.Decal) container = decalContainer;
|
||||
if (item.type == TextureType.Pattern) container = patternContainer;
|
||||
|
||||
var selector = Instantiate(textureSelectorObject, container);
|
||||
selector.Init(item, this);
|
||||
textureSelectors.Add(selector);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetBodyBlends()
|
||||
{
|
||||
for (int i = 0; i < blendSliders.Count; i++)
|
||||
{
|
||||
Destroy(blendSliders[i].gameObject);
|
||||
}
|
||||
blendSliders.Clear();
|
||||
|
||||
var shapes = character.GetShapes();
|
||||
foreach (var item in shapes)
|
||||
{
|
||||
var blendSlider = Instantiate(blendSliderObject, bodyShapeContainer);
|
||||
blendSlider.Init(character, item);
|
||||
blendSliders.Add(blendSlider);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetFaceBlends()
|
||||
{
|
||||
for (int i = 0; i < faceBlendSliders.Count; i++)
|
||||
{
|
||||
Destroy(faceBlendSliders[i].gameObject);
|
||||
}
|
||||
faceBlendSliders.Clear();
|
||||
|
||||
var shapes = character.GetFaceShapes();
|
||||
foreach (var item in shapes)
|
||||
{
|
||||
var blendSlider = Instantiate(blendSliderObject, faceShapeContainer);
|
||||
blendSlider.Init(character, item);
|
||||
faceBlendSliders.Add(blendSlider);
|
||||
}
|
||||
}
|
||||
|
||||
public void GetBodyMods()
|
||||
{
|
||||
var mods = character.GetMods().Values.ToList();
|
||||
|
||||
for (int i = 0; i < ModSliders.Count; i++)
|
||||
{
|
||||
Destroy(ModSliders[i].gameObject);
|
||||
}
|
||||
ModSliders.Clear();
|
||||
|
||||
var container = bodyShapeContainer;
|
||||
foreach (var item in mods)
|
||||
{
|
||||
if (item.sorting == "Head") container = faceModContainer;
|
||||
else container = bodyModContainer;
|
||||
var blendSlider = Instantiate(modSliderObject, container);
|
||||
blendSlider.Init(character, item);
|
||||
ModSliders.Add(blendSlider);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCharacterSaves()
|
||||
{
|
||||
var saves = saveSlots.Values.ToArray();
|
||||
foreach (var item in saves)
|
||||
{
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
saveSlots.Clear();
|
||||
|
||||
if (!System.IO.Directory.Exists(Application.persistentDataPath + "/BoZo_ModularAnimeCharacters"))
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(Application.persistentDataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/");
|
||||
print("Created Save JSON save Location At: " + Application.persistentDataPath + "/BoZo_ModularAnimeCharacters");
|
||||
}
|
||||
|
||||
string path = BMAC_SaveSystem.filePath;
|
||||
string[] jsonFiles = System.IO.Directory.GetFiles(path, "*.json");
|
||||
string[] icons = System.IO.Directory.GetFiles(path + "/Icons", "*.png");
|
||||
|
||||
for (int i = 0; i < jsonFiles.Length; i++)
|
||||
{
|
||||
var json = System.IO.File.ReadAllText(jsonFiles[i]);
|
||||
var data = JsonUtility.FromJson<CharacterData>(json);
|
||||
var image = System.IO.File.ReadAllBytes(icons[i]);
|
||||
var texture = new Texture2D(2, 2);
|
||||
Sprite icon = null;
|
||||
if (texture.LoadImage(image))
|
||||
{
|
||||
icon = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
|
||||
var selector = Instantiate(saveSelector, saveContainer);
|
||||
selector.Init(data, icon, this);
|
||||
saveSlots.Add(data.characterName, selector);
|
||||
}
|
||||
|
||||
var saveObjects = Resources.LoadAll<CharacterObject>("");
|
||||
|
||||
for (int i = 0; i < saveObjects.Length; i++)
|
||||
{
|
||||
var ob = saveObjects[i];
|
||||
if (saveSlots.ContainsKey(ob.data.characterName))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
var selector = Instantiate(saveSelector, saveContainer);
|
||||
Sprite icon = null;
|
||||
if(ob.icon != null)
|
||||
{
|
||||
icon = Sprite.Create(ob.icon, new Rect(0, 0, ob.icon.width, ob.icon.height), new Vector2(0.5f, 0.5f));
|
||||
}
|
||||
selector.Init(ob.data, icon, this);
|
||||
saveSlots.Add(ob.data.characterName, selector);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void OpenPage(GameObject page)
|
||||
{
|
||||
currentPage.SetActive(false);
|
||||
previousPage = currentPage;
|
||||
currentPage = page;
|
||||
currentPage.SetActive(true);
|
||||
}
|
||||
|
||||
public void BackPage()
|
||||
{
|
||||
currentPage.SetActive(false);
|
||||
currentPage = previousPage;
|
||||
currentPage.SetActive(true);
|
||||
colorPickerControl.RemoveObject();
|
||||
}
|
||||
|
||||
public void SetOutfit(Outfit outfit)
|
||||
{
|
||||
var inst = Instantiate(outfit, character.transform);
|
||||
SetColorPickerObject(inst);
|
||||
SwitchTextureCatagory(outfit.TextureCatagory);
|
||||
type = outfit.Type;
|
||||
|
||||
// var type = (OutfitType)Enum.Parse(typeof(OutfitType), catagory);
|
||||
}
|
||||
|
||||
public void OnOutfitUpdate(Outfit outfit)
|
||||
{
|
||||
if (outfit == null) return;
|
||||
if(outfit.Type.name == "Head")
|
||||
{
|
||||
GetFaceBlends();
|
||||
}
|
||||
if (outfit.Type.name == "Body")
|
||||
{
|
||||
GetBodyBlends();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnRigUpdate(SkinnedMeshRenderer rig)
|
||||
{
|
||||
//GetBodyBlends();
|
||||
GetBodyMods();
|
||||
}
|
||||
|
||||
public void SetOutfitDecal(Texture texture)
|
||||
{
|
||||
if (!colorPickerControl.colorObject) return;
|
||||
colorPickerControl.colorObject.SetDecal(texture);
|
||||
}
|
||||
public void SetOutfitPattern(Texture texture)
|
||||
{
|
||||
if (!colorPickerControl.colorObject) return;
|
||||
colorPickerControl.colorObject.SetPattern(texture);
|
||||
}
|
||||
|
||||
public void RemoveOutfit()
|
||||
{
|
||||
if (type == null) return;
|
||||
character.RemoveOutfit(type, true);
|
||||
colorPickerControl.RemoveObject();
|
||||
}
|
||||
|
||||
public void RemoveOutfitDecal()
|
||||
{
|
||||
if (!colorPickerControl.colorObject) return;
|
||||
colorPickerControl.colorObject.SetDecal(null);
|
||||
}
|
||||
|
||||
public void RemoveOutfitPattern()
|
||||
{
|
||||
if (!colorPickerControl.colorObject) return;
|
||||
colorPickerControl.colorObject.SetPattern(null);
|
||||
}
|
||||
|
||||
|
||||
public void SwitchCatagory(string catagory)
|
||||
{
|
||||
foreach (var item in outfitSelectors)
|
||||
{
|
||||
item.SetVisable(catagory);
|
||||
}
|
||||
|
||||
var outfit = character.GetOutfit(catagory);
|
||||
|
||||
SetColorPickerObject(outfit);
|
||||
|
||||
if (outfit == null) return;
|
||||
|
||||
SwitchTextureCatagory(outfit.TextureCatagory);
|
||||
type = outfit.Type;
|
||||
}
|
||||
|
||||
public void SwitchTextureCatagory(string catagory)
|
||||
{
|
||||
if (catagory == "")
|
||||
{
|
||||
catagory = "Outfit";
|
||||
}
|
||||
|
||||
foreach (var item in textureSelectors)
|
||||
{
|
||||
item.SetVisable(catagory);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetColorPickerObject(string type)
|
||||
{
|
||||
var outfit = character.GetOutfit(type);
|
||||
colorPickerControl.ChangeObject(outfit);
|
||||
}
|
||||
|
||||
public void SetColorPickerObject(Outfit outfit)
|
||||
{
|
||||
colorPickerControl.ChangeObject(outfit);
|
||||
}
|
||||
|
||||
public void ReplaceCharacter(OutfitSystem character)
|
||||
{
|
||||
Destroy(this.character.gameObject);
|
||||
this.character = character;
|
||||
Spinner.SetCharacter(character.transform);
|
||||
}
|
||||
|
||||
public void GetCurrentCatagory()
|
||||
{
|
||||
if (type == null) return;
|
||||
SwitchCatagory(type.name);
|
||||
}
|
||||
|
||||
public void CopyColor(string copyTo)
|
||||
{
|
||||
var copyOutfit = character.GetOutfit((OutfitType)Enum.Parse(typeof(OutfitType), copyTo));
|
||||
colorPickerControl.CopyColor(copyOutfit);
|
||||
}
|
||||
|
||||
public void ToggleWalk(bool value)
|
||||
{
|
||||
character.animator.SetBool("isWalk", value);
|
||||
}
|
||||
|
||||
public void SaveCharacter()
|
||||
{
|
||||
StartCoroutine(Save());
|
||||
}
|
||||
|
||||
public Outfit GetOutfit(string outfitName)
|
||||
{
|
||||
return OutfitDataBase[outfitName];
|
||||
}
|
||||
|
||||
[ContextMenu("Save")]
|
||||
private IEnumerator Save()
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
if(CharacterName.text.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("Please enter in a name with at least one letter");
|
||||
yield break;
|
||||
}
|
||||
|
||||
RenderTexture.active = iconTexture;
|
||||
Texture2D icon = new Texture2D(iconTexture.width, iconTexture.height, TextureFormat.RGBA32, false);
|
||||
Rect rect = new Rect(new Rect(0, 0, iconTexture.width, iconTexture.height));
|
||||
icon.ReadPixels(rect, 0,0);
|
||||
icon.Apply();
|
||||
|
||||
byte[] bytes = icon.EncodeToPNG();
|
||||
|
||||
Texture2D characterIcon = null;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
System.IO.File.WriteAllBytes(Application.dataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/" + CharacterName.text + ".png", bytes);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
characterIcon = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/" + CharacterName.text + ".png");
|
||||
TextureImporter importer = AssetImporter.GetAtPath("Assets/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/" + CharacterName.text + ".png") as TextureImporter;
|
||||
|
||||
if (importer != null)
|
||||
{
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.spriteImportMode = SpriteImportMode.Single;
|
||||
importer.SaveAndReimport();
|
||||
}
|
||||
#endif
|
||||
|
||||
if(!System.IO.Directory.Exists(Application.persistentDataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/"))
|
||||
{
|
||||
System.IO.Directory.CreateDirectory(Application.persistentDataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/");
|
||||
}
|
||||
|
||||
System.IO.File.WriteAllBytes(Application.persistentDataPath + "/BoZo_ModularAnimeCharacters/CharacterSaves/Icons/" + CharacterName.text + ".png", bytes);
|
||||
BMAC_SaveSystem.SaveCharacter(character, CharacterName.text, characterIcon);
|
||||
|
||||
UpdateCharacterSaves();
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void LoadCharacter(CharacterData data)
|
||||
{
|
||||
loadedCharacterNameText.text = data.characterName;
|
||||
_ = BMAC_SaveSystem.LoadCharacter(character, data, false, true);
|
||||
}
|
||||
|
||||
public void DeleteCharacter()
|
||||
{
|
||||
if (loadedCharacterNameText.text == "") return;
|
||||
DeleteCharacterNameText.text = "Delete: " + loadedCharacterNameText.text;
|
||||
DeleteConfirmWindow.SetActive(true);
|
||||
}
|
||||
|
||||
public void ConfirmDelete()
|
||||
{
|
||||
BMAC_SaveSystem.DeleteCharacter(loadedCharacterNameText.text);
|
||||
loadedCharacterNameText.text = "";
|
||||
UpdateCharacterSaves();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a7ff0168c5a8aae45abec3f8e5dc6957
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/CharacterCreator.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,67 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class CharacterSpinner : MonoBehaviour, IDragHandler, IPointerClickHandler
|
||||
{
|
||||
public float spinDir;
|
||||
public Transform character;
|
||||
private Animator anim;
|
||||
float dizzyTimer = 1;
|
||||
|
||||
bool spinning;
|
||||
|
||||
public void SetCharacter(Transform character)
|
||||
{
|
||||
this.character = character;
|
||||
anim = character.GetComponentInChildren<Animator>();
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
spinning = true;
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
spinning = true;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
SetCharacter(character);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
|
||||
|
||||
if (spinning)
|
||||
{
|
||||
spinDir = -Input.GetAxis("Mouse X") * 5;
|
||||
dizzyTimer = 0.5f;
|
||||
}
|
||||
|
||||
if (Input.GetMouseButtonUp(0))
|
||||
{
|
||||
spinning = false;
|
||||
}
|
||||
character.Rotate(0, spinDir, 0);
|
||||
spinDir = Mathf.Lerp(spinDir, 0, Time.deltaTime);
|
||||
dizzyTimer -= Time.deltaTime;
|
||||
|
||||
if (dizzyTimer <= 0)
|
||||
{
|
||||
if (spinDir >= 5 || spinDir <= -5)
|
||||
{
|
||||
anim.SetBool("Dizzy", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
anim.SetBool("Dizzy", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 52defae866fd958429021f2e841897ff
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/CharacterSpinner.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,575 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class ColorPickerControl : MonoBehaviour
|
||||
{
|
||||
[Header("Picker Dependencies")]
|
||||
public CharacterCreator creator;
|
||||
public SVImageControl svContoller;
|
||||
[Header("Picker")]
|
||||
public float currentHue;
|
||||
public float currentSat;
|
||||
public float currentVal;
|
||||
public float currentColor;
|
||||
|
||||
[SerializeField] private RawImage hueImage;
|
||||
[SerializeField] private RawImage satValImage;
|
||||
[SerializeField] private RawImage outputImage;
|
||||
|
||||
[SerializeField] private Slider hueSlider;
|
||||
|
||||
private Texture2D hueTexture;
|
||||
private Texture2D svTexture;
|
||||
private Texture2D outputTexture;
|
||||
|
||||
public OutfitBase colorObject;
|
||||
public OutfitType outfitType;
|
||||
public Material colorMaterial;
|
||||
public int MaterialSlot;
|
||||
|
||||
[Header("Editor")]
|
||||
|
||||
[SerializeField] OutfitSystem outfitSystem;
|
||||
[SerializeField] TMP_Text objectName;
|
||||
[SerializeField] TMP_Text channelText;
|
||||
[SerializeField] Image Swatch;
|
||||
|
||||
[SerializeField] TMP_Text CopyCatagoryText;
|
||||
public List<string> outfitTypes = new List<string>();
|
||||
private int copyIndex;
|
||||
|
||||
[SerializeField] TextureType mode = TextureType.Base;
|
||||
[SerializeField] int currentChannel;
|
||||
[SerializeField] int maxChannel;
|
||||
[SerializeField] string[] channelNames;
|
||||
|
||||
[Header("Decal Editor")]
|
||||
[SerializeField] GameObject decalContainer;
|
||||
[SerializeField] Slider DecalXSlider;
|
||||
[SerializeField] Slider DecalYSlider;
|
||||
private Vector2 outfitDefaultDecalSize;
|
||||
|
||||
[Header("Pattern Editor")]
|
||||
[SerializeField] GameObject patternContainer;
|
||||
[SerializeField] Slider patternXSlider;
|
||||
[SerializeField] Slider patternYSlider;
|
||||
private Vector2 outfitDefaultPatternSize;
|
||||
|
||||
[Header("Swatch Editor")]
|
||||
[SerializeField] GameObject swatchParentContainer;
|
||||
[SerializeField] Transform swatchContainer;
|
||||
[SerializeField] SwatchSelector swatchSelectorObject;
|
||||
private List<SwatchSelector> swatchSelectors = new List<SwatchSelector>();
|
||||
|
||||
[Header("AdvancedEditor")]
|
||||
[SerializeField] TMP_Text hexValueTex;
|
||||
[SerializeField] List<Color> HeldColors = new List<Color>();
|
||||
[SerializeField] bool maintainColors;
|
||||
[SerializeField] Toggle maintainColorsToggle;
|
||||
[SerializeField] TMP_InputField inputR;
|
||||
[SerializeField] TMP_InputField inputG;
|
||||
[SerializeField] TMP_InputField inputB;
|
||||
|
||||
[SerializeField] TMP_InputField inputH;
|
||||
[SerializeField] TMP_InputField inputS;
|
||||
[SerializeField] TMP_InputField inputV;
|
||||
private Dictionary<OutfitType, OutfitPickerSettings> outfitPickerSettings = new Dictionary<OutfitType, OutfitPickerSettings>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
CreateHueImage();
|
||||
CreateSVImage();
|
||||
CreateOutputImage();
|
||||
UpdateOutputImage();
|
||||
|
||||
foreach (var type in creator.outfitTypes)
|
||||
{
|
||||
outfitTypes.Add(type.name);
|
||||
}
|
||||
CopyCatagoryText.text = outfitTypes[0];
|
||||
if (colorObject == null) gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void CreateHueImage()
|
||||
{
|
||||
hueTexture = new Texture2D(1, 16);
|
||||
hueTexture.wrapMode = TextureWrapMode.Clamp;
|
||||
hueTexture.name = "HueTexture";
|
||||
|
||||
for (int i = 0; i < hueTexture.height; i++)
|
||||
{
|
||||
hueTexture.SetPixel(0, i, Color.HSVToRGB((float)i / hueTexture.height, 1, 1));
|
||||
}
|
||||
|
||||
hueTexture.Apply();
|
||||
|
||||
currentHue = 0;
|
||||
hueImage.texture = hueTexture;
|
||||
}
|
||||
|
||||
private void CreateSVImage()
|
||||
{
|
||||
svTexture = new Texture2D(16, 16);
|
||||
svTexture.wrapMode = TextureWrapMode.Clamp;
|
||||
svTexture.name = "SVTexture";
|
||||
|
||||
for (int y = 0; y < svTexture.height; y++)
|
||||
{
|
||||
for (int x = 0; x < svTexture.width; x++)
|
||||
{
|
||||
svTexture.SetPixel(x, y, Color.HSVToRGB(currentHue, (float)x / svTexture.width, (float)y / svTexture.height));
|
||||
}
|
||||
}
|
||||
|
||||
svTexture.Apply();
|
||||
|
||||
currentSat = 0;
|
||||
currentVal = 0;
|
||||
satValImage.texture = svTexture;
|
||||
}
|
||||
|
||||
private void CreateOutputImage()
|
||||
{
|
||||
outputTexture = new Texture2D(1, 16);
|
||||
outputTexture.wrapMode = TextureWrapMode.Clamp;
|
||||
outputTexture.name = "OutputTexture";
|
||||
|
||||
Color currentColor = Color.HSVToRGB(currentHue, currentSat, currentVal);
|
||||
|
||||
for (int i = 0; i < hueTexture.height; i++)
|
||||
{
|
||||
outputTexture.SetPixel(0, 1, currentColor);
|
||||
}
|
||||
|
||||
outputTexture.Apply();
|
||||
|
||||
currentHue = 0;
|
||||
outputImage.texture = outputTexture;
|
||||
}
|
||||
|
||||
private void UpdateOutputImage()
|
||||
{
|
||||
Color currentColor = Color.HSVToRGB(currentHue, currentSat, currentVal);
|
||||
|
||||
for (int i = 0; i < outputTexture.height; i++)
|
||||
{
|
||||
outputTexture.SetPixel(0, i, currentColor);
|
||||
}
|
||||
|
||||
//Updating RBG Input
|
||||
inputR.text = ((int)(currentColor.r * 255f)).ToString();
|
||||
inputG.text = ((int)(currentColor.g * 255f)).ToString();
|
||||
inputB.text = ((int)(currentColor.b * 255f)).ToString();
|
||||
|
||||
//Updating HSV Input
|
||||
inputH.text = (currentHue.ToString("F2"));
|
||||
inputS.text = (currentSat.ToString("F2"));
|
||||
inputV.text = (currentVal.ToString("F2"));
|
||||
|
||||
//Updating Hex Input
|
||||
string hexRGB = ColorUtility.ToHtmlStringRGB(currentColor);
|
||||
hexValueTex.text = "#" + hexRGB;
|
||||
|
||||
|
||||
outputTexture.Apply();
|
||||
|
||||
if (!colorObject) return;
|
||||
|
||||
Swatch.color = currentColor;
|
||||
SetColor(currentColor, currentChannel);
|
||||
channelText.color = new Color( 1 - currentVal, 1 - currentVal, 1 - currentVal, 1);
|
||||
|
||||
svContoller.setPickerPosition(currentSat, currentVal);
|
||||
}
|
||||
|
||||
public void SetSV(float S, float V)
|
||||
{
|
||||
currentSat = S;
|
||||
currentVal = V;
|
||||
UpdateOutputImage();
|
||||
}
|
||||
|
||||
public void SetHSV(float H, float S, float V)
|
||||
{
|
||||
currentHue = H;
|
||||
currentSat = S;
|
||||
currentVal = V;
|
||||
UpdateOutputImage();
|
||||
}
|
||||
|
||||
public void SetHSV()
|
||||
{
|
||||
float.TryParse(inputH.text, out currentHue);
|
||||
float.TryParse(inputS.text, out currentSat);
|
||||
float.TryParse(inputV.text, out currentVal);
|
||||
UpdateOutputImage();
|
||||
}
|
||||
|
||||
public void SetRGB()
|
||||
{
|
||||
byte r = 0;
|
||||
byte.TryParse(inputR.text, out r);
|
||||
byte g = 0;
|
||||
byte.TryParse(inputG.text, out g);
|
||||
byte b = 0;
|
||||
byte.TryParse(inputB.text, out b);
|
||||
|
||||
var color = new Color32(r,g,b, 255);
|
||||
Color.RGBToHSV(color, out float h, out float s, out float v);
|
||||
SetHSV(h, s, v);
|
||||
}
|
||||
|
||||
|
||||
public void UpdateSVImage()
|
||||
{
|
||||
currentHue = hueSlider.value;
|
||||
|
||||
for (int y = 0; y < svTexture.height; y++)
|
||||
{
|
||||
for (int x = 0; x < svTexture.width; x++)
|
||||
{
|
||||
svTexture.SetPixel(x, y, Color.HSVToRGB(currentHue, (float)x / svTexture.width, (float)y / svTexture.height));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
svTexture.Apply();
|
||||
UpdateOutputImage();
|
||||
}
|
||||
|
||||
private void SetColor(Color color, int channel)
|
||||
{
|
||||
switch (mode)
|
||||
{
|
||||
case TextureType.Base:
|
||||
colorObject.SetColor(color, channel);
|
||||
break;
|
||||
case TextureType.Decal:
|
||||
maxChannel = 3;
|
||||
colorObject.SetDecalColor(color, channel);
|
||||
break;
|
||||
case TextureType.Pattern:
|
||||
maxChannel = 3;
|
||||
colorObject.SetPatternColor(color, channel);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeSwatch(int value)
|
||||
{
|
||||
currentChannel += value;
|
||||
|
||||
if(currentChannel > maxChannel) { currentChannel = 1; }
|
||||
if(currentChannel < 1) { currentChannel = maxChannel; };
|
||||
|
||||
Color swatchColor = Color.black;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case TextureType.Base:
|
||||
swatchColor = colorObject.GetColor(currentChannel);
|
||||
break;
|
||||
case TextureType.Decal:
|
||||
swatchColor = colorObject.GetDecalColor(currentChannel);
|
||||
break;
|
||||
case TextureType.Pattern:
|
||||
swatchColor = colorObject.GetPatternColor(currentChannel);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Swatch.color = swatchColor;
|
||||
|
||||
SetChannelName();
|
||||
|
||||
Color.RGBToHSV(swatchColor, out float h, out float s, out float v);
|
||||
hueSlider.value = h;
|
||||
SetHSV(h, s, v);
|
||||
UpdateSVImage();
|
||||
}
|
||||
|
||||
public void ChangeObject(OutfitBase ob)
|
||||
{
|
||||
if (!ob) {RemoveObject(); return; }
|
||||
var colorOutfit = ob.GetComponent<Outfit>();
|
||||
|
||||
//Keeping color of previous Outfit if turned on and type is the same
|
||||
if (maintainColors && !colorOutfit.customShader && colorObject != null)
|
||||
{
|
||||
HeldColors = colorObject.GetColors();
|
||||
if(colorOutfit.Type == outfitType)
|
||||
{
|
||||
for (int i = 0; i < HeldColors.Count; i++)
|
||||
{
|
||||
colorOutfit.SetColor(HeldColors[i], i + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//initalizing values
|
||||
channelNames = new string[] { "Base" };
|
||||
outfitType = colorOutfit.Type;
|
||||
mode = TextureType.Base;
|
||||
colorObject = ob;
|
||||
|
||||
//RememberSettings
|
||||
if (!outfitPickerSettings.ContainsKey(colorOutfit.Type))
|
||||
{
|
||||
var newSettings = new OutfitPickerSettings();
|
||||
outfitPickerSettings.Add(colorOutfit.Type, newSettings);
|
||||
|
||||
}
|
||||
var settings = outfitPickerSettings[colorOutfit.Type];
|
||||
SetMaintainColors(settings.maintainColors);
|
||||
SetCopyIndex(settings.copyIndex);
|
||||
|
||||
//Custom Shaders
|
||||
if(colorObject.customShader == true)
|
||||
{
|
||||
decalContainer.SetActive(false);
|
||||
patternContainer.SetActive(false);
|
||||
swatchParentContainer.SetActive(true);
|
||||
maxChannel = 1;
|
||||
|
||||
foreach (var item in swatchSelectors)
|
||||
{
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
swatchSelectors.Clear();
|
||||
for (int i = 0; i < colorOutfit.outfitSwatches.Count; i++)
|
||||
{
|
||||
var swatch = Instantiate(swatchSelectorObject, swatchContainer);
|
||||
swatch.Init(this, colorOutfit.outfitSwatches[i], i);
|
||||
swatchSelectors.Add(swatch);
|
||||
}
|
||||
|
||||
}
|
||||
//BoZo_Toon Shader
|
||||
else
|
||||
{
|
||||
var color = colorObject.GetColor(1);
|
||||
color.a = 1;
|
||||
currentChannel = 1;
|
||||
Swatch.color = color;
|
||||
decalContainer.SetActive(true);
|
||||
patternContainer.SetActive(true);
|
||||
channelNames = colorOutfit.ColorChannels;
|
||||
|
||||
if (colorOutfit)
|
||||
{
|
||||
maxChannel = colorOutfit.ColorChannels.Length;
|
||||
if (!colorOutfit.supportDecals) decalContainer.SetActive(false);
|
||||
if (!colorOutfit.supportPatterns) patternContainer.SetActive(false);
|
||||
swatchParentContainer.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
maxChannel = 9;
|
||||
}
|
||||
|
||||
|
||||
|
||||
var decalSize = colorObject.GetDecalSize();
|
||||
DecalXSlider.value = decalSize.x;
|
||||
DecalYSlider.value = decalSize.y;
|
||||
|
||||
var patternSize = colorObject.GetPatternSize();
|
||||
patternXSlider.value = patternSize.x;
|
||||
patternYSlider.value = patternSize.y;
|
||||
}
|
||||
|
||||
SetChannelName();
|
||||
|
||||
ChangeSwatch(0);
|
||||
objectName.text = colorObject.name.Replace("(Clone)", "");
|
||||
|
||||
if (colorObject == null) gameObject.SetActive(false);
|
||||
else gameObject.SetActive(true);
|
||||
|
||||
}
|
||||
|
||||
public void SetDecalSize()
|
||||
{
|
||||
var scale = new Vector2(DecalXSlider.value, DecalYSlider.value);
|
||||
colorObject.SetDecalSize(scale);
|
||||
}
|
||||
|
||||
public void SetPatternSize()
|
||||
{
|
||||
var scale = new Vector2(patternXSlider.value, patternYSlider.value);
|
||||
colorObject.SetPatternSize(scale);
|
||||
}
|
||||
|
||||
public void RemoveObject()
|
||||
{
|
||||
colorObject = null;
|
||||
SetMaintainColors(false);
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void SetBaseTexture(int textureIndex)
|
||||
{
|
||||
var outfit = colorObject.GetComponent<Outfit>();
|
||||
outfit.SetSwatch(textureIndex);
|
||||
}
|
||||
|
||||
public void SwitchMode(string mode)
|
||||
{
|
||||
var type = (TextureType)Enum.Parse(typeof(TextureType), mode);
|
||||
this.mode = type;
|
||||
|
||||
switch (this.mode)
|
||||
{
|
||||
case TextureType.Base:
|
||||
ChangeObject(colorObject);
|
||||
break;
|
||||
case TextureType.Decal:
|
||||
maxChannel = 3;
|
||||
channelText.text = "1/" + maxChannel;
|
||||
|
||||
var decal = colorObject.GetDecalColor(1);
|
||||
decal.a = 1;
|
||||
currentChannel = 1;
|
||||
Swatch.color = decal;
|
||||
break;
|
||||
case TextureType.Pattern:
|
||||
maxChannel = 3;
|
||||
channelText.text = "1/" + maxChannel;
|
||||
|
||||
var pattern = colorObject.GetPatternColor(1);
|
||||
pattern.a = 1;
|
||||
currentChannel = 1;
|
||||
Swatch.color = pattern;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void ChangeCopyIndex(int value)
|
||||
{
|
||||
copyIndex += value;
|
||||
if(copyIndex > outfitTypes.Count - 1)
|
||||
{
|
||||
copyIndex = 0;
|
||||
}
|
||||
else if (copyIndex < 0)
|
||||
{
|
||||
copyIndex = outfitTypes.Count - 1;
|
||||
}
|
||||
CopyCatagoryText.text = outfitTypes[copyIndex];
|
||||
if(outfitType != null)
|
||||
{
|
||||
outfitPickerSettings[outfitType].copyIndex = copyIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetCopyIndex(int value)
|
||||
{
|
||||
copyIndex = value;
|
||||
CopyCatagoryText.text = outfitTypes[copyIndex];
|
||||
outfitPickerSettings[outfitType].copyIndex = copyIndex;
|
||||
}
|
||||
|
||||
public void CopyColor(OutfitBase copyOutfit)
|
||||
{
|
||||
var from = colorObject;
|
||||
var to = copyOutfit;
|
||||
|
||||
for (int i = 1; i < 9; i++)
|
||||
{
|
||||
to.SetColor(from.GetColor(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyColor()
|
||||
{
|
||||
var from = colorObject;
|
||||
var to = outfitSystem.GetOutfit(CopyCatagoryText.text);
|
||||
|
||||
if (to == null) return;
|
||||
|
||||
for (int i = 1; i < 9; i++)
|
||||
{
|
||||
to.SetColor(from.GetColor(i), i);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetColorByHex(string hex)
|
||||
{
|
||||
if (hex[0].ToString() != "#")
|
||||
{
|
||||
hex = "#" + hex;
|
||||
}
|
||||
|
||||
if (ColorUtility.TryParseHtmlString(hex, out Color hexColor))
|
||||
{
|
||||
print(hexColor);
|
||||
Color.RGBToHSV(hexColor, out float h, out float s, out float v);
|
||||
SetHSV(h, s, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("Invalid hex string!");
|
||||
}
|
||||
}
|
||||
|
||||
public void CopyHex()
|
||||
{
|
||||
GUIUtility.systemCopyBuffer = hexValueTex.text;
|
||||
print("Copied HEX to Clipboard: " + hexValueTex.text);
|
||||
}
|
||||
|
||||
public void SetChannelName()
|
||||
{
|
||||
var channelName = "";
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case TextureType.Base:
|
||||
if (colorObject.customShader) break;
|
||||
if (currentChannel - 1 < channelNames.Length)
|
||||
{
|
||||
channelName = channelNames[currentChannel - 1];
|
||||
}
|
||||
break;
|
||||
case TextureType.Decal:
|
||||
channelName = "Decal";
|
||||
break;
|
||||
case TextureType.Pattern:
|
||||
channelName = "Pattern";
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
channelText.text = channelName + " " + currentChannel + "/" + maxChannel;
|
||||
}
|
||||
|
||||
public void SetMaintainColors(bool value)
|
||||
{
|
||||
if (value && colorObject != null)
|
||||
{
|
||||
HeldColors = colorObject.GetColors();
|
||||
}
|
||||
maintainColors = value;
|
||||
maintainColorsToggle.isOn = maintainColors;
|
||||
if(outfitType != null)
|
||||
{
|
||||
outfitPickerSettings[outfitType].maintainColors = maintainColors;
|
||||
}
|
||||
}
|
||||
|
||||
private class OutfitPickerSettings
|
||||
{
|
||||
public bool maintainColors = false;
|
||||
public int copyIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6ad41dc542643ad4994079a3430133a5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/ColorPickerControl.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class BlendSlider : MonoBehaviour
|
||||
{
|
||||
Slider slider;
|
||||
[SerializeField] TMP_Text title;
|
||||
[SerializeField] TMP_Text sliderValue;
|
||||
|
||||
[SerializeField] OutfitSystem system;
|
||||
[SerializeField] string shape;
|
||||
|
||||
public void Init(OutfitSystem system, string key)
|
||||
{
|
||||
slider = GetComponentInChildren<Slider>();
|
||||
slider.onValueChanged.AddListener(Apply);
|
||||
|
||||
this.system = system;
|
||||
title.text = key;
|
||||
shape = key;
|
||||
var weight = system.GetShapeValue(key);
|
||||
slider.value = weight;
|
||||
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
var weight = system.GetShapeValue(shape);
|
||||
slider.value = weight;
|
||||
}
|
||||
|
||||
private void UpdateSlider()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Apply(float value)
|
||||
{
|
||||
system.SetShape(shape, value);
|
||||
sliderValue.text = $"{slider.value}%";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf57ed88aed245749b3cc66844288e5b
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/Creator_BlendSlider.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bb9f28d735f4309419c417b04ef28c30
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
[CustomEditor(typeof(CharacterObject))]
|
||||
public class CharacterEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
CharacterObject myObj = (CharacterObject)target;
|
||||
serializedObject.Update();
|
||||
float size = 128f;
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("icon"));
|
||||
|
||||
if (myObj.icon != null)
|
||||
{
|
||||
|
||||
// Define a clean Unity-style frame using GUIStyle
|
||||
GUIStyle frameStyle = new GUIStyle(GUI.skin.box);
|
||||
|
||||
frameStyle.padding = new RectOffset(10, 10, 10, 10);
|
||||
frameStyle.margin = new RectOffset(5, 5, 5, 5);
|
||||
frameStyle.margin = new RectOffset(5, 5, 5, 5);
|
||||
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
Rect previewRect = GUILayoutUtility.GetRect(size, size, GUILayout.ExpandWidth(true));
|
||||
EditorGUI.DrawPreviewTexture(previewRect, myObj.icon, null, ScaleMode.ScaleToFit);
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("data"));
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03ad0fb1979a42547bfd21ad94bb5ffb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/Editor/CharacterEditor.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
[CustomEditor(typeof(IconCapture))]
|
||||
public class IconCaptureEditor : Editor
|
||||
{
|
||||
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
IconCapture icon = (IconCapture)target;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Take ScreenShot"))
|
||||
{
|
||||
icon.Capture();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f87dc63653e81464eb2154dd1728e834
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/Editor/IconCaptureEditor.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,31 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
[CustomEditor(typeof(TextureBaker))]
|
||||
public class TextureBakerEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
base.OnInspectorGUI();
|
||||
|
||||
TextureBaker baker = (TextureBaker)target;
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if(GUILayout.Button("Export Outfit"))
|
||||
{
|
||||
baker.ExportOutfit();
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Create Swatch"))
|
||||
{
|
||||
baker.CreateSwatch();
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6fcb6ec024ec6474a93423073e9f2f71
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/Editor/TextureBakerEditor.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,41 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class ExpressionSelect : MonoBehaviour
|
||||
{
|
||||
public OutfitSystem outfitSystem;
|
||||
public Animator animator;
|
||||
|
||||
public string parameterID;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
outfitSystem.OnOutfitChanged += GetHead;
|
||||
}
|
||||
|
||||
private void GetHead(Outfit outfit)
|
||||
{
|
||||
var head = outfitSystem.GetOutfit("Head");
|
||||
if (head) animator = head.GetComponentInChildren<Animator>();
|
||||
else animator = outfitSystem.animator;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
outfitSystem.OnOutfitChanged -= GetHead;
|
||||
}
|
||||
|
||||
public void SetExpression(float value)
|
||||
{
|
||||
if(animator == null)
|
||||
{
|
||||
var head = outfitSystem.GetOutfit("Head");
|
||||
if (head) animator = head.GetComponentInChildren<Animator>();
|
||||
else animator = outfitSystem.animator;
|
||||
}
|
||||
|
||||
animator.SetFloat(parameterID, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57776f57f2fa13549ab17323a6064af0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/ExpressionSelect.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,161 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class IconCapture : MonoBehaviour
|
||||
{
|
||||
[SerializeField] RenderTexture iconTexture;
|
||||
[SerializeField] Camera iconCamera;
|
||||
[SerializeField] Transform parent;
|
||||
[SerializeField] string path = "BoZo_ModularAnimeCharacters/Textures/OutfitIcons";
|
||||
|
||||
[SerializeField] GameObject BackingBody;
|
||||
[SerializeField] GameObject BackingHead;
|
||||
[SerializeField] List<Outfit> outfits = new List<Outfit>();
|
||||
[SerializeField] Color[] Colors;
|
||||
|
||||
private Camera activeCam;
|
||||
[SerializeField] IconCaptureSettings[] cameraSettings;
|
||||
[SerializeField] Dictionary<OutfitType, IconCaptureSettings> cameras = new Dictionary<OutfitType, IconCaptureSettings>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
foreach (var item in cameraSettings)
|
||||
{
|
||||
cameras.Add(item.type, item);
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("Capture")]
|
||||
public void Capture()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
StartCoroutine(CaptureCoroutine());
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Capture(GameObject gameObject)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
outfits.Clear();
|
||||
var outfit = gameObject.GetComponent<Outfit>();
|
||||
if (outfit == null) return;
|
||||
|
||||
path = AssetDatabase.GetAssetPath(gameObject.gameObject);
|
||||
path = path.Replace(gameObject.name + ".prefab", "");
|
||||
path = path.Replace("Assets", "");
|
||||
|
||||
outfits.Add(outfit);
|
||||
|
||||
StartCoroutine(CaptureCoroutine());
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private IEnumerator CaptureCoroutine()
|
||||
{
|
||||
|
||||
if(outfits.Count == 0)
|
||||
{
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
RenderTexture.active = iconTexture;
|
||||
|
||||
Texture2D icon = new Texture2D(iconTexture.width, iconTexture.height, TextureFormat.RGBA32, false);
|
||||
Rect rect = new Rect(new Rect(0, 0, iconTexture.width, iconTexture.height));
|
||||
icon.ReadPixels(rect, 0, 0);
|
||||
icon.Apply();
|
||||
|
||||
byte[] bytes = icon.EncodeToPNG();
|
||||
System.IO.File.WriteAllBytes(Application.dataPath + "/" + path + "/" + "ICON" + ".png", bytes);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
TextureImporter importer = AssetImporter.GetAtPath("Assets/" + path + "/" + "ICON" + ".png") as TextureImporter;
|
||||
|
||||
|
||||
if (importer != null)
|
||||
{
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.spriteImportMode = SpriteImportMode.Single;
|
||||
importer.SaveAndReimport();
|
||||
}
|
||||
|
||||
yield return null;
|
||||
}
|
||||
|
||||
foreach (var item in outfits)
|
||||
{
|
||||
//Match the camera to the outfit
|
||||
if (activeCam != null) activeCam.gameObject.SetActive(false);
|
||||
activeCam = cameras[item.Type].camera;
|
||||
activeCam.gameObject.SetActive(true);
|
||||
|
||||
BackingBody.SetActive(cameras[item.Type].showBody);
|
||||
BackingHead.SetActive(cameras[item.Type].showHead);
|
||||
|
||||
|
||||
var outfit = Instantiate(item, parent);
|
||||
if (!outfit.customShader)
|
||||
{
|
||||
for (int i = 0; i < Colors.Length; i++)
|
||||
{
|
||||
outfit.SetColor(Colors[i], i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
activeCam.Render();
|
||||
yield return new WaitForEndOfFrame();
|
||||
|
||||
RenderTexture.active = iconTexture;
|
||||
|
||||
Texture2D icon = new Texture2D(iconTexture.width, iconTexture.height, TextureFormat.RGBA32, false);
|
||||
Rect rect = new Rect(new Rect(0, 0, iconTexture.width, iconTexture.height));
|
||||
icon.ReadPixels(rect, 0, 0);
|
||||
icon.Apply();
|
||||
|
||||
byte[] bytes = icon.EncodeToPNG();
|
||||
|
||||
System.IO.File.WriteAllBytes(Application.dataPath + "/" + path + "/" + item.name + ".png", bytes);
|
||||
AssetDatabase.Refresh();
|
||||
print("IconCreated: " + Application.dataPath + "/" + path + "/" + item.name + ".png");
|
||||
|
||||
TextureImporter importer = AssetImporter.GetAtPath("Assets/" + path + "/" + item.name + ".png") as TextureImporter;
|
||||
|
||||
Destroy(outfit.gameObject);
|
||||
|
||||
if (importer != null)
|
||||
{
|
||||
importer.textureType = TextureImporterType.Sprite;
|
||||
importer.spriteImportMode = SpriteImportMode.Single;
|
||||
importer.SaveAndReimport();
|
||||
}
|
||||
|
||||
if (outfit)
|
||||
{
|
||||
var spritrIcon = AssetDatabase.LoadAssetAtPath<Sprite>("Assets/" + path + "/" + item.name + ".png");
|
||||
item.OutfitIcon = spritrIcon;
|
||||
EditorUtility.SetDirty(item);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
if (activeCam != null) activeCam.gameObject.SetActive(false);
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
[System.Serializable]
|
||||
public class IconCaptureSettings
|
||||
{
|
||||
public OutfitType type;
|
||||
public Camera camera;
|
||||
public bool showHead = true;
|
||||
public bool showBody = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4e147bfe656788040a25848b79cbab1f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/IconCapture.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,94 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
|
||||
public class SVImageControl : MonoBehaviour, IDragHandler, IPointerClickHandler
|
||||
{
|
||||
[SerializeField] Image PickerImage;
|
||||
|
||||
private RawImage SVImage;
|
||||
|
||||
private ColorPickerControl CC;
|
||||
private RectTransform rect;
|
||||
private RectTransform pickerTransform;
|
||||
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
SVImage = GetComponent<RawImage>();
|
||||
CC = FindFirstObjectByType<ColorPickerControl>();
|
||||
rect = GetComponent<RectTransform>();
|
||||
pickerTransform = PickerImage.GetComponent<RectTransform>();
|
||||
|
||||
pickerTransform = PickerImage.GetComponent<RectTransform>();
|
||||
pickerTransform.position = new Vector2(-(rect.sizeDelta.x * 0.5f), -(rect.sizeDelta.y * 0.5f));
|
||||
}
|
||||
|
||||
private void UpdateColor(PointerEventData eventData)
|
||||
{
|
||||
Vector3 pos = rect.InverseTransformPoint(eventData.position);
|
||||
|
||||
float deltaX = rect.sizeDelta.x * 0.5f;
|
||||
float deltaY = rect.sizeDelta.y * 0.5f;
|
||||
|
||||
if (pos.x < -deltaX)
|
||||
{
|
||||
pos.x = -deltaX;
|
||||
}
|
||||
if (pos.x > deltaX)
|
||||
{
|
||||
pos.x = deltaX;
|
||||
}
|
||||
if (pos.y < -deltaY)
|
||||
{
|
||||
pos.y = -deltaY;
|
||||
}
|
||||
if (pos.y > deltaY)
|
||||
{
|
||||
pos.y = deltaY;
|
||||
}
|
||||
|
||||
float x = pos.x + deltaX;
|
||||
float y = pos.y + deltaY;
|
||||
|
||||
float xNorm = x / rect.sizeDelta.x;
|
||||
float YNorm = y / rect.sizeDelta.y;
|
||||
|
||||
//pickerTransform.localPosition = pos;
|
||||
|
||||
PickerImage.color = Color.HSVToRGB(0, 0, 1 - YNorm);
|
||||
|
||||
CC.SetSV(xNorm, YNorm);
|
||||
|
||||
}
|
||||
|
||||
public void setPickerPosition(float x, float y)
|
||||
{
|
||||
if(!rect) rect = GetComponent<RectTransform>();
|
||||
if(!pickerTransform) pickerTransform = PickerImage.GetComponent<RectTransform>();
|
||||
|
||||
var xPos = Mathf.Lerp(-rect.sizeDelta.x / 2, rect.sizeDelta.x/ 2, x);
|
||||
var yPos = Mathf.Lerp(-rect.sizeDelta.y / 2, rect.sizeDelta.y / 2, y);
|
||||
|
||||
var pos = new Vector2(xPos, yPos);
|
||||
|
||||
pickerTransform.localPosition = pos;
|
||||
}
|
||||
|
||||
public void OnDrag(PointerEventData eventData)
|
||||
{
|
||||
UpdateColor(eventData);
|
||||
}
|
||||
|
||||
public void OnPointerClick(PointerEventData eventData)
|
||||
{
|
||||
UpdateColor(eventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ed18d41614dff814fa3781f04180cd92
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/SVImageControl.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class SaveSelector : MonoBehaviour
|
||||
{
|
||||
public Image icon;
|
||||
private CharacterData data;
|
||||
private CharacterCreator characterCreator;
|
||||
private Button button;
|
||||
public void Init(CharacterData characterData, Sprite icon, CharacterCreator characterCreator)
|
||||
{
|
||||
button = GetComponentInChildren<Button>();
|
||||
button.onClick.AddListener(OnSelect);
|
||||
|
||||
this.data = characterData;
|
||||
this.characterCreator = characterCreator;
|
||||
this.icon.overrideSprite = icon;
|
||||
}
|
||||
|
||||
private void OnSelect()
|
||||
{
|
||||
characterCreator.LoadCharacter(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76c84ed6450e2b142b4db815c7ddb7a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/SaveSelector.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,28 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class SwatchSelector : MonoBehaviour
|
||||
{
|
||||
ColorPickerControl picker;
|
||||
public int swatchIndex;
|
||||
//these are for setting the swatch icon colors
|
||||
public Image color1;
|
||||
public Image color2;
|
||||
|
||||
public void Init(ColorPickerControl colorPickerControl, OutfitSwatch swatchData, int swatchIndex)
|
||||
{
|
||||
picker = colorPickerControl;
|
||||
this.swatchIndex = swatchIndex;
|
||||
color1.color = swatchData.IconColorTop;
|
||||
color2.color = swatchData.IconColorBottom;
|
||||
}
|
||||
|
||||
public void SetSwatch()
|
||||
{
|
||||
picker.SetBaseTexture(swatchIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a233887b31097fe4e8887eb7056865c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/SwatchSelector.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,337 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
|
||||
public class TextureBaker : MonoBehaviour
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
public CharacterCreator characterCreator;
|
||||
public Material BakeMaterial;
|
||||
public Material UserMaterial;
|
||||
public IconCapture IconCapture;
|
||||
|
||||
[Header("ExportSettings")]
|
||||
[SerializeField] string outfitName;
|
||||
[SerializeField] OutfitType OutfitToExport;
|
||||
[SerializeField] int textureDilation = 20;
|
||||
|
||||
private string savePath = Application.dataPath + "/BoZo_ModularAnimeCharacters/CustomOutfits/Resources";
|
||||
private string AssetPath = "Assets/BoZo_ModularAnimeCharacters/CustomOutfits/Resources";
|
||||
|
||||
[ContextMenu("ExportOutfit")]
|
||||
public void ExportOutfit()
|
||||
{
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Debug.LogWarning("Please Enter Play Mode to export an Outfit");
|
||||
return;
|
||||
}
|
||||
|
||||
if (outfitName.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("Please enter name for export");
|
||||
return;
|
||||
}
|
||||
|
||||
if (UserMaterial == null)
|
||||
{
|
||||
Debug.LogWarning("Material Empty please select a source material");
|
||||
return;
|
||||
}
|
||||
|
||||
if (OutfitToExport == null)
|
||||
{
|
||||
Debug.LogWarning("Empty OutfitType Please Provide an Outfit Type");
|
||||
return;
|
||||
}
|
||||
|
||||
var character = characterCreator.character;
|
||||
var sourceOutfit = character.GetOutfit(OutfitToExport);
|
||||
if (sourceOutfit == null)
|
||||
{
|
||||
Debug.LogWarning("Outfit is Null make sure outfit exists on character");
|
||||
return;
|
||||
}
|
||||
var cleanName = sourceOutfit.name;
|
||||
cleanName = cleanName.Replace("(Clone)", "");
|
||||
var NewOutfit = Instantiate(characterCreator.GetOutfit(cleanName));
|
||||
|
||||
|
||||
BakeOutfit(sourceOutfit, NewOutfit, outfitName);
|
||||
|
||||
}
|
||||
|
||||
public void CreateOutfit()
|
||||
{
|
||||
var character = characterCreator.character;
|
||||
var sourceOutfit = character.GetOutfit(OutfitToExport);
|
||||
if (sourceOutfit == null)
|
||||
{
|
||||
Debug.LogWarning("Outfit is Null make sure outfit exists on character");
|
||||
return;
|
||||
}
|
||||
var cleanName = sourceOutfit.name;
|
||||
cleanName = cleanName.Replace("(Clone)", "");
|
||||
var NewOutfit = Instantiate(characterCreator.GetOutfit(cleanName));
|
||||
|
||||
|
||||
BakeOutfit(sourceOutfit, NewOutfit, outfitName);
|
||||
}
|
||||
|
||||
public void BakeOutfit(Outfit sourceOutfit, Outfit newOutfit, string outfitName = "NewOutfit")
|
||||
{
|
||||
|
||||
Renderer renderer = newOutfit.GetComponentInChildren<Renderer>();
|
||||
var tex = CreateTexture(sourceOutfit, newOutfit);
|
||||
|
||||
//Create Save Path
|
||||
string folderPath = sourceOutfit.Type.name;
|
||||
|
||||
if (!AssetDatabase.IsValidFolder(AssetPath + "/" + folderPath))
|
||||
{
|
||||
AssetDatabase.CreateFolder(AssetPath, folderPath);
|
||||
}
|
||||
|
||||
// Save PNG
|
||||
byte[] bytes = tex.EncodeToPNG();
|
||||
System.IO.File.WriteAllBytes(savePath + "/" + folderPath + "/" + folderPath + "_" + outfitName + "_Swatch_1.png", bytes);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
//Save Asset
|
||||
|
||||
string path = AssetPath + "/" + folderPath + "/" + folderPath + "_" + outfitName;
|
||||
|
||||
Material newMaterial = new Material(UserMaterial);
|
||||
var newTex = AssetDatabase.LoadAssetAtPath<Texture2D>(path + "_Swatch_1.png");
|
||||
newMaterial.mainTexture = newTex;
|
||||
|
||||
AssetDatabase.CreateAsset(newMaterial, path + "_mat.mat");
|
||||
var newMat = AssetDatabase.LoadAssetAtPath<Material>(path + "_mat.mat");
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
newMat.mainTexture = newTex;
|
||||
renderer.material = newMat;
|
||||
|
||||
AssetDatabase.DeleteAsset(path + ".prefab");
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
var swatch = new OutfitSwatch();
|
||||
swatch.swatchID = folderPath + "/" + folderPath + "_" + outfitName + "_Swatch_" + 1;
|
||||
newOutfit.outfitSwatches.Add(swatch);
|
||||
newOutfit.customShader = true;
|
||||
|
||||
var savedPrefab = PrefabUtility.SaveAsPrefabAsset(newOutfit.gameObject, path + ".prefab");
|
||||
EditorUtility.SetDirty(savedPrefab);
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
Destroy(newOutfit.gameObject);
|
||||
IconCapture.Capture(savedPrefab);
|
||||
Debug.Log("Swatched Created: " + path);
|
||||
|
||||
}
|
||||
|
||||
[ContextMenu("CreateSwatch")]
|
||||
public void CreateSwatch()
|
||||
{
|
||||
|
||||
|
||||
if (!Application.isPlaying)
|
||||
{
|
||||
Debug.LogWarning("Please Enter Play Mode to create Swatch");
|
||||
return;
|
||||
}
|
||||
|
||||
if (outfitName.Length == 0)
|
||||
{
|
||||
Debug.LogWarning("Please enter name for export");
|
||||
return;
|
||||
}
|
||||
|
||||
var character = characterCreator.character;
|
||||
var sourceOutfit = character.GetOutfit(OutfitToExport);
|
||||
var cleanName = sourceOutfit.name;
|
||||
cleanName = cleanName.Replace("(Clone)", "");
|
||||
var newOutfit = Instantiate(characterCreator.GetOutfit(cleanName));
|
||||
|
||||
string folderPath = sourceOutfit.Type.name;
|
||||
string path = AssetPath + "/" + folderPath + "/" + folderPath + "_" + outfitName + ".prefab";
|
||||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(path);
|
||||
print(path);
|
||||
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogWarning("Custom Outfit does not exist. Please Use Export before creating swatches");
|
||||
Destroy(newOutfit.gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
int count = 1;
|
||||
string SwatchPath = savePath + "/" + folderPath + "/" + folderPath + "_" + outfitName + "_Swatch_" + count + ".png";
|
||||
|
||||
do
|
||||
{
|
||||
count++;
|
||||
SwatchPath = savePath + "/" + folderPath + "/" + folderPath + "_" + outfitName + "_Swatch_" + count + ".png";
|
||||
print(count);
|
||||
} while (System.IO.File.Exists(SwatchPath));
|
||||
|
||||
|
||||
var tex = CreateTexture(sourceOutfit, newOutfit);
|
||||
byte[] bytes = tex.EncodeToPNG();
|
||||
System.IO.File.WriteAllBytes(SwatchPath, bytes);
|
||||
|
||||
var outfit = prefab.GetComponent<Outfit>();
|
||||
var swatch = new OutfitSwatch();
|
||||
swatch.swatchID = folderPath + "/" + folderPath + "_" + outfitName + "_Swatch_" + count;
|
||||
outfit.outfitSwatches.Add(swatch);
|
||||
|
||||
|
||||
AssetDatabase.SaveAssets();
|
||||
AssetDatabase.Refresh();
|
||||
Destroy(newOutfit.gameObject);
|
||||
Debug.Log("Swatched Created: " + path);
|
||||
|
||||
}
|
||||
|
||||
Texture2D CreateTexture(Outfit sourceOutfit, Outfit newOutfit)
|
||||
{
|
||||
Mesh mesh = null;
|
||||
Renderer renderer = newOutfit.GetComponentInChildren<Renderer>();
|
||||
Material sourceMaterial = sourceOutfit.GetComponentInChildren<Renderer>().material;
|
||||
|
||||
if (renderer.TryGetComponent<MeshRenderer>(out MeshRenderer meshRenderer))
|
||||
{
|
||||
mesh = meshRenderer.GetComponent<MeshFilter>().sharedMesh;
|
||||
}
|
||||
else if (renderer.TryGetComponent<SkinnedMeshRenderer>(out SkinnedMeshRenderer skinnedMeshRenderer))
|
||||
{
|
||||
mesh = skinnedMeshRenderer.sharedMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
renderer.material = BakeMaterial;
|
||||
|
||||
Material material = renderer.material;
|
||||
|
||||
//Copy All Colors and Data To Bake Material
|
||||
material.mainTexture = sourceMaterial.mainTexture;
|
||||
material.SetTexture("_DecalMap", sourceMaterial.GetTexture("_DecalMap"));
|
||||
material.SetFloat("_DecalUVSet", sourceMaterial.GetFloat("_DecalUVSet"));
|
||||
material.SetFloat("_DecalBlend", sourceMaterial.GetFloat("_DecalBlend"));
|
||||
material.SetVector("_DecalScale", sourceMaterial.GetVector("_DecalScale"));
|
||||
|
||||
material.SetTexture("_PatternMap", sourceMaterial.GetTexture("_PatternMap"));
|
||||
material.SetFloat("_PatternUVSet", sourceMaterial.GetFloat("_PatternUVSet"));
|
||||
material.SetFloat("_PatternBlend", sourceMaterial.GetFloat("_PatternBlend"));
|
||||
material.SetVector("_PatternScale", sourceMaterial.GetVector("_PatternScale"));
|
||||
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
material.SetColor("_Color_" + (i + 1), sourceMaterial.GetColor("_Color_" + (i + 1)));
|
||||
material.SetColor("_Color_" + (i + 1), sourceMaterial.GetColor("_Color_" + (i + 1)));
|
||||
|
||||
if (i + 1 <= 3)
|
||||
{
|
||||
material.SetColor("_DecalColor_" + (i + 1), sourceMaterial.GetColor("_DecalColor_" + (i + 1)));
|
||||
material.SetColor("_PatternColor_" + (i + 1), sourceMaterial.GetColor("_PatternColor_" + (i + 1)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var textureSize = 2048;
|
||||
// Create RenderTexture
|
||||
RenderTexture rt = new RenderTexture(textureSize, textureSize, 0);
|
||||
rt.wrapMode = TextureWrapMode.Clamp;
|
||||
|
||||
// Create command buffer to render the mesh
|
||||
CommandBuffer cb = new CommandBuffer();
|
||||
cb.SetRenderTarget(rt);
|
||||
cb.ClearRenderTarget(true, true, Color.clear);
|
||||
|
||||
Matrix4x4 identity = Matrix4x4.identity;
|
||||
cb.DrawMesh(mesh, identity, material);
|
||||
|
||||
// Execute
|
||||
Graphics.ExecuteCommandBuffer(cb);
|
||||
cb.Release();
|
||||
|
||||
// Read pixels
|
||||
RenderTexture.active = rt;
|
||||
Texture2D tex = new Texture2D(textureSize, textureSize, TextureFormat.RGBA32, false);
|
||||
tex.ReadPixels(new Rect(0, 0, textureSize, textureSize), 0, 0);
|
||||
tex = DilateTexture(tex);
|
||||
tex.Apply();
|
||||
|
||||
RenderTexture.active = null;
|
||||
return tex;
|
||||
|
||||
}
|
||||
|
||||
Texture2D DilateTexture(Texture2D tex)
|
||||
{
|
||||
var iterations = textureDilation;
|
||||
int w = tex.width;
|
||||
int h = tex.height;
|
||||
|
||||
Color32[] pixels = tex.GetPixels32();
|
||||
Color32[] temp = new Color32[pixels.Length];
|
||||
|
||||
for (int it = 0; it < iterations; it++)
|
||||
{
|
||||
pixels.CopyTo(temp, 0);
|
||||
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
int idx = y * w + x;
|
||||
if (pixels[idx].a != 0) continue;
|
||||
|
||||
// Look around
|
||||
for (int dy = -1; dy <= 1; dy++)
|
||||
{
|
||||
for (int dx = -1; dx <= 1; dx++)
|
||||
{
|
||||
int nx = x + dx;
|
||||
int ny = y + dy;
|
||||
if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
|
||||
|
||||
int nIdx = ny * w + nx;
|
||||
if (pixels[nIdx].a != 0)
|
||||
{
|
||||
temp[idx] = pixels[nIdx];
|
||||
goto NextPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NextPixel:;
|
||||
}
|
||||
}
|
||||
|
||||
// Swap buffers
|
||||
Color32[] swap = pixels;
|
||||
pixels = temp;
|
||||
temp = swap;
|
||||
}
|
||||
|
||||
tex.SetPixels32(pixels);
|
||||
tex.Apply();
|
||||
return tex;
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85387e6ed0b4b7c44aa6a96bbdc3b578
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/TextureBaker.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public enum TextureType {Base, Decal, Pattern}
|
||||
public class TexturePackage : MonoBehaviour
|
||||
{
|
||||
public Texture texture;
|
||||
public Texture normalTexture;
|
||||
public Sprite icon;
|
||||
public TextureType type;
|
||||
public string catagory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ebda9b78a726204ca1dde4751c2a906
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/TexturePackage.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,48 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class TextureSelector : MonoBehaviour
|
||||
{
|
||||
public Image icon;
|
||||
private TexturePackage texture;
|
||||
private CharacterCreator characterCreator;
|
||||
private Button button;
|
||||
public void Init(TexturePackage texture, CharacterCreator characterCreator)
|
||||
{
|
||||
button = GetComponentInChildren<Button>();
|
||||
button.onClick.AddListener(OnSelect);
|
||||
|
||||
this.texture = texture;
|
||||
this.characterCreator = characterCreator;
|
||||
icon.overrideSprite = texture.icon;
|
||||
}
|
||||
|
||||
private void OnSelect()
|
||||
{
|
||||
if (texture.type == TextureType.Decal)
|
||||
{
|
||||
characterCreator.SetOutfitDecal(texture.texture);
|
||||
}
|
||||
if (texture.type == TextureType.Pattern)
|
||||
{
|
||||
characterCreator.SetOutfitPattern(texture.texture);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetVisable(string type)
|
||||
{
|
||||
if (texture.catagory == type)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ac4a46d3ea472c148948989f6e8cbb94
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/CharacterCreator/TextureSelector.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,12 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
[CreateAssetMenu(fileName = "BMAC_CharacterObject", menuName = "BoZo/BMAC_CharacterObject")]
|
||||
public class CharacterObject : ScriptableObject
|
||||
{
|
||||
public Texture2D icon;
|
||||
public CharacterData data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3673d1a705285cd45860e82c86312ef5
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f295e7c04f9304f4895df55a24957a5a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
[CustomEditor(typeof(Outfit))]
|
||||
[CanEditMultipleObjects]
|
||||
public class OutfitEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
Outfit outfit = (Outfit)target;
|
||||
Color originalColor = GUI.color;
|
||||
GUIStyle frameStyle = new GUIStyle(GUI.skin.box);
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
|
||||
EditorGUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Character Creator Settings");
|
||||
GUILayout.BeginVertical(frameStyle);
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
GUILayout.BeginVertical(frameStyle);
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("OutfitName"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("OutfitIcon"));
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("ColorChannels"));
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("TextureCatagory"));
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
|
||||
var decalsupport = serializedObject.FindProperty("supportDecals");
|
||||
EditorGUILayout.LabelField("Supports Decal", GUILayout.Width(200));
|
||||
decalsupport.boolValue = EditorGUILayout.Toggle(decalsupport.boolValue);
|
||||
|
||||
var patternsupport = serializedObject.FindProperty("supportPatterns");
|
||||
EditorGUILayout.LabelField("Supports Pattern", GUILayout.Width(200));
|
||||
patternsupport.boolValue = EditorGUILayout.Toggle(patternsupport.boolValue);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
EditorGUILayout.LabelField("Available In Character Creator", GUILayout.Width(200));
|
||||
|
||||
EditorGUILayout.Space(20);
|
||||
|
||||
var buttonText = "";
|
||||
if (outfit.showCharacterCreator)
|
||||
{
|
||||
buttonText = "(Available)";
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.yellow;
|
||||
buttonText = "(Hidden)";
|
||||
}
|
||||
|
||||
if (GUILayout.Button(buttonText))
|
||||
{
|
||||
outfit.showCharacterCreator = !outfit.showCharacterCreator;
|
||||
}
|
||||
|
||||
GUI.color = originalColor;
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
if (outfit.OutfitIcon != null)
|
||||
{
|
||||
|
||||
// Control the size of the image
|
||||
float size = 128;
|
||||
Rect rect = GUILayoutUtility.GetRect(size, size, GUILayout.ExpandWidth(false));
|
||||
EditorGUI.DrawTextureTransparent(rect, outfit.OutfitIcon.texture);
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Outfit Settings");
|
||||
GUILayout.BeginVertical(frameStyle);
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("Type"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("AttachPoint"));
|
||||
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
|
||||
var customShader = serializedObject.FindProperty("customShader");
|
||||
EditorGUILayout.LabelField("Uses Custom Shader", GUILayout.Width(200));
|
||||
customShader.boolValue = EditorGUILayout.Toggle(customShader.boolValue);
|
||||
|
||||
var attachEditMode = serializedObject.FindProperty("AttachInEditMode");
|
||||
EditorGUILayout.LabelField("Follow Skeleton In Edit Mode", GUILayout.Width(200));
|
||||
attachEditMode.boolValue = EditorGUILayout.Toggle(attachEditMode.boolValue);
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("defaultColors"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("tags"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("LinkedColorSets"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("IncompatibleSets"));
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
EditorGUILayout.Space(20);
|
||||
|
||||
GUILayout.Label("Custom Settings");
|
||||
GUILayout.BeginVertical(frameStyle);
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("currentSwatch"));
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("outfitSwatches"));
|
||||
EditorGUI.indentLevel--;
|
||||
GUILayout.EndVertical();
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
|
||||
//base.OnInspectorGUI();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f3ec7e868ad30a4f991d95602aa2a40
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/Editor/OutfitEditor.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,167 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
[CustomEditor(typeof(OutfitSystem))]
|
||||
public class OutfitSystemEditor : Editor
|
||||
{
|
||||
private bool showMergedOptions;
|
||||
private bool dependencies;
|
||||
private Texture2D banner;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
banner = AssetDatabase.LoadAssetAtPath<Texture2D>("Assets/Bozo_ModularAnimeCharacters/Textures/Editor/Banner_OutfitSystem.png");
|
||||
}
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
OutfitSystem system = (OutfitSystem)target;
|
||||
Color originalColor = GUI.color;
|
||||
|
||||
|
||||
GUIStyle frameStyle = new GUIStyle(GUI.skin.box);
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
if (banner != null)
|
||||
{
|
||||
float maxWidth = EditorGUIUtility.currentViewWidth - 20;
|
||||
float aspect = (float)banner.width / banner.height;
|
||||
float desiredWidth = Mathf.Min(banner.width, maxWidth);
|
||||
float height = desiredWidth / aspect;
|
||||
|
||||
// Center it using flexible space
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label(banner, GUILayout.Width(desiredWidth), GUILayout.Height(height));
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("characterData"));
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("SaveID"));
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("loadMode"), GUILayout.ExpandWidth(true));
|
||||
|
||||
var async = serializedObject.FindProperty("async");
|
||||
EditorGUILayout.LabelField("Async", GUILayout.Width(50));
|
||||
async.boolValue = EditorGUILayout.Toggle(async.boolValue, GUILayout.Width(50));
|
||||
|
||||
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button("Save Character ID"))
|
||||
{
|
||||
system.SaveByID();
|
||||
}
|
||||
if (GUILayout.Button("Load Character ID"))
|
||||
{
|
||||
system.LoadFromID();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
if (system.characterData)
|
||||
{
|
||||
if (system.characterData.icon != null)
|
||||
{
|
||||
|
||||
// Control the size of the image
|
||||
float size = 64;
|
||||
Rect rect = GUILayoutUtility.GetRect(size, size, GUILayout.ExpandWidth(false));
|
||||
EditorGUI.DrawTextureTransparent(rect, system.characterData.icon);
|
||||
}
|
||||
}
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
|
||||
GUIContent mergedTooltip = new GUIContent("(Merged Mode)", "");
|
||||
GUIContent dyanmicTooltip = new GUIContent("(Dynamic Mode)", "");
|
||||
if (system.mergedMode)
|
||||
{
|
||||
GUI.color = Color.green;
|
||||
if (GUILayout.Button(mergedTooltip, GUILayout.Height(30)))
|
||||
{
|
||||
system.mergedMode = false;
|
||||
}
|
||||
GUI.color = originalColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.color = Color.yellow;
|
||||
if (GUILayout.Button(dyanmicTooltip, GUILayout.Height(30)))
|
||||
{
|
||||
system.mergedMode = true;
|
||||
}
|
||||
GUI.color = originalColor;
|
||||
}
|
||||
|
||||
|
||||
//MERGED OPTIONS
|
||||
showMergedOptions = EditorGUILayout.Foldout(showMergedOptions, "Merge Options", true);
|
||||
|
||||
GUILayout.BeginVertical(frameStyle);
|
||||
if (showMergedOptions)
|
||||
{
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("mergeMaterial"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("prefabName"));
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("materialData"));
|
||||
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("mergeOnAwake"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("autoUpdate"));
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
||||
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
|
||||
if (GUILayout.Button("Merge Character"))
|
||||
{
|
||||
system.MergeCharacter();
|
||||
}
|
||||
if (GUILayout.Button("Save as Prefab"))
|
||||
{
|
||||
system.SaveCharacterToPrefab();
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
GUILayout.EndVertical();
|
||||
|
||||
|
||||
|
||||
dependencies = EditorGUILayout.Foldout(dependencies, "Dependencies", true);
|
||||
if (dependencies)
|
||||
{
|
||||
GUILayout.BeginHorizontal(frameStyle);
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("CharacterBody"));
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
//base.OnInspectorGUI();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5460613c21ed8c41b9ed135d1a20b49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/Editor/OutfitSystemEditor.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d81242640599ff94faae802c597a0c6a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public interface IOutfitExtension
|
||||
{
|
||||
string GetID();
|
||||
void Initalize(OutfitSystem outfitSystem, Outfit outfit);
|
||||
void Execute(OutfitSystem outfitSystem, Outfit outfit);
|
||||
//Return Something from this object
|
||||
//Great when you have a Custom Map that you need read for the CharacterOptimizer
|
||||
object GetValue();
|
||||
System.Type GetValueType();
|
||||
}
|
||||
|
||||
public interface IOutfitExtension<T> : IOutfitExtension
|
||||
{
|
||||
//Return Something from this object
|
||||
//Great when you have a Custom Map that you need read for the CharacterOptimizer
|
||||
new T GetValue();
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95def551e1cef5f45bbb17fef6f038b1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/Interfaces/IOutfitExtension.cs
|
||||
uploadId: 853356
|
||||
470
Assets/04_Characters/_Shared/Models/BMAC/Scripts/Outfit.cs
Normal file
470
Assets/04_Characters/_Shared/Models/BMAC/Scripts/Outfit.cs
Normal file
@@ -0,0 +1,470 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class Outfit : OutfitBase
|
||||
{
|
||||
public bool Initalized { get; set; }
|
||||
[SerializeField] bool AttachInEditMode;
|
||||
|
||||
private OutfitSystem system;
|
||||
|
||||
//[Header("Character Creator Settings")]
|
||||
public string OutfitName;
|
||||
public Sprite OutfitIcon;
|
||||
public string[] ColorChannels = new string[] { "Base" };
|
||||
public string TextureCatagory;
|
||||
public bool supportDecals;
|
||||
public bool supportPatterns;
|
||||
public bool showCharacterCreator = true;
|
||||
|
||||
|
||||
public SkinnedMeshRenderer skinnedRenderer { get; private set; }
|
||||
public SkinnedMeshRenderer[] skinnedRenderers { get; private set; }
|
||||
public Renderer outfitRenderer { get; private set; }
|
||||
|
||||
//[field: Header("Outfit Settings")]
|
||||
[SerializeField] public OutfitType Type;
|
||||
public string AttachPoint;
|
||||
|
||||
public Color[] defaultColors;
|
||||
|
||||
public string[] tags;
|
||||
|
||||
private Dictionary<string, int> tagShapes = new Dictionary<string, int>();
|
||||
private Dictionary<string, int> shapes = new Dictionary<string, int>();
|
||||
public LinkedColorSets[] LinkedColorSets;
|
||||
public OutfitType[] IncompatibleSets;
|
||||
|
||||
//[Header("User Settings")]
|
||||
public int currentSwatch;
|
||||
public List<OutfitSwatch> outfitSwatches = new List<OutfitSwatch>();
|
||||
|
||||
public Transform[] originalBones;
|
||||
public Transform originalRootBone;
|
||||
public Transform editorAttachPoint;
|
||||
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (Application.isPlaying && gameObject.scene.isLoaded)
|
||||
{
|
||||
|
||||
if (system == null) system = GetComponentInParent<OutfitSystem>();
|
||||
SetColorInital();
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
if (AttachInEditMode && !Application.isPlaying) SoftAttach();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
|
||||
skinnedRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
if (skinnedRenderer) material = skinnedRenderer.material;
|
||||
skinnedRenderers = GetComponentsInChildren<SkinnedMeshRenderer>();
|
||||
outfitRenderer = GetComponentInChildren<Renderer>();
|
||||
|
||||
foreach (var smr in skinnedRenderers)
|
||||
{
|
||||
smr.sharedMaterial = material;
|
||||
}
|
||||
|
||||
InitSetUpShapes();
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (!Initalized) Attach();
|
||||
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
|
||||
if (!system) return;
|
||||
|
||||
system.OnOutfitChanged -= OnOutfitUpdate;
|
||||
system.OnShapeChanged -= SetShape;
|
||||
system.RemoveOutfit(this, false);
|
||||
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (!system) return;
|
||||
system.OnOutfitChanged -= OnOutfitUpdate;
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (Application.isPlaying && gameObject.scene.isLoaded)
|
||||
{
|
||||
if (!Initalized) Attach();
|
||||
}
|
||||
SetColorInital();
|
||||
}
|
||||
|
||||
public void Attach(Transform parent)
|
||||
{
|
||||
transform.parent = parent;
|
||||
Attach();
|
||||
}
|
||||
|
||||
public void Attach(OutfitSystem system)
|
||||
{
|
||||
transform.parent = system.transform;
|
||||
Attach();
|
||||
}
|
||||
|
||||
public void Attach()
|
||||
{
|
||||
|
||||
system = GetComponentInParent<OutfitSystem>();
|
||||
skinnedRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
outfitRenderer = GetComponentInChildren<Renderer>();
|
||||
if (system == null) return;
|
||||
if (!system.initalized) return;
|
||||
|
||||
var extensions = GetComponentsInChildren<IOutfitExtension>();
|
||||
foreach (var item in extensions) { item.Initalize(system, this); }
|
||||
|
||||
|
||||
//Reassigning original bones incase it was attached in editor
|
||||
if (originalBones.Length > 0 && skinnedRenderer)
|
||||
{
|
||||
skinnedRenderer.bones = originalBones;
|
||||
skinnedRenderer.rootBone = originalRootBone;
|
||||
}
|
||||
|
||||
system.OnOutfitChanged += OnOutfitUpdate;
|
||||
system.OnShapeChanged += SetShape;
|
||||
system.AttachOutfit(this);
|
||||
|
||||
|
||||
RemoveIncompatible();
|
||||
CheckTags();
|
||||
CopySystemShapes();
|
||||
|
||||
foreach (var item in extensions) { item.Execute(system, this); }
|
||||
}
|
||||
|
||||
#region OnUpdate Methods
|
||||
|
||||
private void OnOutfitUpdate(Outfit newOutfit)
|
||||
{
|
||||
if (RemoveIfIncompatible(newOutfit)) return;
|
||||
CheckTags();
|
||||
|
||||
}
|
||||
private void CheckTags()
|
||||
{
|
||||
var shapes = new List<string>(tagShapes.Keys);
|
||||
if (!skinnedRenderer) return;
|
||||
for (int i = 0; i < shapes.Count; i++)
|
||||
{
|
||||
var yes = system.ContainsTag(shapes[i]);
|
||||
if (yes) { skinnedRenderer.SetBlendShapeWeight(tagShapes[shapes[i]], 100); }
|
||||
else { skinnedRenderer.SetBlendShapeWeight(tagShapes[shapes[i]], 0); }
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Shapes Methods
|
||||
private void CopySystemShapes()
|
||||
{
|
||||
if (system)
|
||||
{
|
||||
var shapesKeys = shapes.Keys.ToArray();
|
||||
|
||||
for (int i = 0; i < shapesKeys.Length; i++)
|
||||
{
|
||||
var systemValue = system.GetShape(shapesKeys[i]);
|
||||
|
||||
if (systemValue == -10000) continue;
|
||||
SetShape(shapesKeys[i], systemValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InitSetUpShapes()
|
||||
{
|
||||
if (!skinnedRenderer) return;
|
||||
var mesh = skinnedRenderer.sharedMesh;
|
||||
var blendShapeCount = skinnedRenderer.sharedMesh.blendShapeCount;
|
||||
|
||||
for (int i = 0; i < blendShapeCount; i++)
|
||||
{
|
||||
var blendFullName = mesh.GetBlendShapeName(i);
|
||||
var blendName = mesh.GetBlendShapeName(i);
|
||||
|
||||
//removing nameshape that maya gives
|
||||
var sort = blendName.Split(".");
|
||||
if (sort.Length > 1) { blendName = sort[1]; }
|
||||
|
||||
sort = blendName.Split("_");
|
||||
if (sort.Length > 1)
|
||||
{
|
||||
if (sort[0] == "Tag") { tagShapes.Add(sort[1], i); }
|
||||
if (sort[0] == "Shape")
|
||||
{
|
||||
shapes.Add(sort[1], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetShape(string key, float value)
|
||||
{
|
||||
if (!skinnedRenderer) return;
|
||||
var sort = key.Split(".");
|
||||
if (sort.Length > 1) { key = sort[1]; }
|
||||
|
||||
if (!shapes.TryGetValue(key, out int index)) return;
|
||||
|
||||
foreach (var smr in skinnedRenderers)
|
||||
{
|
||||
smr.SetBlendShapeWeight(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Incompatible Outfit Methods
|
||||
|
||||
private void RemoveIncompatible()
|
||||
{
|
||||
foreach (var item in IncompatibleSets)
|
||||
{
|
||||
system.RemoveOutfit(item, true);
|
||||
}
|
||||
}
|
||||
|
||||
private bool RemoveIfIncompatible(Outfit outfit)
|
||||
{
|
||||
if (outfit == null) return false;
|
||||
foreach (var item in IncompatibleSets)
|
||||
{
|
||||
if (outfit.Type == item)
|
||||
{
|
||||
system.RemoveOutfit(this, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Color Methods
|
||||
|
||||
private void SetColorInital()
|
||||
{
|
||||
if (!outfitRenderer) return;
|
||||
var mat = outfitRenderer.material;
|
||||
|
||||
for (int i = 0; i < defaultColors.Length; i++)
|
||||
{
|
||||
mat.SetColor("_Color_" + (1 + i), defaultColors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public override void SetColor(Color color, int index, bool linkedChanged = false)
|
||||
{
|
||||
if (system == null) { system = GetComponentInParent<OutfitSystem>(); }
|
||||
if (outfitRenderer == null) { outfitRenderer = GetComponentInChildren<Renderer>(); }
|
||||
|
||||
if (customShader)
|
||||
{
|
||||
SetColor(color);
|
||||
}
|
||||
else
|
||||
{
|
||||
outfitRenderer.material.SetColor("_Color_" + index, color);
|
||||
}
|
||||
|
||||
foreach (var item in LinkedColorSets)
|
||||
{
|
||||
if (!linkedChanged)
|
||||
{
|
||||
var linkedOutfit = system.GetOutfit(item.linkedType);
|
||||
if (linkedOutfit == null) continue;
|
||||
if (index > item.linkedChannelRange) continue;
|
||||
linkedOutfit.SetColor(color, index, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public override void SetSwatch(int swatchIndex, bool linkedChanged = false)
|
||||
{
|
||||
if (!customShader) return;
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
if (swatchIndex + 1 > outfitSwatches.Count) return;
|
||||
var swatchID = outfitSwatches[swatchIndex].swatchID;
|
||||
var tex = Resources.Load<Texture>(swatchID);
|
||||
material.mainTexture = tex;
|
||||
currentSwatch = swatchIndex;
|
||||
|
||||
foreach (var item in LinkedColorSets)
|
||||
{
|
||||
if (!linkedChanged)
|
||||
{
|
||||
var linkedOutfit = system.GetOutfit(item.linkedType);
|
||||
if (linkedOutfit == null) continue;
|
||||
linkedOutfit.SetSwatch(swatchIndex, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public OutfitData GetOutfitData()
|
||||
{
|
||||
var outfitData = new OutfitData();
|
||||
|
||||
var path = Type.name + "/" + name;
|
||||
path = path.Replace("(Clone)", "");
|
||||
|
||||
outfitData.outfit = path;
|
||||
|
||||
if (customShader)
|
||||
{
|
||||
outfitData.color = GetColor(1);
|
||||
outfitData.swatch = currentSwatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
outfitData.colors = GetColors();
|
||||
|
||||
var decal = GetDecal();
|
||||
|
||||
if (decal != null)
|
||||
{
|
||||
outfitData.decal = "Decal/" + decal.name;
|
||||
outfitData.decalColors = GetDecalColors();
|
||||
outfitData.decalScale = GetDecalSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
outfitData.decal = "";
|
||||
}
|
||||
|
||||
var pattern = GetPattern();
|
||||
if (pattern != null)
|
||||
{
|
||||
outfitData.pattern = "Pattern/" + pattern.name;
|
||||
outfitData.patternColors = GetPatternColors();
|
||||
outfitData.patternScale = GetPatternSize();
|
||||
}
|
||||
else
|
||||
{
|
||||
outfitData.pattern = "";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return outfitData;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Soft Attach
|
||||
#if UNITY_EDITOR
|
||||
public void SoftAttach()
|
||||
{
|
||||
var system = GetComponentInParent<OutfitSystem>();
|
||||
if (system == null)
|
||||
{
|
||||
//return bones if no longer attach to system
|
||||
SoftDetach();
|
||||
return;
|
||||
}
|
||||
system.SoftAttach(this);
|
||||
}
|
||||
|
||||
public void SoftDetach()
|
||||
{
|
||||
editorAttachPoint = null;
|
||||
if (originalBones.Length > 0)
|
||||
{
|
||||
var skinnedRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
if (skinnedRenderer == null) return;
|
||||
skinnedRenderer.bones = originalBones;
|
||||
skinnedRenderer.rootBone = originalRootBone;
|
||||
originalBones = new Transform[0];
|
||||
originalRootBone = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Magicka Cloth2
|
||||
private void InitCloth()
|
||||
{
|
||||
|
||||
/*
|
||||
#if MAGICACLOTH2
|
||||
var cloth = GetComponentInChildren<MagicaCloth2.MagicaCloth>();
|
||||
if (!cloth) return;
|
||||
cloth.enabled = false;
|
||||
cloth.Initialize();
|
||||
cloth.DisableAutoBuild();
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
public void ActivateCloth(Dictionary<string, Transform> boneMap)
|
||||
{
|
||||
|
||||
/*
|
||||
#if MAGICACLOTH2
|
||||
var cloth = GetComponentInChildren<MagicaCloth2.MagicaCloth>();
|
||||
if (!cloth) return;
|
||||
cloth.ReplaceTransform(boneMap);
|
||||
|
||||
var col = system.GetClothColliders();
|
||||
List<MagicaCloth2.ColliderComponent> ClothColliders = col
|
||||
.Where(m => m != null)
|
||||
.Select(m => m.GetComponent<MagicaCloth2.ColliderComponent>())
|
||||
.ToList();
|
||||
|
||||
cloth.SerializeData.colliderCollisionConstraint.colliderList = ClothColliders;
|
||||
|
||||
cloth.enabled = true;
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class OutfitSwatch
|
||||
{
|
||||
public string swatchID;
|
||||
public Color IconColorTop = Color.white;
|
||||
public Color IconColorBottom = Color.black;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class LinkedColorSets
|
||||
{
|
||||
public OutfitType linkedType;
|
||||
[Range(1, 9)] public int linkedChannelRange;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: db36749fc04f0fd4693c063c504270a1
|
||||
202
Assets/04_Characters/_Shared/Models/BMAC/Scripts/OutfitBase.cs
Normal file
202
Assets/04_Characters/_Shared/Models/BMAC/Scripts/OutfitBase.cs
Normal file
@@ -0,0 +1,202 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public abstract class OutfitBase : MonoBehaviour
|
||||
{
|
||||
public bool customShader;
|
||||
protected Material material;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
material = GetComponentInChildren<Renderer>().material;
|
||||
}
|
||||
|
||||
public virtual void SetColor(Color color, int index, bool linkedChanged = false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SetColor(Color color)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
if (material.HasProperty("_Color_1"))
|
||||
{
|
||||
material.SetColor("_Color_1", color);
|
||||
}
|
||||
else if (material.HasProperty("_Color"))
|
||||
{
|
||||
material.SetColor("_Color", color);
|
||||
}
|
||||
else if (material.HasProperty("_MainColor"))
|
||||
{
|
||||
material.SetColor("_MainColor", color);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual List<Color> GetColors()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
var colors = new List<Color>();
|
||||
|
||||
if (customShader)
|
||||
{
|
||||
colors.Add(material.color);
|
||||
return colors;
|
||||
}
|
||||
|
||||
for (int i = 1; i <= 9; i++)
|
||||
{
|
||||
colors.Add(material.GetColor("_Color_" + i));
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
public virtual Color GetColor(int channel)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
|
||||
if (customShader)
|
||||
{
|
||||
if (material.HasProperty("_Color_1"))
|
||||
{
|
||||
return material.GetColor("_Color_1");
|
||||
}
|
||||
else if (material.HasProperty("_Color"))
|
||||
{
|
||||
return material.GetColor("_Color");
|
||||
}
|
||||
else if (material.HasProperty("_MainColor"))
|
||||
{
|
||||
return material.GetColor("_MainColor");
|
||||
}
|
||||
else
|
||||
{
|
||||
return Color.white;
|
||||
}
|
||||
}
|
||||
|
||||
return material.GetColor("_Color_" + channel);
|
||||
}
|
||||
|
||||
public virtual void SetSwatch(int swatchIndex, bool linkedChange = false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void SetDecal(Texture texture)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
if(texture == null) material.SetTexture("_DecalMap", null);
|
||||
else material.SetTexture("_DecalMap", texture);
|
||||
}
|
||||
|
||||
public virtual void SetDecalSize(Vector4 size)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
material.SetVector("_DecalScale", size);
|
||||
}
|
||||
|
||||
public virtual Vector4 GetDecalSize()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
var v = material.GetVector("_DecalScale");
|
||||
|
||||
return new Vector4(v.x, v.y , 0 ,0);
|
||||
}
|
||||
|
||||
public virtual Texture GetDecal()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
|
||||
return material.GetTexture("_DecalMap");
|
||||
}
|
||||
|
||||
public virtual void SetDecalColor(Color color, int index)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
material.SetColor("_DecalColor_" + index, color);
|
||||
}
|
||||
|
||||
public virtual Color GetDecalColor(int index)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
return material.GetColor("_DecalColor_" + index);
|
||||
}
|
||||
|
||||
public virtual List<Color> GetDecalColors()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
var colors = new List<Color>();
|
||||
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
colors.Add(material.GetColor("_DecalColor_" + i));
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
public virtual void SetPattern(Texture texture)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
|
||||
material.SetTexture("_PatternMap", texture);
|
||||
}
|
||||
|
||||
public virtual Texture GetPattern()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
return material.GetTexture("_PatternMap");
|
||||
}
|
||||
|
||||
public virtual void SetPatternColor(Color color, int index)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
material.SetColor("_PatternColor_" + index, color);
|
||||
}
|
||||
|
||||
public virtual Color GetPatternColor(int index)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
return material.GetColor("_PatternColor_" + index);
|
||||
}
|
||||
|
||||
public virtual List<Color> GetPatternColors()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
var colors = new List<Color>();
|
||||
|
||||
for (int i = 1; i < 4; i++)
|
||||
{
|
||||
colors.Add(material.GetColor("_PatternColor_" + i));
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
public virtual void SetPatternSize(Vector2 size)
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
material.SetVector("_PatternScale", size);
|
||||
}
|
||||
|
||||
public virtual Vector4 GetPatternSize()
|
||||
{
|
||||
if (!material) { material = GetComponentInChildren<Renderer>().material; }
|
||||
var v = material.GetVector("_PatternScale");
|
||||
|
||||
return new Vector4(v.x, v.y, 0 ,0);
|
||||
}
|
||||
|
||||
public virtual void SetBaseTexture(Texture texture, Texture normalTexture = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1e1c13099198aba47bbec60b5fea3afb
|
||||
@@ -0,0 +1,108 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class OutfitFollowBlendShapes : MonoBehaviour, IOutfitExtension
|
||||
{
|
||||
OutfitSystem system;
|
||||
SkinnedMeshRenderer mesh;
|
||||
SkinnedMeshRenderer followTarget;
|
||||
|
||||
[SerializeField] OutfitType follow;
|
||||
[SerializeField] List<Vector2> shapes = new List<Vector2>();
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (system == null) return;
|
||||
system.OnOutfitChanged -= OnNewSetUpHead;
|
||||
}
|
||||
|
||||
private void Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void OnNewSetUpHead(Outfit outfit)
|
||||
{
|
||||
if (outfit == null) { return; }
|
||||
if (outfit.Type != follow) { return; }
|
||||
if (!outfit.skinnedRenderer) { return; }
|
||||
followTarget = outfit.skinnedRenderer;
|
||||
SetUp();
|
||||
}
|
||||
|
||||
private void SetUp()
|
||||
{
|
||||
mesh = GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
|
||||
var characterShapeTitle = followTarget.sharedMesh.GetBlendShapeName(0);
|
||||
var sort = characterShapeTitle.Split(".");
|
||||
if (sort.Length > 1) { characterShapeTitle = sort[0] + "."; }
|
||||
else { characterShapeTitle = ""; }
|
||||
|
||||
shapes.Clear();
|
||||
for (int i = 0; i < mesh.sharedMesh.blendShapeCount; i++)
|
||||
{
|
||||
var shapeName = mesh.sharedMesh.GetBlendShapeName(i);
|
||||
sort = shapeName.Split(".");
|
||||
if (sort.Length > 1) { shapeName = sort[1]; }
|
||||
|
||||
var shapeIndex = followTarget.sharedMesh.GetBlendShapeIndex(characterShapeTitle + shapeName);
|
||||
|
||||
if (shapeIndex != -1)
|
||||
{
|
||||
//print(characterShapeTitle + " | " + shapeName + " | " + shapeIndex);
|
||||
shapes.Add(new Vector2 (i,shapeIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (followTarget == null) return;
|
||||
for (int i = 0; i < shapes.Count; i++)
|
||||
{
|
||||
mesh.SetBlendShapeWeight((int)shapes[i].x, followTarget.GetBlendShapeWeight((int)shapes[i].y));
|
||||
}
|
||||
}
|
||||
|
||||
public string GetID()
|
||||
{
|
||||
return "BlendShapeFollow";
|
||||
}
|
||||
|
||||
public void Initalize(OutfitSystem outfitSystem, Outfit outfit)
|
||||
{
|
||||
system = outfitSystem;
|
||||
if (system == null) return;
|
||||
system.OnOutfitChanged += OnNewSetUpHead;
|
||||
mesh = outfit.skinnedRenderer;
|
||||
|
||||
var followOutfit = system.GetOutfit(follow);
|
||||
if (followOutfit == null) { return; }
|
||||
if (followOutfit.skinnedRenderer == null) { return; }
|
||||
followTarget = followOutfit.skinnedRenderer;
|
||||
|
||||
SetUp();
|
||||
|
||||
}
|
||||
|
||||
public void Execute(OutfitSystem outfitSystem, Outfit outfit)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public object GetValue()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Type GetValueType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 497fa68147501dc4f81acb60c2647e46
|
||||
@@ -0,0 +1,27 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class OutfitHeightChange : MonoBehaviour
|
||||
{
|
||||
[SerializeField] float HeightOffset;
|
||||
private void OnEnable()
|
||||
{
|
||||
var System = GetComponentInParent<OutfitSystem>();
|
||||
if (System == null) return;
|
||||
|
||||
System.SetHeight(HeightOffset);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
var System = GetComponentInParent<OutfitSystem>();
|
||||
if (System == null) return;
|
||||
|
||||
System.SetHeight(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56c7d0af527584d479702c3f4242abb3
|
||||
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class OutfitHideByTag : MonoBehaviour
|
||||
{
|
||||
OutfitSystem system;
|
||||
[SerializeField] HideSettings[] settings;
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
system = GetComponentInParent<OutfitSystem>();
|
||||
if (!system) return;
|
||||
system.OnOutfitChanged += SetHide;
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
system = GetComponentInParent<OutfitSystem>(true);
|
||||
if (!system) return;
|
||||
system.OnOutfitChanged -= SetHide;
|
||||
}
|
||||
|
||||
private void SetHide(Outfit arg0)
|
||||
{
|
||||
foreach (var item in settings)
|
||||
{
|
||||
if (system.ContainsTag(item.tag))
|
||||
{
|
||||
item.renderer.gameObject.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.renderer.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
private struct HideSettings
|
||||
{
|
||||
public SkinnedMeshRenderer renderer;
|
||||
public string tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d588c07bc45fc674499da992f84b5d29
|
||||
@@ -0,0 +1,47 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class OutfitSelector : MonoBehaviour
|
||||
{
|
||||
public Image icon;
|
||||
private Outfit outfit;
|
||||
private CharacterCreator characterCreator;
|
||||
private Button button;
|
||||
public void Init(Outfit outfit, CharacterCreator characterCreator)
|
||||
{
|
||||
//icon = GetComponentInChildren<Image>();
|
||||
button = GetComponentInChildren<Button>();
|
||||
button.onClick.AddListener(OnSelect);
|
||||
|
||||
this.outfit = outfit;
|
||||
this.characterCreator = characterCreator;
|
||||
icon.overrideSprite = this.outfit.OutfitIcon;
|
||||
}
|
||||
|
||||
private void OnSelect()
|
||||
{
|
||||
characterCreator.SetOutfit(outfit);
|
||||
}
|
||||
|
||||
public void SetVisable(string type)
|
||||
{
|
||||
if (outfit.Type == null)
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
Debug.LogWarning(outfit.name + " is missing an outfitType and will not show in the character creator");
|
||||
return;
|
||||
}
|
||||
|
||||
if(outfit.Type.name == type)
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b046ca2a12a9c3846a325943ca101458
|
||||
989
Assets/04_Characters/_Shared/Models/BMAC/Scripts/OutfitSystem.cs
Normal file
989
Assets/04_Characters/_Shared/Models/BMAC/Scripts/OutfitSystem.cs
Normal file
@@ -0,0 +1,989 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class OutfitSystem : MonoBehaviour
|
||||
{
|
||||
//[Header("Save Data")]
|
||||
|
||||
public CharacterObject characterData;
|
||||
private CharacterObject _characterData;
|
||||
public string SaveID;
|
||||
|
||||
|
||||
//[Header("Dependencies")]
|
||||
[SerializeField] SkinnedMeshRenderer CharacterBody;
|
||||
|
||||
//Height
|
||||
public bool muteHeightChange { get; private set; }
|
||||
public float height { get; private set; }
|
||||
|
||||
//Animation
|
||||
public Animator animator
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_animator == null)
|
||||
{
|
||||
_animator = GetComponentInParent<Animator>();
|
||||
if (_animator == null) { _animator = GetComponentInChildren<Animator>(); }
|
||||
}
|
||||
|
||||
return _animator;
|
||||
}
|
||||
private set
|
||||
{ _animator = value; }
|
||||
}
|
||||
private Animator _animator;
|
||||
public float stance { get; private set; }
|
||||
|
||||
//Dimensions
|
||||
private Bounds CharacterRenderBounds;
|
||||
Dictionary<string, Transform> boneMap = new Dictionary<string, Transform>();
|
||||
|
||||
//Outfits
|
||||
public Dictionary<OutfitType, Outfit> Outfits = new Dictionary<OutfitType, Outfit>();
|
||||
public Dictionary<string, OutfitType> KnownOutfitTypes = new Dictionary<string, OutfitType>();
|
||||
|
||||
//Shapes
|
||||
private Dictionary<string, int> bodyShapes = new Dictionary<string, int>();
|
||||
private Dictionary<string, int> faceShapes = new Dictionary<string, int>();
|
||||
private Dictionary<string, int> tagShapes = new Dictionary<string, int>();
|
||||
public Dictionary<string, BodyShapeModifier> bodyModifiers = new Dictionary<string, BodyShapeModifier>();
|
||||
private List<string> tags = new List<string>();
|
||||
|
||||
|
||||
//Events
|
||||
public UnityAction<Outfit> OnOutfitChanged;
|
||||
public UnityAction<SkinnedMeshRenderer> OnRigChanged;
|
||||
public UnityAction<string, float> OnShapeChanged;
|
||||
|
||||
public bool initalized { get; private set; }
|
||||
|
||||
|
||||
// Merged Properties
|
||||
public string prefabName;
|
||||
public Material mergeMaterial;
|
||||
public bool mergedMode;
|
||||
public bool mergeBase;
|
||||
public bool mergeOnAwake;
|
||||
public bool autoUpdate;
|
||||
public CharacterData data;
|
||||
private Dictionary<string, OutfitData> outfitData = new Dictionary<string, OutfitData>();
|
||||
public Dictionary<string,Texture2D> customMaps = new Dictionary<string, Texture2D>();
|
||||
public bool isDirty { get; private set; }
|
||||
public MergedMaterialData[] materialData;
|
||||
|
||||
public enum LoadMode { OnStartAndOnValidate, OnStart, Manual}
|
||||
public LoadMode loadMode;
|
||||
|
||||
public bool async;
|
||||
|
||||
|
||||
#if MAGICACLOTH2
|
||||
//MagicaCloth
|
||||
private MagicaCloth2.ColliderComponent[] ClothColliders;
|
||||
#endif
|
||||
|
||||
|
||||
private void OnValidate()
|
||||
{
|
||||
if (Application.isPlaying && gameObject.scene.isLoaded && loadMode == LoadMode.OnStartAndOnValidate)
|
||||
{
|
||||
Invoke("LoadFromObject", 0f);
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Init();
|
||||
if (mergeOnAwake) mergedMode = true;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (loadMode == LoadMode.OnStart || loadMode == LoadMode.OnStartAndOnValidate)
|
||||
{
|
||||
LoadFromObject();
|
||||
}
|
||||
}
|
||||
|
||||
#region Initalizers
|
||||
|
||||
public void Init()
|
||||
{
|
||||
|
||||
if (initalized) return;
|
||||
|
||||
if (CharacterBody == null)
|
||||
{
|
||||
Debug.LogWarning("Outfit System does not have a Rig assigned please assign one to prevent this warning", gameObject);
|
||||
Debug.LogWarning("Attempting auto rig assignment...");
|
||||
var skinnedMeshes = GetComponentsInChildren<SkinnedMeshRenderer>(true);
|
||||
foreach (var item in skinnedMeshes)
|
||||
{
|
||||
if (item.name == "BMAC_Body")
|
||||
{
|
||||
CharacterBody = item;
|
||||
Debug.Log("Rig Found Successfully!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
Debug.LogError("Search Failed. Please Assign Mannually", gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
CharacterRenderBounds = CharacterBody.localBounds;
|
||||
|
||||
|
||||
InitBoneMap();
|
||||
InitBodyShapes();
|
||||
InitBodyMods();
|
||||
InitClothColliders();
|
||||
|
||||
initalized = true;
|
||||
}
|
||||
|
||||
private void InitBoneMap()
|
||||
{
|
||||
boneMap.Clear();
|
||||
foreach (Transform bone in CharacterBody.bones)
|
||||
{
|
||||
if (boneMap.ContainsKey(bone.name) == false)
|
||||
{
|
||||
boneMap.Add(bone.name, bone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void InitBodyShapes()
|
||||
{
|
||||
|
||||
var body = GetOutfit("Body");
|
||||
|
||||
|
||||
bodyShapes.Clear();
|
||||
tagShapes.Clear();
|
||||
|
||||
Mesh mesh;
|
||||
int blendShapeCount = 0;
|
||||
|
||||
if (body != null)
|
||||
{
|
||||
|
||||
mesh = body.skinnedRenderer.sharedMesh;
|
||||
blendShapeCount = body.skinnedRenderer.sharedMesh.blendShapeCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh = CharacterBody.sharedMesh;
|
||||
blendShapeCount = CharacterBody.sharedMesh.blendShapeCount;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < blendShapeCount; i++)
|
||||
{
|
||||
var blendFullName = mesh.GetBlendShapeName(i);
|
||||
var blendName = mesh.GetBlendShapeName(i);
|
||||
|
||||
//removing nameshape that maya gives
|
||||
var sort = blendName.Split(".");
|
||||
if (sort.Length > 1) { blendName = sort[1]; }
|
||||
|
||||
|
||||
sort = blendName.Split("_");
|
||||
if (sort.Length > 1)
|
||||
{
|
||||
if (sort[0] == "Shape") { bodyShapes.Add(sort[1], i); }
|
||||
if (sort[0] == "Tag") { tagShapes.Add(sort[1], i); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void InitBodyMods()
|
||||
{
|
||||
var bodyMods = new List<BodyShapeModifier>(GetComponentsInChildren<BodyShapeModifier>());
|
||||
bodyModifiers.Clear();
|
||||
for (int i = 0; i < bodyMods.Count; i++)
|
||||
{
|
||||
bodyModifiers.Add(bodyMods[i].name, bodyMods[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void InitFaceShapes()
|
||||
{
|
||||
var head = GetOutfit("Head");
|
||||
|
||||
faceShapes.Clear();
|
||||
|
||||
Mesh mesh;
|
||||
if (head != null)
|
||||
{
|
||||
mesh = head.skinnedRenderer.sharedMesh;
|
||||
}
|
||||
else
|
||||
{
|
||||
mesh = CharacterBody.sharedMesh;
|
||||
}
|
||||
|
||||
var blendShapeCount = mesh.blendShapeCount;
|
||||
|
||||
for (int i = 0; i < blendShapeCount; i++)
|
||||
{
|
||||
var blendFullName = mesh.GetBlendShapeName(i);
|
||||
var blendName = mesh.GetBlendShapeName(i);
|
||||
|
||||
//removing nameshape that maya gives
|
||||
var sort = blendName.Split(".");
|
||||
if (sort.Length > 1) { blendName = sort[1]; }
|
||||
|
||||
sort = blendName.Split("_");
|
||||
if (sort.Length > 1)
|
||||
{
|
||||
if (sort[0] == "Shape") { faceShapes.Add(sort[1], i); }
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void InitClothColliders()
|
||||
{
|
||||
#if MAGICACLOTH2
|
||||
ClothColliders = GetComponentsInChildren<MagicaCloth2.ColliderComponent>();
|
||||
#endif
|
||||
}
|
||||
|
||||
#region Saving and Loading
|
||||
|
||||
public void LoadFromObject(CharacterObject saveData)
|
||||
{
|
||||
characterData = saveData;
|
||||
LoadFromObject();
|
||||
}
|
||||
|
||||
[ContextMenu("Load")]
|
||||
public void LoadFromObject()
|
||||
{
|
||||
|
||||
if (characterData)
|
||||
{
|
||||
if (_characterData != characterData)
|
||||
{
|
||||
SaveID = characterData.name;
|
||||
|
||||
if (mergedMode)
|
||||
{
|
||||
data = characterData.data;
|
||||
isDirty = true;
|
||||
MergeCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
_characterData = characterData;
|
||||
LoadCharacter(characterData.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
[ContextMenu("LoadByID")]
|
||||
public void LoadFromID()
|
||||
{
|
||||
LoadFromID(SaveID);
|
||||
}
|
||||
|
||||
public void LoadFromID(string saveName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(saveName)) return;
|
||||
SaveID = saveName;
|
||||
|
||||
var data = BMAC_SaveSystem.GetDataFromID(SaveID);
|
||||
if (data == null) return;
|
||||
|
||||
LoadCharacter(data);
|
||||
}
|
||||
|
||||
private async void LoadCharacter(CharacterData data)
|
||||
{
|
||||
if (mergedMode)
|
||||
{
|
||||
this.data = data;
|
||||
isDirty = true;
|
||||
MergeCharacter();
|
||||
}
|
||||
else
|
||||
{
|
||||
await BMAC_SaveSystem.LoadCharacter(this, data, false, async);
|
||||
}
|
||||
}
|
||||
|
||||
[ContextMenu("SaveToObject")]
|
||||
public void SaveToObject()
|
||||
{
|
||||
if (!characterData)
|
||||
{
|
||||
Debug.LogWarning("Character Data Field is empty. Please provide a BSMC_CharacterObject to " + transform.name);
|
||||
return;
|
||||
}
|
||||
BMAC_SaveSystem.SaveCharacter(this, characterData.data.characterName, characterData.icon);
|
||||
}
|
||||
|
||||
[ContextMenu("SaveByID")]
|
||||
|
||||
public void SaveByID()
|
||||
{
|
||||
SaveByID(SaveID);
|
||||
}
|
||||
|
||||
public void SaveByID(string characterName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(characterName))
|
||||
{
|
||||
Debug.LogWarning("No ID provided saving aborted");
|
||||
return;
|
||||
}
|
||||
|
||||
//Creating EmptyIcon
|
||||
if (!System.IO.File.Exists(BMAC_SaveSystem.iconFilePath + "/" + characterName + ".png"))
|
||||
{
|
||||
Texture2D tex = new Texture2D(2, 2, TextureFormat.RGBA32, false);
|
||||
byte[] bytes = tex.EncodeToPNG();
|
||||
System.IO.File.WriteAllBytes(BMAC_SaveSystem.iconFilePath + "/" + characterName + ".png", bytes);
|
||||
}
|
||||
|
||||
BMAC_SaveSystem.SaveCharacter(this, characterName);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region Outfit Removeal
|
||||
public void RemoveOutfit(Outfit outfit, bool destory)
|
||||
{
|
||||
if (Outfits.TryGetValue(outfit.Type, out Outfit currentOutfitInSlot))
|
||||
{
|
||||
if (destory == true && currentOutfitInSlot != null)
|
||||
{
|
||||
Destroy(currentOutfitInSlot.gameObject);
|
||||
Outfits[outfit.Type] = null;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveTags(outfit);
|
||||
OnOutfitChanged?.Invoke(null);
|
||||
}
|
||||
|
||||
|
||||
public void RemoveOutfit(OutfitType type, bool destory)
|
||||
{
|
||||
if (Outfits.TryGetValue(type, out Outfit currentOutfitInSlot))
|
||||
{
|
||||
if (destory == true && currentOutfitInSlot != null)
|
||||
{
|
||||
Destroy(currentOutfitInSlot.gameObject);
|
||||
Outfits[type] = null;
|
||||
}
|
||||
}
|
||||
|
||||
RemoveTags(currentOutfitInSlot);
|
||||
OnOutfitChanged?.Invoke(null);
|
||||
}
|
||||
|
||||
public void RemoveTags(Outfit removedOutfit)
|
||||
{
|
||||
if (removedOutfit == null) return;
|
||||
tags.RemoveAll(item => removedOutfit.tags.Contains(item));
|
||||
}
|
||||
|
||||
public void RemoveAllOutfits()
|
||||
{
|
||||
List<Outfit> list = new List<Outfit>(Outfits.Values);
|
||||
foreach (var item in list)
|
||||
{
|
||||
if (item == null) continue;
|
||||
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
Outfits.Clear();
|
||||
tags.Clear();
|
||||
OnOutfitChanged?.Invoke(null);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public Outfit InstantiateOutfit(Outfit outfit)
|
||||
{
|
||||
var inst = Instantiate(outfit, transform);
|
||||
inst.name = inst.name.Replace("(Clone)", "");
|
||||
return inst;
|
||||
}
|
||||
|
||||
public void AttachOutfit(Outfit outfit)
|
||||
{
|
||||
if (!initalized) return;
|
||||
|
||||
if (mergedMode)
|
||||
{
|
||||
outfitData[outfit.Type.name] = outfit.GetOutfitData();
|
||||
data.outfitDatas = outfitData.Values.ToList();
|
||||
isDirty = true;
|
||||
Destroy(outfit.gameObject);
|
||||
if (autoUpdate) MergeCharacter();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!KnownOutfitTypes.ContainsKey(outfit.Type.name))
|
||||
{
|
||||
KnownOutfitTypes.Add(outfit.Type.name, outfit.Type);
|
||||
}
|
||||
|
||||
|
||||
//check if an outfit is already in that slot and replace it
|
||||
ReplaceOutfit(outfit);
|
||||
|
||||
|
||||
//Merging outfit bones or attaching outfit to specified bone
|
||||
MergeBones(outfit);
|
||||
|
||||
|
||||
//Adjusting Mesh bounds so the meshes don't unexpectingly disappear.
|
||||
if (outfit.skinnedRenderer)
|
||||
{
|
||||
UpdateCharacterBounds(outfit);
|
||||
}
|
||||
|
||||
|
||||
//Apply the Current Body Morphs to the Outfit
|
||||
ApplyShapesToOufit(outfit);
|
||||
|
||||
//If Head get its Morphs
|
||||
if (outfit.Type.name == "Head") { InitFaceShapes(); }
|
||||
|
||||
//If Body get its Morphs
|
||||
if (outfit.Type.name == "Body") { InitBodyShapes(); }
|
||||
|
||||
tags.AddRange(outfit.tags);
|
||||
ApplyTags();
|
||||
|
||||
OnOutfitChanged?.Invoke(outfit);
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void ApplyShapesToOufit(Outfit outfit)
|
||||
{
|
||||
var keys = new List<string>(bodyShapes.Keys);
|
||||
for (int i = 0; i < keys.Count; i++)
|
||||
{
|
||||
outfit.SetShape(keys[i], bodyShapes[keys[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetShape(string key, float value)
|
||||
{
|
||||
SkinnedMeshRenderer renderer = null;
|
||||
var index = -1;
|
||||
|
||||
var body = GetOutfit("Body");
|
||||
var head = GetOutfit("Head");
|
||||
|
||||
if (bodyShapes.TryGetValue(key, out int bodyValue) && body)
|
||||
{
|
||||
index = bodyValue;
|
||||
if (body != null) { renderer = body.skinnedRenderer; }
|
||||
}
|
||||
else if (faceShapes.TryGetValue(key, out int faceValue) && head)
|
||||
{
|
||||
index = faceValue;
|
||||
if (head != null) { renderer = head.skinnedRenderer; }
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bodyShapes.TryGetValue(key, out int blendValue))
|
||||
{
|
||||
index = blendValue;
|
||||
renderer = CharacterBody;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (renderer != null) renderer.SetBlendShapeWeight(index, value);
|
||||
|
||||
OnShapeChanged?.Invoke(key, value);
|
||||
}
|
||||
|
||||
private void ApplyTags()
|
||||
{
|
||||
// This method is intented for when you merged the body but still want to attach outfits dynamically
|
||||
if(GetOutfit("Body") != null) { return; }
|
||||
|
||||
var shapes = new List<string>(tagShapes.Keys);
|
||||
if (!CharacterBody) return;
|
||||
if (CharacterBody.sharedMesh.blendShapeCount == 0) return;
|
||||
for (int i = 0; i < shapes.Count; i++)
|
||||
{
|
||||
var yes = ContainsTag(shapes[i]);
|
||||
if (yes) { CharacterBody.SetBlendShapeWeight(tagShapes[shapes[i]], 100); }
|
||||
else { CharacterBody.SetBlendShapeWeight(tagShapes[shapes[i]], 0); }
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStance(float value)
|
||||
{
|
||||
animator.SetFloat("Stance", value);
|
||||
stance = value;
|
||||
}
|
||||
|
||||
public void SetHeight(float value)
|
||||
{
|
||||
//remove Previous Height
|
||||
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y - height, transform.localPosition.z);
|
||||
//Apply New Height
|
||||
height = value;
|
||||
if (!muteHeightChange)
|
||||
{
|
||||
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y + value, transform.localPosition.z);
|
||||
}
|
||||
}
|
||||
|
||||
public void MuteHeightChange(bool value)
|
||||
{
|
||||
if (value == muteHeightChange) return;
|
||||
|
||||
muteHeightChange = value;
|
||||
|
||||
var height = this.height;
|
||||
if (muteHeightChange)
|
||||
{
|
||||
height = -height;
|
||||
}
|
||||
|
||||
transform.localPosition = new Vector3(transform.localPosition.x, transform.localPosition.y + height, transform.localPosition.z);
|
||||
}
|
||||
|
||||
private void ReplaceOutfit(Outfit outfit)
|
||||
{
|
||||
if (Outfits.TryGetValue(outfit.Type, out Outfit currentOutfitInSlot))
|
||||
{
|
||||
if (Outfits[outfit.Type])
|
||||
{
|
||||
if (outfit.transform != Outfits[outfit.Type].transform)
|
||||
{
|
||||
Destroy(currentOutfitInSlot.gameObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnOutfitChanged?.Invoke(outfit);
|
||||
|
||||
}
|
||||
}
|
||||
Outfits[outfit.Type] = outfit;
|
||||
}
|
||||
else
|
||||
{
|
||||
Outfits.Add(outfit.Type, outfit);
|
||||
}
|
||||
}
|
||||
|
||||
private void MergeBones(Outfit outfit)
|
||||
{
|
||||
foreach (var smr in outfit.skinnedRenderers)
|
||||
{
|
||||
var renderer = smr;
|
||||
|
||||
if (outfit.AttachPoint == "" && renderer)
|
||||
{
|
||||
if (outfit.Initalized == false)
|
||||
{
|
||||
|
||||
var oldBones = renderer.bones.ToArray();
|
||||
var newBones = new Transform[renderer.bones.Length];
|
||||
for (int i = 0; i < oldBones.Length; i++)
|
||||
{
|
||||
var bone = oldBones[i];
|
||||
boneMap.TryGetValue(bone.name, out Transform baseBone);
|
||||
if (bone == baseBone)
|
||||
{
|
||||
newBones[i] = baseBone;
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
newBones[i] = baseBone;
|
||||
//Destroy(bone.gameObject);
|
||||
}
|
||||
}
|
||||
renderer.bones = newBones;
|
||||
renderer.rootBone = CharacterBody.rootBone;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Transform bone = null;
|
||||
try
|
||||
{
|
||||
bone = boneMap[outfit.AttachPoint];
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError(name + " is missing " + outfit.AttachPoint + " that " + outfit.name + " requires");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
outfit.transform.parent = bone.transform;
|
||||
outfit.transform.position = bone.position;
|
||||
outfit.transform.rotation = bone.rotation;
|
||||
outfit.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
|
||||
outfit.ActivateCloth(boneMap);
|
||||
outfit.Initalized = true;
|
||||
|
||||
if (outfit.outfitRenderer && outfit.AttachPoint != "")
|
||||
{
|
||||
Transform bone = null;
|
||||
try
|
||||
{
|
||||
bone = boneMap[outfit.AttachPoint];
|
||||
}
|
||||
catch
|
||||
{
|
||||
Debug.LogError(name + " is missing " + outfit.AttachPoint + " that " + outfit.name + " requires");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
outfit.transform.parent = bone.transform;
|
||||
outfit.transform.position = bone.position;
|
||||
outfit.transform.rotation = bone.rotation;
|
||||
outfit.transform.localScale = Vector3.one;
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateCharacterBounds(Outfit outfit)
|
||||
{
|
||||
foreach (var item in Outfits.Values)
|
||||
{
|
||||
if (item == null) continue;
|
||||
foreach (var smr in item.skinnedRenderers)
|
||||
{
|
||||
if (smr != null) smr.localBounds = CharacterRenderBounds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool ContainsTag(string tag)
|
||||
{
|
||||
return tags.Contains(tag);
|
||||
}
|
||||
|
||||
#region Getters
|
||||
|
||||
public Outfit GetOutfit(OutfitType outfitType)
|
||||
{
|
||||
if (Outfits.TryGetValue(outfitType, out Outfit item))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public Outfit GetOutfit(string outfitType)
|
||||
{
|
||||
if (KnownOutfitTypes.TryGetValue(outfitType, out OutfitType type))
|
||||
{
|
||||
if (Outfits.TryGetValue(type, out Outfit item))
|
||||
{
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<Outfit> GetOutfits()
|
||||
{
|
||||
return new List<Outfit>(Outfits.Values);
|
||||
}
|
||||
|
||||
public List<string> GetShapes()
|
||||
{
|
||||
return bodyShapes.Keys.ToList();
|
||||
}
|
||||
|
||||
public List<string> GetFaceShapes()
|
||||
{
|
||||
return faceShapes.Keys.ToList();
|
||||
}
|
||||
|
||||
#if MAGICACLOTH2
|
||||
public MagicaCloth2.ColliderComponent[] GetClothColliders()
|
||||
{
|
||||
return ClothColliders;
|
||||
}
|
||||
#endif
|
||||
|
||||
public float GetShape(string key)
|
||||
{
|
||||
if (bodyShapes.TryGetValue(key, out int value))
|
||||
{
|
||||
var body = GetOutfit("Body");
|
||||
if (body != null)
|
||||
{
|
||||
var weightValue = body.skinnedRenderer.GetBlendShapeWeight(value);
|
||||
return weightValue;
|
||||
}
|
||||
else return -10000;
|
||||
}
|
||||
else return -10000;
|
||||
}
|
||||
|
||||
public Dictionary<string, BodyShapeModifier> GetMods()
|
||||
{
|
||||
return bodyModifiers;
|
||||
}
|
||||
public Dictionary<string, Transform> GetBones()
|
||||
{
|
||||
return boneMap;
|
||||
}
|
||||
|
||||
public float GetShapeValue(string key)
|
||||
{
|
||||
var weight = -1f;
|
||||
|
||||
var body = GetOutfit("Body");
|
||||
|
||||
if (body == null) return -1;
|
||||
if (bodyShapes.TryGetValue(key, out int bodyValue))
|
||||
{
|
||||
weight = body.skinnedRenderer.GetBlendShapeWeight(bodyValue);
|
||||
}
|
||||
else if (faceShapes.TryGetValue(key, out int faceValue))
|
||||
{
|
||||
var face = GetOutfit("Head");
|
||||
if (face == null) return -1;
|
||||
weight = face.skinnedRenderer.GetBlendShapeWeight(faceValue);
|
||||
}
|
||||
|
||||
return weight;
|
||||
}
|
||||
|
||||
public float GetShapeValue(int key)
|
||||
{
|
||||
SkinnedMeshRenderer renderer;
|
||||
var body = GetOutfit("Body");
|
||||
if (body == null) renderer = CharacterBody;
|
||||
else renderer = body.skinnedRenderer;
|
||||
|
||||
var weightValue = renderer.GetBlendShapeWeight(key);
|
||||
return weightValue;
|
||||
}
|
||||
|
||||
public Dictionary<string, float> GetBodyShapeValues()
|
||||
{
|
||||
var bodyShapeValues = new Dictionary<string, float>();
|
||||
var shapes = bodyShapes.Values.ToArray();
|
||||
var keys = bodyShapes.Keys.ToArray();
|
||||
|
||||
SkinnedMeshRenderer renderer;
|
||||
var body = GetOutfit("Body");
|
||||
if (body == null) renderer = CharacterBody;
|
||||
else renderer = body.skinnedRenderer;
|
||||
|
||||
for (int i = 0; i < shapes.Length; i++)
|
||||
{
|
||||
var weightValue = renderer.GetBlendShapeWeight(shapes[i]);
|
||||
bodyShapeValues.Add(keys[i], weightValue);
|
||||
}
|
||||
|
||||
return bodyShapeValues;
|
||||
}
|
||||
|
||||
public Dictionary<string, float> GetFaceShapeValues()
|
||||
{
|
||||
var faceShapeValues = new Dictionary<string, float>();
|
||||
var shapes = faceShapes.Values.ToArray();
|
||||
var keys = faceShapes.Keys.ToArray();
|
||||
|
||||
SkinnedMeshRenderer renderer;
|
||||
var head = GetOutfit("Head");
|
||||
if (head == null) renderer = CharacterBody;
|
||||
else renderer = head.skinnedRenderer;
|
||||
|
||||
for (int i = 0; i < shapes.Length; i++)
|
||||
{
|
||||
var weightValue = renderer.GetBlendShapeWeight(shapes[i]);
|
||||
faceShapeValues.Add(keys[i], weightValue);
|
||||
}
|
||||
|
||||
return faceShapeValues;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#if UNITY_EDITOR
|
||||
|
||||
public void SoftAttach(Outfit outfit)
|
||||
{
|
||||
//For Attaching outfits during in the Editor
|
||||
if (CharacterBody == null)
|
||||
{
|
||||
Debug.LogWarning("Soft Attach attempted but OuftitSystem did not have a CharacterBody please assign in the inspector", gameObject);
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, Transform> boneMap = new Dictionary<string, Transform>();
|
||||
foreach (Transform bone in CharacterBody.bones)
|
||||
{
|
||||
if (boneMap.ContainsKey(bone.name) == false)
|
||||
{
|
||||
boneMap.Add(bone.name, bone);
|
||||
}
|
||||
}
|
||||
|
||||
var renderer = outfit.GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
|
||||
renderer.localBounds = CharacterBody.localBounds;
|
||||
|
||||
//Already Attached
|
||||
if (outfit.originalBones.Length > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (outfit.AttachPoint == "" && renderer)
|
||||
{
|
||||
if (outfit.Initalized == false)
|
||||
{
|
||||
outfit.originalBones = renderer.bones;
|
||||
outfit.originalRootBone = renderer.rootBone;
|
||||
|
||||
var oldBones = renderer.bones.ToArray();
|
||||
var newBones = new Transform[renderer.bones.Length];
|
||||
for (int i = 0; i < oldBones.Length; i++)
|
||||
{
|
||||
var bone = oldBones[i];
|
||||
boneMap.TryGetValue(bone.name, out newBones[i]);
|
||||
}
|
||||
renderer.bones = newBones;
|
||||
renderer.rootBone = CharacterBody.rootBone;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public SkinnedMeshRenderer GetCharacterBody() { return CharacterBody; }
|
||||
public void SetCharacterBody(GameObject newBody)
|
||||
{
|
||||
var smr = newBody.GetComponentInChildren<SkinnedMeshRenderer>();
|
||||
if (smr == null) return;
|
||||
|
||||
RemoveAllOutfits();
|
||||
DestroyImmediate(CharacterBody.transform.parent.gameObject);
|
||||
|
||||
newBody.transform.parent = transform;
|
||||
newBody.transform.localPosition = Vector3.zero;
|
||||
newBody.transform.localRotation = Quaternion.identity;
|
||||
newBody.transform.localScale = Vector3.one;
|
||||
|
||||
CharacterBody = smr;
|
||||
|
||||
InitBoneMap();
|
||||
InitBodyShapes();
|
||||
InitBodyMods();
|
||||
InitClothColliders();
|
||||
|
||||
OnRigChanged?.Invoke(CharacterBody);
|
||||
|
||||
Invoke("RebindBody", 0);
|
||||
}
|
||||
|
||||
public void RebindBody()
|
||||
{
|
||||
animator.Rebind();
|
||||
}
|
||||
|
||||
[ContextMenu("Merge")]
|
||||
public void MergeCharacter()
|
||||
{
|
||||
if (Application.isPlaying && gameObject.scene.isLoaded)
|
||||
{
|
||||
var optimizer = new BoZo_CharacterOptimizer();
|
||||
|
||||
if (mergedMode && isDirty)
|
||||
{
|
||||
optimizer.OptimizeCharacter(this, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var preMergedData = BMAC_SaveSystem.GetCharacterData(this);
|
||||
data = preMergedData;
|
||||
|
||||
foreach (var item in GetOutfits())
|
||||
{
|
||||
if (!item) { continue; }
|
||||
var outfit = outfitData[item.Type.name] = item.GetOutfitData();
|
||||
|
||||
}
|
||||
|
||||
|
||||
optimizer.OptimizeCharacter(this, preMergedData);
|
||||
animator.SetBool("isMerged", true);
|
||||
mergedMode = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogWarning("For stability reason Character Merging is only available in Play Mode");
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
[ContextMenu("SaveToPrefab")]
|
||||
public void SaveCharacterToPrefab()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (Application.isPlaying && gameObject.scene.isLoaded)
|
||||
{
|
||||
var optimizer = new BoZo_CharacterOptimizer();
|
||||
|
||||
if (mergedMode && isDirty)
|
||||
{
|
||||
optimizer.SaveOptimizedCharacter(this, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
var preMergedData = BMAC_SaveSystem.GetCharacterData(this);
|
||||
data = preMergedData;
|
||||
|
||||
foreach (var item in GetOutfits())
|
||||
{
|
||||
outfitData[item.Type.name] = item.GetOutfitData();
|
||||
}
|
||||
|
||||
optimizer.SaveOptimizedCharacter(this, preMergedData);
|
||||
animator.SetBool("isMerged", true);
|
||||
mergedMode = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c317bffdef488c04db98be9d95891349
|
||||
@@ -0,0 +1,10 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
[CreateAssetMenu(fileName = "NewOutfitType", menuName = "BoZo/BMAC_OutfitType")]
|
||||
public class OutfitType : ScriptableObject
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab164b4404dbd424ba5b274ece7019e6
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 110022a0c05d6c649893537671c28e90
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/04_Characters/_Shared/Models/BMAC/Scripts/ThirdParty/MagicaCloth.meta
vendored
Normal file
8
Assets/04_Characters/_Shared/Models/BMAC/Scripts/ThirdParty/MagicaCloth.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f50424043833af24ebf193a442e9583b
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class BoZo_MagicaClothCollider : MonoBehaviour
|
||||
{
|
||||
#if MAGICACLOTH2
|
||||
[SerializeField] Direction direction;
|
||||
[SerializeField] bool reverseDirection;
|
||||
[SerializeField] float length;
|
||||
[SerializeField] float startRadius;
|
||||
[SerializeField] float endRadius;
|
||||
[SerializeField] Vector3 center;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
var col = gameObject.AddComponent<MagicaCloth2.MagicaCapsuleCollider>();
|
||||
|
||||
switch (direction)
|
||||
{
|
||||
case Direction.X:
|
||||
col.direction = MagicaCloth2.MagicaCapsuleCollider.Direction.X;
|
||||
break;
|
||||
case Direction.Y:
|
||||
col.direction = MagicaCloth2.MagicaCapsuleCollider.Direction.Y;
|
||||
break;
|
||||
case Direction.Z:
|
||||
col.direction = MagicaCloth2.MagicaCapsuleCollider.Direction.Z;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
col.reverseDirection = reverseDirection;
|
||||
col.SetSize(startRadius, endRadius, length);
|
||||
col.center = center;
|
||||
col.UpdateParameters();
|
||||
}
|
||||
|
||||
private enum Direction { X, Y, Z }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63e462de7adcce6478830a8f97bd9a95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/ThirdParty/MagicaCloth/BoZo_MagicaClothCollider.cs
|
||||
uploadId: 853356
|
||||
165
Assets/04_Characters/_Shared/Models/BMAC/Scripts/ThirdParty/MagicaCloth/BoZo_MagicaClothSupport.cs
vendored
Normal file
165
Assets/04_Characters/_Shared/Models/BMAC/Scripts/ThirdParty/MagicaCloth/BoZo_MagicaClothSupport.cs
vendored
Normal file
@@ -0,0 +1,165 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class BoZo_MagicaClothSupport : MonoBehaviour, IOutfitExtension<Texture2D>
|
||||
{
|
||||
public const string id = "MagicaClothExtension";
|
||||
|
||||
bool initalized;
|
||||
private OutfitSystem system;
|
||||
public ClothType type;
|
||||
|
||||
[Header("Bones")]
|
||||
public bool boneReferenceByString;
|
||||
public List<Transform> rootBones;
|
||||
public List<string> rootBonesString;
|
||||
public float collisionSize = 0.025f;
|
||||
|
||||
[Header("Mesh")]
|
||||
public Texture2D influenceMap;
|
||||
[Range(0, 0.2f)] public float reductionSetting = 0.065f;
|
||||
|
||||
[Header("Preset")]
|
||||
public TextAsset clothPreset;
|
||||
|
||||
public List<Transform> transforms = new List<Transform>();
|
||||
|
||||
#if MAGICACLOTH2
|
||||
MagicaCloth2.MagicaCloth cloth;
|
||||
#endif
|
||||
|
||||
public Texture2D GetValue() => influenceMap;
|
||||
object IOutfitExtension.GetValue() => influenceMap;
|
||||
public System.Type GetValueType() => typeof(Texture2D);
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
system = GetComponentInParent<OutfitSystem>();
|
||||
if (system) system.OnRigChanged += OnCharacterMerged;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
system = GetComponentInParent<OutfitSystem>();
|
||||
if (system) system.OnRigChanged -= OnCharacterMerged;
|
||||
}
|
||||
|
||||
public void Initalize(OutfitSystem outfitSystem, Outfit outfit)
|
||||
{
|
||||
#if MAGICACLOTH2
|
||||
if (cloth) return;
|
||||
cloth = gameObject.AddComponent<MagicaCloth2.MagicaCloth>();
|
||||
|
||||
cloth.Initialize();
|
||||
cloth.DisableAutoBuild();
|
||||
#endif
|
||||
}
|
||||
|
||||
private void OnCharacterMerged(SkinnedMeshRenderer rig)
|
||||
{
|
||||
#if MAGICACLOTH2
|
||||
if (system == null) return;
|
||||
if (cloth) { Destroy(cloth); cloth = null; }
|
||||
|
||||
initalized = false;
|
||||
if (system.customMaps.ContainsKey(id)) influenceMap = system.customMaps[id];
|
||||
|
||||
Initalize(null, null);
|
||||
Execute(system, null);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Execute(OutfitSystem outfitSystem, Outfit outfit)
|
||||
{
|
||||
#if MAGICACLOTH2
|
||||
if (outfitSystem.mergeBase) return;
|
||||
if (initalized) return;
|
||||
switch (type)
|
||||
{
|
||||
case ClothType.Mesh:
|
||||
SetMeshCloth(outfitSystem, outfit);
|
||||
break;
|
||||
case ClothType.Bone:
|
||||
SetBoneCloth(outfitSystem, outfit);
|
||||
break;
|
||||
case ClothType.Spring:
|
||||
SetBoneCloth(outfitSystem, outfit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
initalized = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if MAGICACLOTH2
|
||||
private void SetMeshCloth(OutfitSystem outfitSystem, Outfit outfit)
|
||||
{
|
||||
var sdata = cloth.SerializeData;
|
||||
|
||||
SkinnedMeshRenderer smr = null;
|
||||
|
||||
if (outfit) smr = outfit.skinnedRenderer;
|
||||
else smr = outfitSystem.GetCharacterBody();
|
||||
|
||||
sdata.sourceRenderers.Add(smr);
|
||||
|
||||
sdata.reductionSetting.shapeDistance = reductionSetting;
|
||||
|
||||
sdata.paintMode = MagicaCloth2.ClothSerializeData.PaintMode.Texture_Fixed_Move;
|
||||
sdata.paintMaps.Add(influenceMap);
|
||||
|
||||
if (clothPreset) cloth.SerializeData.ImportJson(clothPreset.ToString());
|
||||
sdata.radius = new MagicaCloth2.CurveSerializeData(collisionSize);
|
||||
|
||||
var col = outfitSystem.GetClothColliders();
|
||||
sdata.colliderCollisionConstraint.colliderList = col.ToList();
|
||||
outfitSystem.RebindBody();
|
||||
cloth.enabled = true;
|
||||
cloth.BuildAndRun();
|
||||
}
|
||||
|
||||
private void SetBoneCloth(OutfitSystem outfitSystem, Outfit outfit)
|
||||
{
|
||||
var sdata = cloth.SerializeData;
|
||||
if (type == ClothType.Bone) sdata.clothType = MagicaCloth2.ClothProcess.ClothType.BoneCloth;
|
||||
if (type == ClothType.Spring) sdata.clothType = MagicaCloth2.ClothProcess.ClothType.BoneSpring;
|
||||
|
||||
|
||||
SkinnedMeshRenderer smr = null;
|
||||
|
||||
if (outfit) smr = outfit.skinnedRenderer;
|
||||
else smr = outfitSystem.GetCharacterBody();
|
||||
|
||||
if (rootBonesString.Count != 0)
|
||||
{
|
||||
sdata.rootBones = smr.bones.Where(bone => rootBonesString.Contains(bone.name)).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
sdata.rootBones = rootBones;
|
||||
}
|
||||
|
||||
if (clothPreset) cloth.SerializeData.ImportJson(clothPreset.ToString());
|
||||
sdata.radius = new MagicaCloth2.CurveSerializeData(collisionSize);
|
||||
|
||||
var col = outfitSystem.GetClothColliders();
|
||||
sdata.colliderCollisionConstraint.colliderList = col.ToList();
|
||||
|
||||
cloth.enabled = true;
|
||||
cloth.BuildAndRun();
|
||||
}
|
||||
#endif
|
||||
|
||||
public string GetID()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public enum ClothType { Mesh, Bone, Spring }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1d2d34769e54eb14398b24dc32eea2c5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/ThirdParty/MagicaCloth/BoZo_MagicaClothSupport.cs
|
||||
uploadId: 853356
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99584cca56fc61e408f2d14378fa2059
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/ThirdParty/MagicaCloth/BoZo_Preset_LongHair.json
|
||||
uploadId: 853356
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 433936ba35faf404f921f4a7966526f1
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/ThirdParty/MagicaCloth/BoZo_Preset_ShortHair.json
|
||||
uploadId: 853356
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,14 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e136f8a162b7c3f419623d4d87104bb7
|
||||
TextScriptImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/ThirdParty/MagicaCloth/BoZo_Preset_Skirt.json
|
||||
uploadId: 853356
|
||||
8
Assets/04_Characters/_Shared/Models/BMAC/Scripts/ThirdParty/MagicaCloth/Editor.meta
vendored
Normal file
8
Assets/04_Characters/_Shared/Models/BMAC/Scripts/ThirdParty/MagicaCloth/Editor.meta
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a24dc9a5633fd9449ac1e9c528ae1eb7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
|
||||
[CustomEditor(typeof(BoZo_MagicaClothSupport))]
|
||||
[CanEditMultipleObjects]
|
||||
public class BoZo_MagicaClothSupportEditor : Editor
|
||||
{
|
||||
public override void OnInspectorGUI()
|
||||
{
|
||||
#if MAGICACLOTH2
|
||||
BoZo_MagicaClothSupport ob = (BoZo_MagicaClothSupport)target;
|
||||
Color originalColor = GUI.color;
|
||||
|
||||
serializedObject.Update();
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("type"));
|
||||
|
||||
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
if (ob.type == BoZo_MagicaClothSupport.ClothType.Mesh)
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("influenceMap"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("reductionSetting"));
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("collisionSize"));
|
||||
}
|
||||
else if (ob.type == BoZo_MagicaClothSupport.ClothType.Bone || ob.type == BoZo_MagicaClothSupport.ClothType.Spring)
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("boneReferenceByString"));
|
||||
if (ob.boneReferenceByString)
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("rootBonesString"));
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("rootBones"));
|
||||
}
|
||||
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("collisionSize"));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space(10);
|
||||
|
||||
EditorGUILayout.PropertyField(serializedObject.FindProperty("clothPreset"));
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
//base.OnInspectorGUI();
|
||||
return;
|
||||
#endif
|
||||
EditorGUILayout.LabelField("MagicaCloth2 Not Installed");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d1433a1d9f4cc134a8500cb9c5b2be9c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
AssetOrigin:
|
||||
serializedVersion: 1
|
||||
productId: 323550
|
||||
packageName: 'BoZo: Modular Anime Characters - Base Pack'
|
||||
packageVersion: 1.7.4
|
||||
assetPath: Assets/BoZo_ModularAnimeCharacters/Scripts/ThirdParty/MagicaCloth/Editor/BoZo_MagicaClothSupportEditor.cs
|
||||
uploadId: 853356
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class ToonFaceRelay : MonoBehaviour
|
||||
{
|
||||
private ToonFacialAnimator animator;
|
||||
|
||||
|
||||
private void Start()
|
||||
{
|
||||
animator = GetComponentInParent<ToonFacialAnimator>();
|
||||
}
|
||||
public void SetFace(int preset)
|
||||
{
|
||||
if (animator == null) return;
|
||||
animator.SetFace(preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e69a102f430316f44af6ccf14ad2b401
|
||||
@@ -0,0 +1,136 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Bozo.AnimeCharacters
|
||||
{
|
||||
public class ToonFacialAnimator : MonoBehaviour
|
||||
{
|
||||
|
||||
public Vector3 commonLeftEyeOffset;
|
||||
public Vector3 commonRightEyeOffset;
|
||||
public Vector3 commonMouthOffset;
|
||||
|
||||
public float eyeRotation;
|
||||
public float mouthRotation;
|
||||
public Vector3 spriteScale;
|
||||
|
||||
|
||||
private SpriteRenderer leftEye;
|
||||
private SpriteRenderer rightEye;
|
||||
private SpriteRenderer mouth;
|
||||
|
||||
[SerializeField] ToonFacePreset[] facePresets;
|
||||
|
||||
[SerializeField] SkinnedMeshRenderer rigOverride;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
GenerateFace();
|
||||
}
|
||||
|
||||
[ContextMenu("test")]
|
||||
public void test()
|
||||
{
|
||||
SetFace(0);
|
||||
}
|
||||
|
||||
private void GenerateFace()
|
||||
{
|
||||
|
||||
Transform headBone = null;
|
||||
Transform eyeBoneL = null;
|
||||
Transform eyeBoneR = null;
|
||||
|
||||
if (rigOverride)
|
||||
{
|
||||
foreach (var bone in rigOverride.bones)
|
||||
{
|
||||
if (bone.name == "head"){ headBone = bone; }
|
||||
if (bone.name == "eyeRoot_l") { eyeBoneL = bone; }
|
||||
if (bone.name == "eyeRoot_r") { eyeBoneR = bone; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var system = GetComponentInParent<OutfitSystem>();
|
||||
if (!system) system = GetComponentInChildren<OutfitSystem>();
|
||||
|
||||
|
||||
|
||||
headBone = system.GetBones()["head"];
|
||||
eyeBoneL = system.GetBones()["eyeRoot_l"];
|
||||
eyeBoneR = system.GetBones()["eyeRoot_r"];
|
||||
}
|
||||
|
||||
|
||||
leftEye = new GameObject("ToonLeftEye", typeof(SpriteRenderer)).GetComponent<SpriteRenderer>();
|
||||
rightEye = new GameObject("ToonRightEye", typeof(SpriteRenderer)).GetComponent<SpriteRenderer>();
|
||||
mouth = new GameObject("ToonMouth", typeof(SpriteRenderer)).GetComponent<SpriteRenderer>();
|
||||
|
||||
|
||||
leftEye.transform.parent = eyeBoneL;
|
||||
rightEye.transform.parent = eyeBoneR;
|
||||
mouth.transform.parent = headBone;
|
||||
|
||||
leftEye.transform.localPosition = commonLeftEyeOffset;
|
||||
leftEye.transform.localScale = spriteScale;
|
||||
leftEye.transform.localRotation = Quaternion.Euler(0, eyeRotation, 0);
|
||||
|
||||
rightEye.transform.localPosition = commonRightEyeOffset;
|
||||
rightEye.transform.localScale = spriteScale;
|
||||
rightEye.transform.localRotation = Quaternion.Euler(0, -eyeRotation, 0);
|
||||
|
||||
mouth.transform.localPosition = commonMouthOffset;
|
||||
mouth.transform.localScale = spriteScale;
|
||||
mouth.transform.localRotation = Quaternion.Euler(mouthRotation, 0, 0);
|
||||
}
|
||||
|
||||
public void SetFace(int preset)
|
||||
{
|
||||
if(leftEye == null || rightEye == null || mouth == null)
|
||||
{
|
||||
GenerateFace();
|
||||
}
|
||||
|
||||
var set = facePresets[preset];
|
||||
|
||||
leftEye.sprite = set.leftEyeSprite;
|
||||
leftEye.flipX = set.leftEyeFlip;
|
||||
leftEye.transform.localPosition = set.leftEyeOffset + commonLeftEyeOffset;
|
||||
leftEye.transform.localScale = set.leftEyeScale + spriteScale;
|
||||
|
||||
rightEye.sprite = set.rightEyeSprite;
|
||||
rightEye.flipX = set.rightEyeFlip;
|
||||
rightEye.transform.localPosition = set.rightEyeOffset + commonRightEyeOffset;
|
||||
rightEye.transform.localScale = set.rightEyeScale + spriteScale;
|
||||
|
||||
mouth.sprite = set.mouthSprite;
|
||||
mouth.flipX = set.mouthFlip;
|
||||
mouth.transform.localPosition = set.mouthOffset + commonMouthOffset;
|
||||
mouth.transform.localScale = set.mouthScale + spriteScale;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public class ToonFacePreset
|
||||
{
|
||||
public string presetName;
|
||||
|
||||
public Sprite leftEyeSprite;
|
||||
public bool leftEyeFlip = true;
|
||||
public Vector3 leftEyeOffset;
|
||||
public Vector3 leftEyeScale = Vector3.zero;
|
||||
|
||||
|
||||
public Sprite rightEyeSprite;
|
||||
public bool rightEyeFlip = false;
|
||||
public Vector3 rightEyeOffset;
|
||||
public Vector3 rightEyeScale = Vector3.zero;
|
||||
|
||||
|
||||
public Sprite mouthSprite;
|
||||
public bool mouthFlip = true;
|
||||
public Vector3 mouthOffset;
|
||||
public Vector3 mouthScale = Vector3.zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7c34edd43158e704a831709334750f64
|
||||
Reference in New Issue
Block a user