squash commits

This commit is contained in:
2025-01-07 18:54:46 +02:00
parent 855639487b
commit 62c0a21987
3632 changed files with 708443 additions and 999 deletions
@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 8a1005fa5f68007458d03ea1b75105a9
folderAsset: yes
timeCreated: 1486762311
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,186 @@
using UnityEngine;
using System.Collections.Generic;
namespace UMA.CharacterSystem
{
//The following classes are used by the pUMATextRecipe extension but also need to be available in RecipeEditor
public enum recipeTypeOpts { Standard, WardrobeItem, DynamicCharacterAvatar, WardrobeCollection }
[System.Serializable]
public class WardrobeRecipeThumb
{
public string race = "";
public string filename = "";
public Sprite thumb = null;
public WardrobeRecipeThumb()
{
}
public WardrobeRecipeThumb(string n_race)
{
race = n_race;
}
public WardrobeRecipeThumb(string n_race, Sprite n_thumb)
{
race = n_race;
filename = n_thumb.name;
thumb = n_thumb;
}
}
[System.Serializable]
public class WardrobeSettings
{
public string slot;
public string recipe;
public WardrobeSettings()
{
}
public WardrobeSettings(string _slot, string _recipe)
{
slot = _slot;
recipe = _recipe;
}
}
[System.Serializable]
public class WardrobeSet
{
public string targetRace = "";
public List<WardrobeSettings> wardrobeSet = new List<WardrobeSettings>();
public WardrobeSet() { }
public WardrobeSet(string race)
{
targetRace = race;
wardrobeSet = new List<WardrobeSettings>();
}
public WardrobeSet(string race, List<WardrobeSettings> settings)
{
targetRace = race;
wardrobeSet = settings;
}
}
[System.Serializable]
public class WardrobeCollectionList
{
public List<WardrobeSet> sets = new List<WardrobeSet>();
public List<WardrobeSettings> this[string key]
{
get
{
return GetValue(key);
}
set
{
SetValue(key, value);
}
}
public void Clear()
{
sets = new List<WardrobeSet>();
}
public bool Contains(string race)
{
bool contained = false;
for (int i = 0; i < sets.Count; i++)
{
if (sets[i].targetRace == race)
{
contained = true;
break;
}
}
return contained;
}
public void Add(string race)
{
if (!Contains(race))
{
sets.Add(new WardrobeSet(race));
}
}
public void Add(string race, List<WardrobeSettings> settings)
{
if (!Contains(race))
{
sets.Add(new WardrobeSet(race, settings));
}
}
public void Remove(string race)
{
if (Contains(race))
{
var newSets = new List<WardrobeSet>(sets.Count - 1);
for (int i = 0; i < sets.Count; i++)
{
if (sets[i].targetRace != race)
{
newSets.Add(new WardrobeSet(sets[i].targetRace, sets[i].wardrobeSet));
}
}
sets = newSets;
}
}
public List<string> GetAllRacesInCollection()
{
List<string> ret = new List<string>();
for (int i = 0; i < sets.Count; i++)
{
ret.Add(sets[i].targetRace);
}
return ret;
}
public List<string> GetAllRecipeNamesInCollection(string forRace = "")
{
var collectionNames = new List<string>();
for (int i = 0; i < sets.Count; i++)
{
if (forRace != "" && sets[i].targetRace != forRace)
{
continue;
}
for (int si = 0; si < sets[i].wardrobeSet.Count; si++)
{
if (sets[i].wardrobeSet[si].recipe != "")
{
collectionNames.Add(sets[i].wardrobeSet[si].recipe);
}
}
}
return collectionNames;
}
protected List<WardrobeSettings> GetValue(string key)
{
for (int i = 0; i < sets.Count; i++)
{
if (sets[i].targetRace == key)
{
return sets[i].wardrobeSet;
}
}
return new List<WardrobeSettings>();
}
protected void SetValue(string key, List<WardrobeSettings> value)
{
for (int i = 0; i < sets.Count; i++)
{
if (sets[i].targetRace == key)
{
sets[i].wardrobeSet = value;
}
}
}
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 587a3fe806c16ba4faf96a3fe0b4b10a
timeCreated: 1481748839
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/DCSStandardTypes.cs
uploadId: 679826
@@ -0,0 +1,35 @@
using UnityEngine;
using System.Collections.Generic;
namespace UMA.CharacterSystem
{
public class DynamicCharacterSystemBase : MonoBehaviour
{
//just here really so that there is something that can be assigned in UMAContextBase.
//We can make some methods available here tho
public virtual void Awake() { }
public virtual void OnEnable() { }
public virtual void Start() { }
public virtual void Refresh(bool forceUpdateRaceLibrary = true, string bundleToGather = "") { }
public virtual void Update() { }
public virtual void Init() { }
//Unfortunately we cant do anything useful that uses UMATextRecipe because that doesn't exist here
//but we can define some methods that can be overidden so they can be used
//except we BLOODY CANT because UMATextRecipe doesn't exist at this point
public virtual UMARecipeBase GetBaseRecipe(string filename, bool dynamicallyAdd = true) { return null; }
//Again for RecipeEditor to be able to get usable info
public virtual List<string> GetRecipeNamesForRaceSlot(string race, string slot) { return null; }
//Again for RecipeEditor to be able to get usable info
public virtual List<UMARecipeBase> GetRecipesForRaceSlot(string race, string slot) { return null; }
//Again for RecipeEditor to get info
public virtual bool CheckRecipeAvailability(string recipeName) { return true; }
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: f4f544908028e7141bd9f915691e5b5a
timeCreated: 1472850643
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/DynamicCharacterSystemBase.cs
uploadId: 679826
@@ -0,0 +1,20 @@
using System;
namespace UMA.CharacterSystem
{
public static class EnumExtensions
{
public static bool HasFlagSet(this Enum self, Enum flag)
{
if (self.GetType() != flag.GetType())
{
throw new ArgumentException("HasFlag : Flag is not of the type of Enum");
}
var selfValue = Convert.ToUInt64(self);
var flagValue = Convert.ToUInt64(flag);
return (selfValue & flagValue) == flagValue;
}
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 784526a99b0fa4d4fa81fa5c96df92f0
timeCreated: 1481654922
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/EnumExtensions.cs
uploadId: 679826
@@ -0,0 +1,9 @@
using UnityEngine;
namespace UMA.CharacterSystem
{
public class EnumFlagsAttribute : PropertyAttribute
{
public EnumFlagsAttribute() { }
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 96ef98699e166d4459eeb1b38a5a9c07
timeCreated: 1481654940
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/EnumFlagsAttribute.cs
uploadId: 679826
@@ -0,0 +1,98 @@
using System;
using System.Text;
namespace UMA.CharacterSystem
{
public static class UMAExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
public static string ToTitleCase(this String str)
{
char[] sep = { ' ' };
string[] words = str.Split(sep,StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < words.Length; i++)
{
string word = words[i];
if (word.Length > 2)
{
string s1 = word.Substring(0, 1).ToUpper();
string s2 = word.Substring(1, word.Length - 1).ToLower();
sb.Append(s1);
sb.Append(s2);
}
else
{
sb.Append(word.ToUpper());
}
}
return sb.ToString();
}
public static string[] SplitCamelCase(this String str)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (i > 0 && char.IsUpper(c))
{
sb.Append('|');
}
if (i == 0)
{
c = char.ToUpper(c);
}
sb.Append(c);
}
return sb.ToString().Split('|');
}
public static string MenuCamelCase(this String str)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.Length; i++)
{
char c = str[i];
if (i > 0 && char.IsUpper(c))
{
sb.Append('/');
}
if (i == 0)
{
c = char.ToUpper(c);
}
sb.Append(c);
}
return sb.ToString();
}
public static string BreakupCamelCase(this String str)
{
StringBuilder sb = new StringBuilder();
for (int i=0;i<str.Length;i++)
{
char c = str[i];
if (i > 0 && char.IsUpper(c))
{
sb.Append(' ');
}
if (i==0)
{
c = char.ToUpper(c);
}
sb.Append(c);
}
return sb.ToString();
}
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 450251df66e2314469043cdcabdd62ca
timeCreated: 1457986327
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/ExtensionMethods.cs
uploadId: 679826
@@ -0,0 +1,115 @@
using UnityEngine;
namespace UMA.CharacterSystem
{
public class UMAExtendedAvatar : UMADynamicAvatar
{
#if UNITY_EDITOR
public bool showPlaceholder = true;
private Mesh previewMesh;
public enum PreviewModel {Male, Female}
public PreviewModel previewModel;
public Color previewColor = Color.grey;
private PreviewModel lastPreviewModel;
private Material mat;
#endif
// Draws Placeholder Model
#if UNITY_EDITOR
void OnDrawGizmos()
{
// Build Shader
if (!mat)
{
Shader shader = Shader.Find ("Hidden/Internal-Colored");
mat = new Material (shader);
mat.hideFlags = HideFlags.HideAndDontSave;
}
if(showPlaceholder){
// Check for mesh Change
if(!previewMesh || lastPreviewModel != previewModel)
{
LoadMesh();
}
mat.color = previewColor;
if(!Application.isPlaying && previewMesh != null)
{
mat.SetPass(0);
Graphics.DrawMeshNow(previewMesh, Matrix4x4.TRS(transform.position, transform.rotation * Quaternion.Euler(-90,180,0), new Vector3(0.88f,0.88f,0.88f)));
}
lastPreviewModel = previewModel;
}
}
void LoadMesh()
{
//search string finds both male and female!
string[] assets = UnityEditor.AssetDatabase.FindAssets("t:Model Male_Unified");
string male = "";
string female = "";
GameObject model = null;
for (int i = 0; i < assets.Length; i++)
{
string guid = assets[i];
string thePath = UnityEditor.AssetDatabase.GUIDToAssetPath(guid);
if (thePath.ToLower().Contains("female"))
{
female = thePath;
}
else
{
male = thePath;
}
}
if (previewModel == PreviewModel.Male)
{
if(!string.IsNullOrEmpty(male))
{
model = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(male);
}
else
{
if(Debug.isDebugBuild)
{
Debug.LogWarning("Could not load Male_Unified model for preview!");
}
}
}
if (previewModel == PreviewModel.Female)
{
if (!string.IsNullOrEmpty(female))
{
model = UnityEditor.AssetDatabase.LoadAssetAtPath<GameObject>(female);
}
else
{
if (Debug.isDebugBuild)
{
Debug.LogWarning("Could not load Female_Unified model for preview!");
}
}
}
if (model != null)
{
previewMesh = model.GetComponentInChildren<SkinnedMeshRenderer>().sharedMesh;
}
else
{
if (Debug.isDebugBuild)
{
Debug.LogWarning("Preview Model not found on object " + gameObject.name);
}
}
}
#endif
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 2775cfae9e4ac344faa2bda63c1a86b0
timeCreated: 1484950941
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/UMAExtendedAvatar.cs
uploadId: 679826
@@ -0,0 +1,569 @@
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using System.Collections.Generic;
using System.Linq;
namespace UMA
{
public partial class RaceData
{
[Tooltip("This should be set to true for Blender FBX models")]
public bool FixupRotations = true;
[Tooltip("UMA Text recipe that holds the slots and overlays that are the default set up for this race.")]
public UMARecipeBase baseRaceRecipe;
[Tooltip("Wardobe slots that wardrobe recipes can be assigned to.")]
public List<string> wardrobeSlots = new List<string>(){
"None",
"Face",
"Hair",
"Complexion",
"Eyebrows",
"Beard",
"Ears",
"Helmet",
"Shoulders",
"Chest",
"Arms",
"Hands",
"Waist",
"Legs",
"Feet"
};
private UMAPackedRecipeBase.UMAPackRecipe packedRecipe;
private UMAData.UMARecipe unPackedRecipe;
private Dictionary<string, float> RaceDNAValues = new Dictionary<string, float>();
private List<OverlayColorData> RaceColorValues = new List<OverlayColorData>();
//UMA26 we want to depricate this- how much do we need to worry about the fact that users could do backwardsCompatibleWith.Add/Remove via scripting before?
[Obsolete("[RaceData backwardsCompatibleWith is deprecated and will be removed in a future version. Please use RaceData.CrossCompatibleRaces instead.")]
public List<string> backwardsCompatibleWith = new List<string>();
//CrossCompatibilitySettings allows this race to wear wardrobe slots from another race, if this race has a wardrobe slot that the recipe is set to.
//You can further configure the compatibility settings for each compatible race to define 'equivalent' slotdatas in the races' base recipes. For example you could define
//that this races 'highpolyMaleChest' slotdata in its base recipe is equivalent to HumanMales 'MaleChest' slot data in its base recipe. This would mean that any recipes which hid or applied an overlay to 'MaleChest'
//would hide or apply an overlay to 'highPolyMaleChest' on this race. If 'Overlays Match' is unchecked then overlays in a recipe wont be applied.
[SerializeField]
private CrossCompatibilitySettingsList _crossCompatibilitySettings = new CrossCompatibilitySettingsList();
public RaceThumbnails raceThumbnails;
public List<OverlayColorData> GetDefaultColors()
{
if (RaceColorValues.Count > 0)
{
return RaceColorValues;
}
if (GetPackedRecipe() == null)
{
return RaceColorValues;
}
OverlayColorData[] colors = UMAPackedRecipeBase.UnpackColors(packedRecipe);
RaceColorValues.AddRange(colors);
return RaceColorValues;
}
public UMAPackedRecipeBase.UMAPackRecipe GetPackedRecipe()
{
if (packedRecipe != null)
{
return packedRecipe;
}
packedRecipe = (baseRaceRecipe as UMATextRecipe).PackedLoad(UMAContextBase.Instance);
return packedRecipe;
}
private Dictionary<string,List<string>> _usedBlendshapeNames = null;
public Dictionary<string, List<string>> GetDNAToBlendShapes()
{
if (_usedBlendshapeNames != null)
{
return _usedBlendshapeNames;
}
_usedBlendshapeNames = new Dictionary<string, List<string>>();
for(int i=0; i< dnaConverterList.Length; i++)
{
var plugins = dnaConverterList[i].GetPlugins();
for (int j=0;j< plugins.Count; j++)
{
if (plugins[j] is BlendshapeDNAConverterPlugin)
{
var plugin = plugins[j] as BlendshapeDNAConverterPlugin;
plugin.blendshapeDNAConverters.ForEach((converter) =>
{
converter.UsedDNANames.ForEach((name) =>
{
if (_usedBlendshapeNames.ContainsKey(name) == false)
{
_usedBlendshapeNames.Add(name, new List<string>());
}
_usedBlendshapeNames[name].Add(converter.blendshapeToApply);
});
});
}
}
}
return _usedBlendshapeNames;
}
public Dictionary<string, float> GetDefaultDNA()
{
if (GetPackedRecipe() == null)
{
return RaceDNAValues;
}
if (RaceDNAValues.Count == 0)
{
List<UMADnaBase> dna = UMAPackedRecipeBase.UnPackDNA(packedRecipe.packedDna);
for (int i1 = 0; i1 < dna.Count; i1++)
{
UMADnaBase udb = dna[i1];
for (int i=0;i < udb.Names.Length;i++)
{
if (RaceDNAValues.ContainsKey(udb.Names[i]) == false)
{
RaceDNAValues.Add(udb.Names[i], udb.Values[i]);
}
}
}
}
return RaceDNAValues;
}
//Not sure if this is needed I think I could just set the wardrobe slots property to be this by default?
public void AddDefaultWardrobeSlots(bool forceOverride = false)
{
if (wardrobeSlots.Count == 0 || forceOverride)
{
wardrobeSlots = new List<string>() {
"None",
"Face",
"Hair",
"Complexion",
"Eyebrows",
"Beard",
"Ears",
"Helmet",
"Shoulders",
"Chest",
"Arms",
"Hands",
"Waist",
"Legs",
"Feet"
};
}
}
/// <summary>
/// Validates the wardrobe slots.
/// </summary>
/// <returns><c>true</c>, if wardrobe slots was validated, <c>false</c> otherwise.</returns>
/// <param name="setToDefault">If set to <c>true</c> wardrobeSlots are set to default (returns true).</param>
public bool ValidateWardrobeSlots(bool setToDefault = false)
{
if (wardrobeSlots.Count == 0)
{
AddDefaultWardrobeSlots(setToDefault);
return setToDefault;
}
return true;
}
//For backwards compatibility
[Obsolete("findBackwardsCompatibleWith has been depricated and will be removed in a future version. Please use 'IsCrossCompatibleWith' instead.")]
public bool findBackwardsCompatibleWith(List<string> compatibleStrings)
{
return IsCrossCompatibleWith(compatibleStrings);
}
/// <summary>
/// Given a raceNames returns whether this race has been set to be 'cross compatible' with that race.
/// </summary>
public bool IsCrossCompatibleWith(RaceData compatibleRace)
{
return GetCrossCompatibleRaces().Contains(compatibleRace.raceName);
}
/// <summary>
/// Given a raceNames returns whether this race has been set to be 'cross compatible' with that race.
/// </summary>
public bool IsCrossCompatibleWith(string compatibleString)
{
return GetCrossCompatibleRaces().Contains(compatibleString);
}
/// <summary>
/// Given a list of raceNames returns whether this race has been set to be 'cross compatible' with any of those races.
/// </summary>
public bool IsCrossCompatibleWith(List<string> compatibleStrings)
{
for (int i = 0; i < compatibleStrings.Count; i++)
{
string val = compatibleStrings[i];
if (GetCrossCompatibleRaces().Contains(val))
{
return true;
}
}
return false;
}
/// <summary>
/// backwards compatibility: Updates any Races from before _crossCompatibilitySettings so their backwards compatible races are added automatically. If the race is being inspected these changes are saved - remove in a future version
/// </summary>
private void UpdateOldRace()
{
#pragma warning disable 618
if (_crossCompatibilitySettings.settingsData.Count == 0 && backwardsCompatibleWith.Count > 0)
{
SetCrossCompatibleRaces(backwardsCompatibleWith);
//then clear the backwardsCompatibleWith list and save the asset- the user wont be able to use 'backwardsCompatibleWith'
//but they will have been shown a warning if their scripts access the field directly
#if UNITY_EDITOR
if (Debug.isDebugBuild)
{
Debug.Log("RaceData for " + raceName + " updated its backwardsCompatibleWith value to the new CrossCompatibilitySettings. All good.");
}
if (!Application.isPlaying)
{
//Debug.Log("RaceData for " + raceName + " updated its backwardsCompatibleWith value to the new CrossCompatibilitySettings. All good.");
backwardsCompatibleWith.Clear();
EditorUtility.SetDirty(this);
AssetDatabase.SaveAssets();
}
#endif
}
#pragma warning restore 618
}
/// <summary>
/// Returns the list of raceNames that this race has set to be 'cross compatible' with
/// </summary>
public List<string> GetCrossCompatibleRaces()
{
UpdateOldRace();
List<string> ccRaces = new List<string>();
for (int i = 0; i < _crossCompatibilitySettings.settingsData.Count; i++)
{
ccRaces.Add(_crossCompatibilitySettings.settingsData[i].ccRace);
}
return ccRaces;
}
/// <summary>
/// Sets the races that this race can be 'cross compatible with.
/// </summary>
public void SetCrossCompatibleRaces(List<string> ccRaces)
{
for (int i = 0; i < ccRaces.Count; i++)
{
_crossCompatibilitySettings.Add(ccRaces[i]);
}
//then remove any that were not in the list
List<string> racesToRemove = new List<string>();
for (int i = 0; i < _crossCompatibilitySettings.settingsData.Count; i++)
{
if (!ccRaces.Contains(_crossCompatibilitySettings.settingsData[i].ccRace))
{
racesToRemove.Add(_crossCompatibilitySettings.settingsData[i].ccRace);
}
}
_crossCompatibilitySettings.Remove(racesToRemove);
}
/// <summary>
/// Gets the cross compatibility settings that have been defined for this race
/// </summary>
protected List<CrossCompatibilityData> GetSettingsFor(string crossCompatibleRace)
{
for (int i = 0; i < _crossCompatibilitySettings.settingsData.Count; i++)
{
if (_crossCompatibilitySettings.settingsData[i].ccRace == crossCompatibleRace)
{
return _crossCompatibilitySettings.settingsData[i].ccSettings;
}
}
return null;
}
/// <summary>
/// If this race has been defined as being 'cross compatible' with any of the given races, this will return the slot in this races base recipe that has been defined as
/// equivalent to the given slot in the given races (optionally only returning a value if the overlays have ALSO been defined as matching)
/// </summary>
/// <param name="races">The cross compatible races to check. i.e. is this race defined as compatible with any of these races</param>
/// <param name="crossCompatibleSlot">The slot to check. i.e. if this race IS defined as compatible with one of the above races, does it define that it has a slot that is equivalent to the given slot</param>
/// <param name="overlaysMustMatch">If this is true, an equivalent slot will only be returned if it has also been defined as having Overlay scales that match the cross compatible race</param>
/// <returns></returns>
public string FindEquivalentSlot(List<string> races, string crossCompatibleSlot, bool overlaysMustMatch = true)
{
for (int i = 0; i < races.Count; i++)
{
var foundEquivalent = FindEquivalentSlot(races[i], crossCompatibleSlot, overlaysMustMatch);
if (foundEquivalent != "")
{
return foundEquivalent;
}
}
return "";
}
/// <param name="race">The cross compatible race to check. i.e. is this race defined as compatible with the given race</param>
public string FindEquivalentSlot(string race, string crossCompatibleSlot, bool overlaysMustMatch = true)
{
for (int i = 0; i < _crossCompatibilitySettings.settingsData.Count; i++)
{
if (_crossCompatibilitySettings.settingsData[i].ccRace == race)
{
return _crossCompatibilitySettings.settingsData[i].GetEquivalentSlot(crossCompatibleSlot, overlaysMustMatch);
}
}
return "";
}
/// <summary>
/// Searches this races Cross compatibility settings for the given slot and returns whether its equivalent slot (if defined) has been defined as having compatible overlays
/// </summary>
public bool GetOverlayCompatibility(string crossCompatibleSlot)
{
for (int i = 0; i < _crossCompatibilitySettings.settingsData.Count; i++)
{
var compatibilityForThisRace = _crossCompatibilitySettings.settingsData[i].GetOverlayCompatibility(crossCompatibleSlot);
if (compatibilityForThisRace != -1)
{
return compatibilityForThisRace == 1 ? true : false;
}
}
return false;
}
/// <summary>
/// Searches this races Cross compatibility settings for the given race to find the given slot and returns whether its equivalent slot (if defined) has been defined as having compatible overlays
/// </summary>
public bool GetOverlayCompatibility(string race, string crossCompatibleSlot)
{
for (int i = 0; i < _crossCompatibilitySettings.settingsData.Count; i++)
{
if (_crossCompatibilitySettings.settingsData[i].ccRace == race)
{
return _crossCompatibilitySettings.settingsData[i].GetOverlayCompatibility(crossCompatibleSlot) == 1 ? true : false;
}
}
return false;
}
#region SpecialTypes
//new classes for CrossCompatibilitySettings
//allows the user to define that a given slot in this races base recipe is equal to the named slot in the backwards compatible races base recipe
[System.Serializable]
protected class CrossCompatibilityData
{
//the slot in this race's baseRaceRecipe
public string raceSlot = "";
//the slot in the other races baseRaceRecipe that should be considered equivalent
public string compatibleRaceSlot = "";
//are the overlay resolutions the same, if not overlays in recipes on the compatible race will not be copied over
public bool overlaysMatch;
public CrossCompatibilityData() { }
public CrossCompatibilityData(string _raceSlot, string _compatibleRaceSlot)
{
raceSlot = _raceSlot;
compatibleRaceSlot = _compatibleRaceSlot;
}
public CrossCompatibilityData(string _raceSlot, string _compatibleRaceSlot, bool _overlaysMatch)
{
raceSlot = _raceSlot;
compatibleRaceSlot = _compatibleRaceSlot;
overlaysMatch = _overlaysMatch;
}
}
[System.Serializable]
protected class CrossCompatibilitySettings
{
public string ccRace = "";
public List<CrossCompatibilityData> ccSettings = new List<CrossCompatibilityData>();
public CrossCompatibilitySettings() { }
public CrossCompatibilitySettings(string race)
{
ccRace = race;
}
public CrossCompatibilitySettings(string race, List<CrossCompatibilityData> settings)
{
ccRace = race;
ccSettings = settings;
}
/// <summary>
/// Returns the slot in the COMPATIBLE race that has been defined as equivalent to the given slot from THIS race
/// </summary>
public string GetCompatibleRacesSlot(string thisRacesSlot)
{
for (int i = 0; i < ccSettings.Count; i++)
{
if (ccSettings[i].raceSlot == thisRacesSlot)
{
return ccSettings[i].compatibleRaceSlot;
}
}
return "";
}
/// <summary>
/// Returns the slot in THIS race that has been defined as equivalent to the given slot from the COMPATIBLE race
/// </summary>
public string GetEquivalentSlot(string compatibleSlot, bool overlaysMustMatch = true)
{
for (int i = 0; i < ccSettings.Count; i++)
{
if (ccSettings[i].compatibleRaceSlot == compatibleSlot)
{
if ((overlaysMustMatch == true && ccSettings[i].overlaysMatch == true) || overlaysMustMatch == false)
{
return ccSettings[i].raceSlot;
}
}
}
return "";
}
/// <summary>
/// Returns whether the given slot in THIS race has been defined as having compatible overlays with the given slot from the COMPATIBLE race
/// </summary>
public int GetOverlayCompatibility(string compatibleRaceSlot)
{
for (int i = 0; i < ccSettings.Count; i++)
{
if (ccSettings[i].compatibleRaceSlot == compatibleRaceSlot)
{
return ccSettings[i].overlaysMatch ? 1 : 0;
}
}
return -1;
}
/// <summary>
/// Defines that a slot in THIS race is compatible with the given slot from the COMPATIBLE race (optionally defining overlay compatibility as false)
/// </summary>
public void SetEquivalentSlot(string thisRacesSlot, string compatibleRacesSlot = "", bool overlayCompatibility = true)
{
bool found = false;
for (int i = 0; i < ccSettings.Count; i++)
{
if (ccSettings[i].raceSlot == thisRacesSlot)
{
ccSettings[i].compatibleRaceSlot = compatibleRacesSlot;
ccSettings[i].overlaysMatch = overlayCompatibility;
found = true;
}
}
if (!found)
{
ccSettings.Add(new CrossCompatibilityData(thisRacesSlot, compatibleRacesSlot, overlayCompatibility));
}
}
}
[System.Serializable]
protected class CrossCompatibilitySettingsList
{
public List<CrossCompatibilitySettings> settingsData = new List<CrossCompatibilitySettings>();
public bool Contains(string crossCompatibleRace)
{
for (int i = 0; i < settingsData.Count; i++)
{
if (settingsData[i].ccRace == crossCompatibleRace)
{
return true;
}
}
return false;
}
public void Add(string crossCompatibleRace)
{
if (!Contains(crossCompatibleRace))
{
settingsData.Add(new CrossCompatibilitySettings(crossCompatibleRace));
}
}
public void Remove(List<string> races)
{
for (int i = 0; i < races.Count; i++)
{
Remove(races[i]);
}
}
public void Remove(string crossCompatibleRace)
{
int removeAt = -1;
for (int i = 0; i < settingsData.Count; i++)
{
if (settingsData[i].ccRace == crossCompatibleRace)
{
removeAt = i;
}
}
if (removeAt > -1)
{
settingsData.RemoveAt(removeAt);
}
}
}
//Race Thumbnails used in the GUI to give a visual representation of the race
[System.Serializable]
public class RaceThumbnails
{
[System.Serializable]
public class WardrobeSlotThumb
{
[Tooltip("A comma separated list of wardrobe slots this is the base thumbnail for (no spaces)")]
public string thumbIsFor = "";
public Sprite thumb = null;
}
public Sprite fullThumb = null;
public Sprite faceThumb = null;
[SerializeField]
List<WardrobeSlotThumb> wardrobeSlotThumbs = new List<WardrobeSlotThumb>();
public Sprite GetThumbFor(string thumbToGet = "")
{
Sprite foundSprite = fullThumb != null ? fullThumb : null;
for (int i = 0; i < wardrobeSlotThumbs.Count; i++)
{
WardrobeSlotThumb wardrobeThumb = wardrobeSlotThumbs[i];
string[] thumbIsForArray = null;
wardrobeThumb.thumbIsFor.Replace(" ,", ",").Replace(", ", ",");
if (wardrobeThumb.thumbIsFor.IndexOf(",") == -1)
{
thumbIsForArray = new string[1] { wardrobeThumb.thumbIsFor };
}
else
{
thumbIsForArray = wardrobeThumb.thumbIsFor.Split(new string[1] { "," }, StringSplitOptions.RemoveEmptyEntries);
}
for (int i1 = 0; i1 < thumbIsForArray.Length; i1++)
{
string thumbFor = thumbIsForArray[i1];
if (thumbFor == thumbToGet)
{
foundSprite = wardrobeThumb.thumb;
break;
}
}
}
return foundSprite;
}
}
#endregion
}
}
@@ -0,0 +1,19 @@
fileFormatVersion: 2
guid: 693273374619be643933f926eeea3408
timeCreated: 1457203635
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
AssetOrigin:
serializedVersion: 1
productId: 35611
packageName: UMA 2
packageVersion: 2.13
assetPath: Assets/UMA/Core/StandardAssets/Extensions/DynamicCharacterSystem/Scripts/pRaceData.cs
uploadId: 679826