void Start() { // let's start by initialising the builder with the atlas scale of half HumanoidBuilder.Initialize(1.0f); // now let's generate a humanoid male human = new HumanoidStructure('M'); // set the basic body slots. // Use color indexes from the GamePalette.cs HumanoidStructure.BodyAdd(human, "Human Male Eyes 01"); HumanoidStructure.BodyAdd(human, "Human Male Head 01", 4); HumanoidStructure.BodyAdd(human, "Human Male HeadEars 01", 4); HumanoidStructure.BodyAdd(human, "Human Male HeadEyes 01", 4); HumanoidStructure.BodyAdd(human, "Human Male HeadMouth 01", 4); HumanoidStructure.BodyAdd(human, "Human Male HeadNose 01", 4); HumanoidStructure.BodyAdd(human, "Human Male Head InnerMouth"); HumanoidStructure.BodyAdd(human, "Human Male Torso 01", 4); HumanoidStructure.BodyAdd(human, "Human Male Hands 01", 4); HumanoidStructure.BodyAdd(human, "Human Male Legs 01", 4); HumanoidStructure.BodyAdd(human, "Human Male Feet 01", 4); // let's add some clothing HumanoidStructure.WardrobeAdd(human, "Male Jeans 01", 12); HumanoidStructure.WardrobeAdd(human, "MaleShirt 01", 1); // just a test of packing a human ( just a proof it all works) string testpack = HumanoidStructure.Pack(human); Debug.Log(testpack); Debug.Log("Pack size " + testpack.Length); // now lets unpack and generate the uma (we're using the packed version just to show that packing/unpacking works) HumanoidStructure testhuman = HumanoidStructure.Unpack(testpack); myuma = HumanoidBuilder.Create(testhuman, "myumaM", animController, new Vector3(0.5f, 0, 0) , 0, false, true); //Set up a callback thats run when UMA has finished loading myuma.GetComponent<UMAData>().OnCharacterCreated += UMAMaleFinished; // now let's generate a humanoid female humanf = new HumanoidStructure('F'); // you can add tails, horns, eyelashes, etc after these basics // but the build order is vital to keep attachment vertex indecies // This time we use Color32 to set the color instead. HumanoidStructure.BodyAdd(humanf, "Human Female Eyes 01"); HumanoidStructure.BodyAdd(humanf, "Human Female Head 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female HeadEars 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female HeadEyes 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female HeadMouth 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female HeadNose 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female Head InnerMouth"); HumanoidStructure.BodyAdd(humanf, "Human Female Torso 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female Hands 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female Legs 01", new Color32(188, 188, 188, 255)); HumanoidStructure.BodyAdd(humanf, "Human Female Feet 01", new Color32(188, 188, 188, 255)); // let's add some clothing HumanoidStructure.WardrobeAdd(humanf, "MaleShirt 01", 2); // just a test of packing a human ( just a proof it all works) string testpackf = HumanoidStructure.Pack(humanf); Debug.Log(testpackf); Debug.Log("Pack size " + testpackf.Length); // now lets unpack and generate the uma HumanoidStructure testhumanf = HumanoidStructure.Unpack(testpackf); myumaf = HumanoidBuilder.Create(testhumanf, "myumaF", animController, new Vector3(-0.5f, 0, 0), 0, false, true); //Set up a callback thats run when UMA has finished loading myumaf.GetComponent<UMAData>().OnCharacterCreated += UMAFemaleFinished; }
/// <summary> /// Removes a body element of the humanoid-structure build, from the build-slot position. See <see cref="UMAElements.Positions"/> class. /// </summary> /// <returns> /// Returns a bool, true if anything was removed, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='position'> /// the build-slot position to clear. /// </param> public static bool BodyRemoveAtPosition(HumanoidStructure human, int position) { // find any elements at this position foreach(ElementBlock eb in human.Body) { if((int)eb.element.buildPos == position) { human.Body.Remove(eb); return true; } } return false; }
/// <summary> /// Pack the specified HumanoidStructure into a string. /// </summary> /// <returns> /// Returns a packed string. /// </returns> /// <param name='humanoid'> /// The structure to pack. /// </param> public static string Pack(HumanoidStructure human) { string o = ""; // the basic shape elements /* 0 */ o += human.race + "|"; /* 1 */ o += human.gender + "|"; /* 2 */ o += human.height + "|"; /* 3 */ o += Scalar2Int2String(human.upperMuscle) + "|"; /* 4 */ o += Scalar2Int2String(human.upperWeight) + "|"; /* 5 */ o += Scalar2Int2String(human.lowerMuscle) + "|"; /* 6 */ o += Scalar2Int2String(human.lowerWeight) + "|"; /* 7 */ o += Scalar2Int2String(human.armLength) + "|"; /* 8 */ o += Scalar2Int2String(human.forearmLength) + "|"; /* 9 */ o += Scalar2Int2String(human.legSeparation) + "|"; /* 10 */ o += Scalar2Int2String(human.handSize) + "|"; /* 11 */ o += Scalar2Int2String(human.feetSize) + "|"; /* 12 */ o += Scalar2Int2String(human.legsSize) + "|"; /* 13 */ o += Scalar2Int2String(human.armWidth) + "|"; /* 14 */ o += Scalar2Int2String(human.forearmWidth) + "|"; /* 15 */ o += Scalar2Int2String(human.breastSize) + "|"; /* 16 */ o += Scalar2Int2String(human.waist) + "|"; /* 17 */ o += Scalar2Int2String(human.belly) + "|"; /* 18 */ o += Scalar2Int2String(human.gluteusSize) + "|"; /* 19 */ o += Scalar2Int2String(human.headSize) + "|"; /* 20 */ o += Scalar2Int2String(human.headWidth) + "|"; /* 21 */ o += Scalar2Int2String(human.neckThickness) + "|"; /* 22 */ o += Scalar2Int2String(human.earsSize) + "|"; /* 23 */ o += Scalar2Int2String(human.earsPosition) + "|"; /* 24 */ o += Scalar2Int2String(human.earsRotation) + "|"; /* 25 */ o += Scalar2Int2String(human.noseSize) + "|"; /* 26 */ o += Scalar2Int2String(human.noseCurve) + "|"; /* 27 */ o += Scalar2Int2String(human.noseWidth) + "|"; /* 28 */ o += Scalar2Int2String(human.noseInclination) + "|"; /* 29 */ o += Scalar2Int2String(human.nosePosition) + "|"; /* 30 */ o += Scalar2Int2String(human.nosePronounced) + "|"; /* 31 */ o += Scalar2Int2String(human.noseFlatten) + "|"; /* 32 */ o += Scalar2Int2String(human.chinSize) + "|"; /* 33 */ o += Scalar2Int2String(human.chinPronounced) + "|"; /* 34 */ o += Scalar2Int2String(human.chinPosition) + "|"; /* 35 */ o += Scalar2Int2String(human.mandibleSize) + "|"; /* 36 */ o += Scalar2Int2String(human.jawsSize) + "|"; /* 37 */ o += Scalar2Int2String(human.jawsPosition) + "|"; /* 38 */ o += Scalar2Int2String(human.cheekSize) + "|"; /* 39 */ o += Scalar2Int2String(human.cheekPosition) + "|"; /* 40 */ o += Scalar2Int2String(human.lowCheekPronounced) + "|"; /* 41 */ o += Scalar2Int2String(human.lowCheekPosition) + "|"; /* 42 */ o += Scalar2Int2String(human.foreheadSize) + "|"; /* 43 */ o += Scalar2Int2String(human.foreheadPosition) + "|"; /* 44 */ o += Scalar2Int2String(human.lipsSize) + "|"; /* 45 */ o += Scalar2Int2String(human.mouthSize) + "|"; /* 46 */ o += Scalar2Int2String(human.eyeSize) + "|"; /* 47 */ o += Scalar2Int2String(human.eyeRotation) + "|"; // the body slots info string bodyparts = ""; for(int n = 0; n < human.Body.Count; n++) { if(n != 0) bodyparts += "^"; bodyparts += human.Body[n].element.Index; if(human.Body[n].colors != null) { if(human.Body[n].colors.Count == 1) bodyparts += "," + human.Body[n].colors[0]; else if(human.Body[n].colors.Count == 3) bodyparts += "," + human.Body[n].colors[0] + "," + human.Body[n].colors[1] + "," + human.Body[n].colors[2]; } else { bodyparts += "," + human.Body[n].color.r + "," + human.Body[n].color.g + "," + human.Body[n].color.b + "," + human.Body[n].color.a; } } o += bodyparts + "|"; // the wardrobe slots info string wardrobeparts = ""; for(int n = 0; n < human.Wardrobe.Count; n++) { if(n != 0) wardrobeparts += "^"; wardrobeparts += human.Wardrobe[n].element.Index; if(human.Wardrobe[n].colors != null) { if(human.Wardrobe[n].colors.Count == 1) wardrobeparts += "," + human.Wardrobe[n].colors[0]; if(human.Wardrobe[n].colors.Count == 3) wardrobeparts += "," + human.Wardrobe[n].colors[0] + "," + human.Wardrobe[n].colors[1] + "," + human.Wardrobe[n].colors[2]; } else { wardrobeparts += "," + human.Wardrobe[n].color.r + "," + human.Wardrobe[n].color.g + "," + human.Wardrobe[n].color.b + "," + human.Wardrobe[n].color.a; } } o += wardrobeparts + "|"; // the attachments slots info string attachmentparts = ""; for(int n = 0; n < human.Attachments.Count; n++) { if(n != 0) attachmentparts += "^"; attachmentparts += human.Attachments[n].element.Index; if(human.Attachments[n].colors.Count == 1) attachmentparts += "," + human.Attachments[n].colors[0]; if(human.Attachments[n].colors.Count == 3) attachmentparts += "," + human.Attachments[n].colors[0] + "," + human.Attachments[n].colors[1] + "," + human.Attachments[n].colors[2]; } o += attachmentparts; // all done return o; }
/// <summary> /// Removes a body element of the humanoid-structure build, from it's element-index /// </summary> /// <returns> /// Returns a bool, true if anything was removed, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='index'> /// the element-index of the element to remove. /// </param> public static bool BodyRemove(HumanoidStructure human, int index) { // does this named element exist foreach(ElementBlock eb in human.Body) { if(eb.element.Index == index) { human.Body.Remove(eb); return true; } } return false; }
/// <summary> /// Remove all body elements from the build. /// </summary> /// <param name='human'> /// HumanoidStructure /// </param> public static void BodyRemoveAll(HumanoidStructure human) { human.Body.Clear(); }
/// <summary> /// Adds a body element to the humanoid-structure build, given it's element-name, and three element-splatmap colors. /// </summary> /// <returns> /// Returns a bool, true if anything was added, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='name'> /// the element-name of the element to add. /// </param> /// <param name='color1'> /// the index of the elemement-splatmap color to use, see DyeSwatch in the <see cref="UMAElements.GamePalette"/> class. This color replaces the Red splatmap component. /// </param> /// <param name='color2'> /// the index of the elemement-splatmap color to use, see DyeSwatch in the <see cref="UMAElements.GamePalette"/> class. This color replaces the Green splatmap component /// </param> /// <param name='color3'> /// the index of the elemement-splatmap color to use, see DyeSwatch in the <see cref="UMAElements.GamePalette"/> class. This color replaces the Blue splatmap component /// </param> public static bool BodyAdd(HumanoidStructure human, string name, int color1, int color2, int color3) { // does this named element exist in our dictionaries foreach(ElementData ed in ElementsLibrary.Elements.Values) { if(ed.Name == name) { // build a new element block and add it to the body ElementBlock eb = new ElementBlock(ed, color1, color2, color3); human.Body.Add(eb); return true; } } return false; }
/// <summary> /// Adds a body element to the humanoid-structure build, given it's element-index, and three element-splatmap colors. /// </summary> /// <returns> /// Returns a bool, true if anything was added, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='index'> /// the element-index of the element to add. /// </param> /// <param name='color1'> /// the index of the elemement-splatmap color to use, see DyeSwatch in the <see cref="UMAElements.GamePalette"/> class. This color replaces the Red splatmap component. /// </param> /// <param name='color2'> /// the index of the elemement-splatmap color to use, see DyeSwatch in the <see cref="UMAElements.GamePalette"/> class. This color replaces the Green splatmap component /// </param> /// <param name='color3'> /// the index of the elemement-splatmap color to use, see DyeSwatch in the <see cref="UMAElements.GamePalette"/> class. This color replaces the Blue splatmap component /// </param> public static bool BodyAdd(HumanoidStructure human, int index, int color1, int color2, int color3) { // does this index exist? if(!ElementsLibrary.Elements.ContainsKey(index)) return false; // build a new element block and add it to the body ElementBlock eb = new ElementBlock(ElementsLibrary.Elements[index], color1, color2, color3); human.Body.Add(eb); return true; }
/// <summary> /// Remove all attachments elements from the build. /// </summary> /// <param name='human'> /// HumanoidStructure /// </param> public static void AttachmentsRemoveAll(HumanoidStructure human) { human.Attachments.Clear(); }
/// <summary> /// Removes an attachment element of the humanoid-structure build, from the attachment default position. See <see cref="UMAElements.Positions"/> class. /// </summary> /// <returns> /// Returns a bool, true if anything was removed, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='position'> /// the attachment default position to clear. /// </param> public static bool AttachmentsRemoveAtDefaultPosition(HumanoidStructure human, int position) { // find any elements at this position foreach(ElementBlock eb in human.Attachments) { if((int)eb.element.attachmentDefaultPos == position) { human.Attachments.Remove(eb); return true; } } return false; }
/// <summary> /// Set the named attachment to it's default position. /// </summary> /// <returns> /// Returns false if the element was not found. /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='name'> /// the element-name of the element to set. /// </param> public static bool AttachmentSetDefault(HumanoidStructure human, string name) { // iterate throught the list of attachments for(int i = 0; i < human.Attachments.Count; i++) { // is this our attachment? if(human.Attachments[i].element.Name == name) { human.Attachments[i].attachmentIsActive = false; return true; } } return false; }
/// <summary> /// Removes an attachment element of the humanoid-structure build, from it's element-name /// </summary> /// <returns> /// Returns a bool, true if anything was removed, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='name'> /// the element-name of the attachment to remove. /// </param> public static bool AttachmentsRemove(HumanoidStructure human, string name) { // does this named element exist foreach(ElementBlock eb in human.Attachments) { if(eb.element.Name == name) { human.Attachments.Remove(eb); return true; } } return false; }
/// <summary> /// Adds an attachment element to the humanoid-structure build, given it's element-index. /// </summary> /// <returns> /// Returns a bool, true if anything was added, false if the body build list was unchanged /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='index'> /// the element-index of the element to add. /// </param> public static bool AttachmentsAdd(HumanoidStructure human, int index) { // does this index exist? if(!ElementsLibrary.Elements.ContainsKey(index)) return false; // build a new element block and add it to the body ElementBlock eb = new ElementBlock(ElementsLibrary.Elements[index]); human.Attachments.Add(eb); return true; }
/// <summary> /// Remove all wardrobe elements from the build. /// </summary> /// <param name='human'> /// HumanoidStructure /// </param> public static void WardrobeRemoveAll(HumanoidStructure human) { human.Wardrobe.Clear(); }
/// <summary> /// Does the wardrobe element exist in our list? /// </summary> /// <returns> /// true or false. /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='index'> /// the element-index of the element to find. /// </param> public static bool WardrobeHasElement(HumanoidStructure human, int index) { // does this named element exist foreach(ElementBlock eb in human.Wardrobe) { if(eb.element.Index == index) return true; } return false; }
/// <summary> /// Does the named wardrobe element exist in our list? /// </summary> /// <returns> /// true or false. /// </returns> /// <param name='human'> /// HumanoidStructure /// </param> /// <param name='name'> /// the element-name of the element to find. /// </param> public static bool WardrobeHasElement(HumanoidStructure human, string name) { // does this named element exist foreach(ElementBlock eb in human.Wardrobe) { if(eb.element.Name == name) return true; } return false; }
// ------------------------------------------------------------------------------------------------------------- // serialization /// <summary> /// Unpack the specified HumanoidStructure packed string. /// </summary> /// <returns> /// Returns a HumanoidStructure. /// </returns> /// <param name='package'> /// The string to unpack. This must have been packed with the Pack() method. /// </param> public static HumanoidStructure Unpack(string package) { HumanoidStructure hs = new HumanoidStructure(); string[] parts = package.Split('|'); // the basic shape elements hs.race = String2Char(parts[0]); hs.gender = String2Char(parts[1]); hs.height = String2Int(parts[2]); hs.upperMuscle = String2Int2Scalar(parts[3]); hs.upperWeight = String2Int2Scalar(parts[4]); hs.lowerMuscle = String2Int2Scalar(parts[5]); hs.lowerWeight = String2Int2Scalar(parts[6]); hs.armLength = String2Int2Scalar(parts[7]); hs.forearmLength = String2Int2Scalar(parts[7]); hs.legSeparation = String2Int2Scalar(parts[8]); hs.handSize = String2Int2Scalar(parts[10]); hs.feetSize = String2Int2Scalar(parts[11]); hs.legsSize = String2Int2Scalar(parts[12]); hs.armWidth = String2Int2Scalar(parts[13]); hs.forearmWidth = String2Int2Scalar(parts[14]); hs.breastSize = String2Int2Scalar(parts[15]); hs.waist = String2Int2Scalar(parts[16]); hs.belly = String2Int2Scalar(parts[17]); hs.gluteusSize = String2Int2Scalar(parts[18]); hs.headSize = String2Int2Scalar(parts[19]); hs.headWidth = String2Int2Scalar(parts[20]); hs.neckThickness = String2Int2Scalar(parts[21]); hs.earsSize = String2Int2Scalar(parts[22]); hs.earsPosition = String2Int2Scalar(parts[23]); hs.earsRotation = String2Int2Scalar(parts[24]); hs.noseSize = String2Int2Scalar(parts[25]); hs.noseCurve = String2Int2Scalar(parts[26]); hs.noseWidth = String2Int2Scalar(parts[27]); hs.noseInclination = String2Int2Scalar(parts[28]); hs.nosePosition = String2Int2Scalar(parts[29]); hs.nosePronounced = String2Int2Scalar(parts[30]); hs.noseFlatten = String2Int2Scalar(parts[31]); hs.chinSize = String2Int2Scalar(parts[32]); hs.chinPronounced = String2Int2Scalar(parts[33]); hs.chinPosition = String2Int2Scalar(parts[34]); hs.mandibleSize = String2Int2Scalar(parts[35]); hs.jawsSize = String2Int2Scalar(parts[36]); hs.jawsPosition = String2Int2Scalar(parts[37]); hs.cheekSize = String2Int2Scalar(parts[38]); hs.cheekPosition = String2Int2Scalar(parts[39]); hs.lowCheekPronounced = String2Int2Scalar(parts[40]); hs.lowCheekPosition = String2Int2Scalar(parts[41]); hs.foreheadSize = String2Int2Scalar(parts[42]); hs.foreheadPosition = String2Int2Scalar(parts[43]); hs.lipsSize = String2Int2Scalar(parts[44]); hs.mouthSize = String2Int2Scalar(parts[45]); hs.eyeSize = String2Int2Scalar(parts[46]); hs.eyeRotation = String2Int2Scalar(parts[47]); // the body slots info string[] bodyparts = parts[48].Split('^'); hs.Body = new List<ElementBlock>(); for(int n = 0; n < bodyparts.Length; n++) { string[] bodypartsparams = bodyparts[n].Split(','); if(bodypartsparams.Length == 1) BodyAdd(hs, String2Int(bodypartsparams[0])); else if(bodypartsparams.Length == 2) BodyAdd(hs, String2Int(bodypartsparams[0]), String2Int(bodypartsparams[1])); else if(bodypartsparams.Length == 4) BodyAdd(hs, String2Int(bodypartsparams[0]), String2Int(bodypartsparams[1]), String2Int(bodypartsparams[2]), String2Int(bodypartsparams[3])); else if(bodypartsparams.Length == 5) { Color32 color = new Color32(byte.Parse(bodypartsparams[1]), byte.Parse(bodypartsparams[2]), byte.Parse(bodypartsparams[3]), byte.Parse(bodypartsparams[4])); BodyAdd(hs, String2Int(bodypartsparams[0]), color); } } // the wardrobe slots info string[] wardrobeparts = parts[49].Split('^'); hs.Wardrobe = new List<ElementBlock>(); for(int n = 0; n < wardrobeparts.Length; n++) { string[] wardrobepartsparams = wardrobeparts[n].Split(','); if(wardrobepartsparams.Length == 1) WardrobeAdd(hs, String2Int(wardrobepartsparams[0])); else if(wardrobepartsparams.Length == 2) WardrobeAdd(hs, String2Int(wardrobepartsparams[0]), String2Int(wardrobepartsparams[1])); else if(wardrobepartsparams.Length == 4) WardrobeAdd(hs, String2Int(wardrobepartsparams[0]), String2Int(wardrobepartsparams[1]), String2Int(wardrobepartsparams[2]), String2Int(wardrobepartsparams[3])); else if(wardrobepartsparams.Length == 5) { Color32 color = new Color32(byte.Parse(wardrobepartsparams[1]), byte.Parse(wardrobepartsparams[2]), byte.Parse(wardrobepartsparams[3]), byte.Parse(wardrobepartsparams[4])); WardrobeAdd(hs, String2Int(wardrobepartsparams[0]), color); } } // the attachments slots info string[] attachmentsparts = parts[50].Split('^'); hs.Attachments = new List<ElementBlock>(); for(int n = 0; n < attachmentsparts.Length; n++) { string[] attachmentspartsparams = attachmentsparts[n].Split(','); if(attachmentspartsparams.Length == 1) AttachmentsAdd(hs, String2Int(attachmentspartsparams[0])); //if(attachmentspartsparams.Length == 2) AttachmentsAdd(hs, String2Int(attachmentspartsparams[0]), String2Int(attachmentspartsparams[1])); //if(attachmentspartsparams.Length == 4) AttachmentsAdd(hs, String2Int(attachmentspartsparams[0]), String2Int(attachmentspartsparams[1]), String2Int(attachmentspartsparams[2]), String2Int(bodypartsparams[3])); } // return the result return hs; }