void UpdateTarget() { GameObject[] enemies = GameObject.FindGameObjectsWithTag(enemyTag); //TODO: This may not be optimized, I place every enemy into array rather than just ones that enter range... float shortestDistance = Mathf.Infinity; //infinity while we haven't found an enemy GameObject nearestEnemy = null; //Calculate distances to all enemies, and identify the shortest distance foreach (GameObject enemy in enemies) { float distanceToEnemy = Vector3.Distance(transform.position, enemy.transform.position); if (distanceToEnemy < shortestDistance) { shortestDistance = distanceToEnemy; nearestEnemy = enemy; } } //If there is a nearest enemy and it's distance is under our range, get enemy transform and set targetEnemy to the Creature body if (nearestEnemy != null && shortestDistance <= range) { target = nearestEnemy.transform; targetEnemy = nearestEnemy.GetComponent <CreatureBody> (); } else { target = null; } }
public override void OnStartup() { CheckTemplate(); //create body for creature CreatureBody body = null; if (!Creatures.GetBody(Template.Props.BodyName, out body)) { Debug.Log("Couldn't get body in creature " + State.TemplateName); return; } else { GameObject newBody = GameObject.Instantiate(body.gameObject, worlditem.tr.position, Quaternion.identity) as GameObject; Body = newBody.GetComponent <CreatureBody> (); } //set the body's eye colors Body.HostileEyeColor = Color.red; Body.TimidEyeColor = Color.green; Body.AggressiveEyeColor = Color.yellow; Body.ScaredEyeColor = Color.white; //don't set the body's parent or name //let the body stay in the world to keep the heirarchy clean //Body.transform.parent = worlditem.Group.transform; //Body.name = worlditem.FileName + "-Body"; //if we're dead, we need to set the body to ragdoll right away }
void ArrangeModeledPart(CreatureBody body) { if (modeledPart == null) { return; } modeledPart.transform.localScale = body.bodyScale; modeledPart.volume = volume; modeledPart.FixVolume(); bounds = modeledPart.GetComponentInChildren <MeshRenderer>().bounds; foreach (var renderer in GetComponentsInChildren <MeshRenderer>()) { bounds.Encapsulate(renderer.bounds); } List <ChildPlacement> placements = new List <ChildPlacement>(); foreach (Transform child in modeledPart.transform) { BodyPartChildPlaceholder bodyPartChild = child.GetComponent <BodyPartChildPlaceholder>(); if (bodyPartChild == null) { continue; } bool placedPart = false; foreach (var placement in placements) { if (placement.Matches(bodyPartChild)) { placement.Add(bodyPartChild); placedPart = true; } } if (!placedPart) { placements.Add(new ChildPlacement(bodyPartChild)); } } foreach (Transform child in transform) { var childPart = child.GetComponent <BodyPart>(); if (childPart == null) { continue; } foreach (var placement in placements) { if (placement.Matches(childPart)) { placement.Add(childPart); break; } } childPart.Arrange(body); } foreach (var placement in placements) { placement.Arrange(); } }
bool FitsFilter(CreatureRaw creature) { if (!string.IsNullOrEmpty(filter) && (filterName || filterDescription || filterToken || filterParts)) { bool matched = false; if (filterToken && creature.creature_id.ToUpper().Contains(filter.ToUpper())) { matched = true; } if (filterName && creature.name[0].ToUpper().Contains(filter.ToUpper())) { matched = true; } if (!matched) { foreach (var caste in creature.caste) { if (filterName && caste.caste_name[0].ToUpper().Contains(filter.ToUpper())) { matched = true; } if (filterDescription && caste.description.ToUpper().Contains(filter.ToUpper())) { matched = true; } if (filterParts) { foreach (var part in caste.body_parts) { if (part.category.ToUpper().Contains(filter.ToUpper())) { matched = true; break; } } } } } if (!matched) { return(false); } } if (bodyCategoryFilter != CreatureBody.BodyCategory.None) { foreach (var caste in creature.caste) { if (bodyCategoryFilter == CreatureBody.FindBodyCategory(caste)) { return(true); } } return(false); } return(true); }
bool FitsFilter(UnitDefinition unit) { if (!string.IsNullOrEmpty(filter)) { if (filterToken) { if (!creatureRaws[unit.race.mat_type].creature_id.ToUpper().Contains(filter.ToUpper())) { return(false); } } if (filterName) { if (!name.ToUpper().Contains(filter.ToUpper())) { return(false); } } if (filterParts) { if (unit.inventory.Count == 0) { return(false); } foreach (var item in unit.inventory) { if (!ItemRaws.Instance.ContainsKey(item.item.type)) { continue; } if (ItemRaws.Instance[item.item.type].id.ToUpper().Contains(filter.ToUpper())) { return(true); } } return(false); } } if (bodyCategoryFilter != CreatureBody.BodyCategory.None) { foreach (var caste in creatureRaws[unit.race.mat_type].caste) { if (bodyCategoryFilter == CreatureBody.FindBodyCategory(caste)) { return(true); } } return(false); } return(true); }
public IEnumerator PlayCutsceneOverTime() { double start = Frontiers.WorldClock.AdjustedRealTime; while (Frontiers.WorldClock.AdjustedRealTime < start + State.InitialDelay) { yield return(null); } //get the creature body - we're only using a shell here CreatureBody body = null; CreatureTemplate template = null; AnimationClip clip = null; if (Creatures.GetBody(State.CreatureBodyName, out body)) { if (Creatures.GetCutsceneClip(State.CutsceneClipName, out clip)) { //create the base object and add the animation //parent it under this trigger CreatureCutsceneObject = gameObject.CreateChild(State.Name + " - " + State.CreatureBodyName).gameObject; CreatureCutsceneAnimation = CreatureCutsceneObject.AddComponent <Animation>(); CreatureCutsceneAnimation.AddClip(clip, State.CutsceneClipName); //this script will implement the IBodyOwner interface UnityEngineInternal.APIUpdaterRuntimeServices.AddComponent(CreatureCutsceneObject, "Assets/Scripts/GameWorld/Triggers/TriggerCreatureCutscene.cs (46,11)", State.CutsceneScriptName); IBodyOwner bodyOwner = CreatureCutsceneObject.GetComponent(typeof(IBodyOwner)) as IBodyOwner; //create an empty body shell GameObject creatureCutsceneBodyObject = GameObject.Instantiate(body.gameObject, transform.position, Quaternion.identity) as GameObject; CreatureCutsceneBody = creatureCutsceneBodyObject.GetComponent <CreatureBody>(); CreatureCutsceneBody.Owner = bodyOwner; bodyOwner.Body = CreatureCutsceneBody; //and we're off! CreatureCutsceneAnimation.Play(State.CutsceneClipName, PlayMode.StopAll); } } while (CreatureCutsceneObject != null) { yield return(null); } GameObject.Destroy(CreatureCutsceneBody.gameObject); mPlayingCutscene = false; Missions.Get.ChangeVariableValue(State.MissionVariableMissionName, State.MissionVariableVariableName, State.MissionVariableChangeValue, State.MissionVariableChangeType); yield break; }
public override void OnInspectorGUI() { base.OnInspectorGUI(); if (GUILayout.Button("Dump mods")) { var path = EditorUtility.SaveFilePanel("Save mod tree", "", "dwarf.txt", "txt"); if (!string.IsNullOrWhiteSpace(path)) { CreatureBody body = target as CreatureBody; using (System.IO.StreamWriter file = new System.IO.StreamWriter(path)) { int indent = 0; WritePartMods(file, body.rootPart, indent); } } } }
bool FitsFilter(CreatureRaw creature) { if (!string.IsNullOrEmpty(filter) && !creature.creature_id.ToUpper().Contains(filter.ToUpper())) { return(false); } if (bodyCategoryFilter != CreatureBody.BodyCategory.None) { foreach (var caste in creature.caste) { if (bodyCategoryFilter == CreatureBody.FindBodyCategory(caste)) { return(true); } } return(false); } return(true); }
private void OnGUI() { if (GUILayout.Button("Read Raws")) { var client = new RemoteClient(); if (!client.Connect()) { return; } client.SuspendGame(); var getCreatureRaws = new RemoteFunction <EmptyMessage, CreatureRawList>(client, "GetCreatureRaws", "RemoteFortressReader"); var materialListCall = new RemoteFunction <EmptyMessage, MaterialList>(client, "GetMaterialList", "RemoteFortressReader"); var itemListCall = new RemoteFunction <EmptyMessage, MaterialList>(client, "GetItemList", "RemoteFortressReader"); var unitListCall = new RemoteFunction <EmptyMessage, UnitList>(client, "GetUnitList", "RemoteFortressReader"); client.ResumeGame(); creatureRaws = getCreatureRaws.Execute().creature_raws; var ExistingMatList = AssetDatabase.LoadAssetAtPath <MaterialRaws>("Assets/Resources/MaterialRaws.asset"); var ExistingItemList = AssetDatabase.LoadAssetAtPath <ItemRaws>("Assets/Resources/ItemRaws.asset"); MaterialRaws.Instance.MaterialList = materialListCall.Execute().material_list; ItemRaws.Instance.ItemList = itemListCall.Execute().material_list; units = unitListCall.Execute().creature_list; if (ExistingMatList == null) { AssetDatabase.CreateAsset(MaterialRaws.Instance, "Assets/Resources/MaterialRaws.asset"); } if (ExistingItemList == null) { AssetDatabase.CreateAsset(ItemRaws.Instance, "Assets/Resources/ItemRaws.asset"); } AssetDatabase.SaveAssets(); Debug.Log(string.Format("Pulled {0} creature raws from DF.", creatureRaws.Count)); if (MaterialCollection.Instance == null) { MaterialCollector.BuildMaterialCollection(); } MaterialCollection.Instance.PopulateMatTextures(); client.Disconnect(); //foreach (var raw in creatureRaws) //{ // raw.creature_id = BodyDefinition.GetCorrectedCreatureID(raw); //} RefilterList(); } if (creatureRaws != null) { EditorGUI.BeginChangeCheck(); filter = EditorGUILayout.TextField(filter); filterToken = EditorGUILayout.Toggle("Token", filterToken); filterName = EditorGUILayout.Toggle("Name", filterName); filterDescription = EditorGUILayout.Toggle("Description", filterDescription); filterParts = EditorGUILayout.Toggle("Parts", filterParts); bodyCategoryFilter = (CreatureBody.BodyCategory)EditorGUILayout.EnumPopup(bodyCategoryFilter); if (EditorGUI.EndChangeCheck()) { RefilterList(); } EditorGUILayout.Space(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Sort by name")) { creatureRaws.Sort((x, y) => x.creature_id.CompareTo(y.creature_id)); RefilterList(); } if (GUILayout.Button("Sort by size")) { creatureRaws.Sort((x, y) => x.adultsize.CompareTo(y.adultsize)); RefilterList(); } if (GUILayout.Button("Sort by index")) { creatureRaws.Sort((x, y) => x.index.CompareTo(y.index)); RefilterList(); } GUILayout.EndHorizontal(); showRaces = EditorGUILayout.Foldout(showRaces, "Races"); if (showRaces) { raceScroll = EditorGUILayout.BeginScrollView(raceScroll); foreach (var creature in filteredRaws) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel(string.Format("{0} ({1})", creature.creature_id, creature.name[0])); EditorGUILayout.BeginVertical(); foreach (var caste in creature.caste) { if (GUILayout.Button(string.Format("{0} ({1})", caste.caste_id, caste.caste_name[0]))) { var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.name = caste.caste_name[0]; creatureBase.race = creature; creatureBase.caste = caste; creatureBase.MakeBody(); Selection.SetActiveObjectWithContext(creatureBase, null); } } EditorGUILayout.EndVertical(); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndScrollView(); if (GUILayout.Button("Dump Part Categories")) { var path = EditorUtility.SaveFilePanel("Save bodypart list", "", "Bodyparts.csv", "csv"); if (!string.IsNullOrEmpty(path)) { Dictionary <string, Dictionary <string, ChildCount> > parts = new Dictionary <string, Dictionary <string, ChildCount> >(); foreach (var creature in filteredRaws) { foreach (var caste in creature.caste) { if (bodyCategoryFilter != CreatureBody.BodyCategory.None && bodyCategoryFilter != CreatureBody.FindBodyCategory(caste)) { continue; } for (int i = 0; i < caste.body_parts.Count; i++) { var part = caste.body_parts[i]; //this is an internal part, and doesn't need modeling. if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } if (!parts.ContainsKey(part.category)) { parts[part.category] = new Dictionary <string, ChildCount>(); } Dictionary <string, int> childCounts = new Dictionary <string, int>(); foreach (var sub in caste.body_parts) { if (sub.parent != i) { continue; } if (sub.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } if (!childCounts.ContainsKey(sub.category)) { childCounts[sub.category] = 1; } else { childCounts[sub.category]++; } } foreach (var item in childCounts) { if (!parts[part.category].ContainsKey(item.Key)) { parts[part.category][item.Key] = new ChildCount(); } if (parts[part.category][item.Key].min > item.Value) { parts[part.category][item.Key].min = item.Value; } if (parts[part.category][item.Key].max < item.Value) { parts[part.category][item.Key].max = item.Value; } } } } } using (var writer = new StreamWriter(path)) { foreach (var parent in parts) { writer.Write("\"" + parent.Key + "\","); foreach (var child in parent.Value) { writer.Write(string.Format("\"{0}\",{1},{2},", child.Key, child.Value.min, child.Value.max)); } writer.WriteLine(); } } } } if (GUILayout.Button("Place all races")) { var watch = System.Diagnostics.Stopwatch.StartNew(); CreatureBody prevCreature = null; foreach (var creature in filteredRaws) { var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.name = creature.caste[0].caste_name[0]; creatureBase.race = creature; creatureBase.caste = creature.caste[0]; creatureBase.MakeBody(); if (prevCreature != null) { creatureBase.transform.position = new Vector3(prevCreature.transform.position.x + prevCreature.bounds.max.x - creatureBase.bounds.min.x, 0, 0); } prevCreature = creatureBase; } watch.Stop(); Debug.Log(string.Format("Took {0}ms to create {1} creatures, averaging {2}ms per creature.", watch.ElapsedMilliseconds, filteredRaws.Count, (float)watch.ElapsedMilliseconds / filteredRaws.Count)); } } showUnits = EditorGUILayout.Foldout(showUnits, "Units"); if (showUnits) { unitScroll = EditorGUILayout.BeginScrollView(unitScroll); foreach (var unit in units) { string name = unit.name; if (string.IsNullOrEmpty(name)) { name = creatureRaws[unit.race.mat_type].caste[unit.race.mat_index].caste_name[0]; } if (!string.IsNullOrEmpty(filter) && (filterParts || filterName)) { bool matched = false; if (filterName) { matched = name.ToUpper().Contains(filter.ToUpper()); } if (filterParts) { foreach (var item in unit.inventory) { if (!ItemRaws.Instance.ContainsKey(item.item.type)) { continue; } matched = ItemRaws.Instance[item.item.type].id.ToUpper().Contains(filter.ToUpper()); if (matched) { break; } } } if (!matched) { continue; } } if (GUILayout.Button(name)) { var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.name = name; creatureBase.race = creatureRaws[unit.race.mat_type]; creatureBase.caste = creatureRaws[unit.race.mat_type].caste[unit.race.mat_index]; creatureBase.unit = unit; creatureBase.MakeBody(); creatureBase.UpdateUnit(unit); Selection.SetActiveObjectWithContext(creatureBase, null); } } EditorGUILayout.EndScrollView(); if (GUILayout.Button("Place all units")) { var watch = System.Diagnostics.Stopwatch.StartNew(); CreatureBody prevCreature = null; foreach (var unit in units) { string name = unit.name; if (string.IsNullOrEmpty(name)) { name = creatureRaws[unit.race.mat_type].caste[unit.race.mat_index].caste_name[0]; } if (!string.IsNullOrEmpty(filter) && (filterParts || filterName)) { bool matched = false; if (filterToken) { matched = creatureRaws[unit.race.mat_type].creature_id.ToUpper().Contains(filter.ToUpper()); } if (filterName) { matched = name.ToUpper().Contains(filter.ToUpper()); } if (filterParts) { foreach (var item in unit.inventory) { if (!ItemRaws.Instance.ContainsKey(item.item.type)) { continue; } matched = ItemRaws.Instance[item.item.type].id.ToUpper().Contains(filter.ToUpper()); if (matched) { break; } } } if (!matched) { continue; } } var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.name = name; creatureBase.race = creatureRaws[unit.race.mat_type]; creatureBase.caste = creatureRaws[unit.race.mat_type].caste[unit.race.mat_index]; creatureBase.unit = unit; creatureBase.MakeBody(); creatureBase.UpdateUnit(unit); creatureBase.transform.localRotation = Quaternion.identity; if (prevCreature != null) { creatureBase.transform.position = new Vector3(prevCreature.transform.position.x + prevCreature.bounds.max.x - creatureBase.bounds.min.x, 0, 0); } prevCreature = creatureBase; } watch.Stop(); Debug.Log(string.Format("Took {0}ms to create {1} creatures, averaging {2}ms per creature.", watch.ElapsedMilliseconds, filteredRaws.Count, (float)watch.ElapsedMilliseconds / filteredRaws.Count)); } } } }
private void OnGUI() { if (GUILayout.Button("Read Raws")) { var client = new RemoteClient(); if (!client.Connect()) { return; } var getCreatureRaws = new RemoteFunction <EmptyMessage, CreatureRawList>(client, "GetCreatureRaws", "RemoteFortressReader"); creatureRaws = getCreatureRaws.Execute().creature_raws; Debug.Log(string.Format("Pulled {0} creature raws from DF.", creatureRaws.Count)); client.Disconnect(); creatureRaws.Sort((x, y) => x.creature_id.CompareTo(y.creature_id)); RefilterList(); } if (creatureRaws != null) { EditorGUI.BeginChangeCheck(); filter = EditorGUILayout.TextField(filter); bodyCategoryFilter = (CreatureBody.BodyCategory)EditorGUILayout.EnumPopup(bodyCategoryFilter); if (EditorGUI.EndChangeCheck()) { RefilterList(); } if (GUILayout.Button("Dump Part Categories")) { var path = EditorUtility.SaveFilePanel("Save bodypart list", "", "Bodyparts.csv", "csv"); Dictionary <string, Dictionary <string, ChildCount> > parts = new Dictionary <string, Dictionary <string, ChildCount> >(); foreach (var creature in filteredRaws) { foreach (var caste in creature.caste) { if (bodyCategoryFilter != CreatureBody.BodyCategory.None && bodyCategoryFilter != CreatureBody.FindBodyCategory(caste)) { continue; } for (int i = 0; i < caste.body_parts.Count; i++) { var part = caste.body_parts[i]; //this is an internal part, and doesn't need modeling. if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } if (!parts.ContainsKey(part.category)) { parts[part.category] = new Dictionary <string, ChildCount>(); } Dictionary <string, int> childCounts = new Dictionary <string, int>(); foreach (var sub in caste.body_parts) { if (sub.parent != i) { continue; } if (sub.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } if (!childCounts.ContainsKey(sub.category)) { childCounts[sub.category] = 1; } else { childCounts[sub.category]++; } } foreach (var item in childCounts) { if (!parts[part.category].ContainsKey(item.Key)) { parts[part.category][item.Key] = new ChildCount(); } if (parts[part.category][item.Key].min > item.Value) { parts[part.category][item.Key].min = item.Value; } if (parts[part.category][item.Key].max < item.Value) { parts[part.category][item.Key].max = item.Value; } } } } } using (var writer = new StreamWriter(path)) { foreach (var parent in parts) { writer.Write("\"" + parent.Key + "\","); foreach (var child in parent.Value) { writer.Write(string.Format("\"{0}\",{1},{2},", child.Key, child.Value.min, child.Value.max)); } writer.WriteLine(); } } } GUILayout.BeginHorizontal(); if (GUILayout.Button("Sort by name")) { creatureRaws.Sort((x, y) => x.creature_id.CompareTo(y.creature_id)); RefilterList(); } if (GUILayout.Button("Sort by size")) { creatureRaws.Sort((x, y) => x.adultsize.CompareTo(y.adultsize)); RefilterList(); } GUILayout.EndHorizontal(); scrollPosition = GUILayout.BeginScrollView(scrollPosition); foreach (var creature in filteredRaws) { GUILayout.BeginHorizontal(); GUILayout.Label(creature.creature_id); foreach (var caste in creature.caste) { if (GUILayout.Button(caste.caste_id)) { var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.name = creature.creature_id + "_" + caste.caste_id; creatureBase.race = creature; creatureBase.caste = caste; creatureBase.MakeBody(); Selection.SetActiveObjectWithContext(creatureBase, null); } } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); if (GUILayout.Button("Place all creatures")) { var watch = System.Diagnostics.Stopwatch.StartNew(); CreatureBody prevCreature = null; foreach (var creature in filteredRaws) { var creatureBase = new GameObject().AddComponent <CreatureBody>(); creatureBase.name = creature.creature_id + "_" + creature.caste[0].caste_id; creatureBase.race = creature; creatureBase.caste = creature.caste[0]; creatureBase.MakeBody(); creatureBase.transform.rotation = Quaternion.LookRotation(Vector3.back); if (prevCreature != null) { creatureBase.transform.position = new Vector3(prevCreature.transform.position.x + prevCreature.bounds.max.x - creatureBase.bounds.min.x, 0, 0); } prevCreature = creatureBase; } watch.Stop(); Debug.Log(string.Format("Took {0}ms to create {1} creatures, averaging {2}ms per creature.", watch.ElapsedMilliseconds, filteredRaws.Count, (float)watch.ElapsedMilliseconds / filteredRaws.Count)); } } }
public void Shapen(CreatureBody body) { switch (category) { case "BODY_UPPER": if (body.bodyCategory == CreatureBody.BodyCategory.Humanoid) { placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1.5f, 1.5f, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); } else { placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1.5f, 1, 1.5f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); } break; case "BODY_LOWER": if (body.bodyCategory == CreatureBody.BodyCategory.Humanoid) { placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1.5f, 1.5f, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); } else { placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1.5f, 1, 1.5f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, -placeholder.transform.localScale.z / 2); } break; case "ARM_UPPER": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(0.75f, 2f, 0.75f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -(placeholder.transform.localScale.y / 2) + (placeholder.transform.localScale.x / 2), 0); break; case "ARM": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(0.75f, 4f, 0.75f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -(placeholder.transform.localScale.y / 2) + (placeholder.transform.localScale.x / 2), 0); break; case "TENTACLE": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(0.75f, 0.75f, 4f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); break; case "LEG_UPPER": case "LEG_LOWER": case "ARM_LOWER": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(0.75f, 2f, 0.75f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; case "LEG": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(0.75f, 0.75f, 4f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); break; case "LEG_FRONT": case "LEG_REAR": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 4, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; case "FOOT": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(0.5f, 0.25f, 1f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, (placeholder.transform.localScale.z / 2) - (placeholder.transform.localScale.x / 2)); break; case "FOOT_REAR": case "FOOT_FRONT": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 1, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, (placeholder.transform.localScale.z / 2) - (placeholder.transform.localScale.x / 2)); break; case "TOE": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 1, 2)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); break; case "HAND": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(2, 6, 5)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; case "FINGER": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 4, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; case "HEAD": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 1, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); break; case "MOUTH": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(3.5f, 1, 2)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, placeholder.transform.localScale.z / 2); break; case "EYE": case "EAR": placeholder.transform.localScale = MultiplyScales(body.bodyScale, Vector3.one); placeholder.FixVolume(); placeholder.transform.localPosition = Vector3.zero; break; case "EYELID": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(2.5f, 1, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y, placeholder.transform.localScale.z / 2); break; case "CHEEK": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 3, 4)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(placeholder.transform.localScale.x / 2, 0, -placeholder.transform.localScale.z / 2); break; case "TONGUE": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1.5f, 1, 2.8f)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, -placeholder.transform.localScale.z / 2); break; case "LIP": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(5, 1, 1f)); placeholder.FixVolume(); if (token.StartsWith("U")) { placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); } else { placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); } break; case "TOOTH": if (token.EndsWith("EYE_TOOTH")) { placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 1, 6)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); } else { placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(6, 1, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); } break; case "TUSK": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 6, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); break; case "WING": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(10, 1, 20)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(-placeholder.transform.localScale.x / 2, 0, placeholder.transform.localScale.z / 2); break; case "TAIL": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 4, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; case "STINGER": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 5, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; case "ANTENNA": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 8, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); break; case "HORN": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 4, 1)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); break; case "FIN": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(1, 3, 5)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, placeholder.transform.localScale.z / 2); break; case "PINCER": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(2, 1, 3)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); break; case "FLIPPER": placeholder.transform.localScale = MultiplyScales(body.bodyScale, new Vector3(3, 1, 2)); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(-placeholder.transform.localScale.y / 2, 0, placeholder.transform.localScale.z / 2); break; case "NOSE": placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, 0, placeholder.transform.localScale.z / 2); break; case "HOOF": placeholder.transform.localScale = MultiplyScales(body.bodyScale, Vector3.one); placeholder.FixVolume(); placeholder.transform.localPosition = new Vector3(0, -placeholder.transform.localScale.y / 2, 0); break; default: placeholder.transform.localScale = MultiplyScales(body.bodyScale, Vector3.one); placeholder.FixVolume(); if (flags.embedded) { placeholder.transform.localPosition = Vector3.zero; } else { placeholder.transform.localPosition = new Vector3(0, placeholder.transform.localScale.y / 2, 0); } break; } bounds = new Bounds(placeholder.transform.localPosition, placeholder.transform.localScale); }
public void Arrange(CreatureBody body) { if (modeledPart != null) { ArrangeModeledPart(body); return; } if (placeholder == null) { return; } Shapen(body); List <BodyPart> toes = new List <BodyPart>(); List <BodyPart> fingers = new List <BodyPart>(); List <BodyPart> mouthParts = new List <BodyPart>(); BodyPart mouth = null; BodyPart beak = null; List <BodyPart> leftLegs = new List <BodyPart>(); List <BodyPart> rightLegs = new List <BodyPart>(); List <BodyPart> multiArms = new List <BodyPart>(); List <BodyPart> tentacles = new List <BodyPart>(); List <BodyPart> centerEyes = new List <BodyPart>(); foreach (Transform child in transform) { var childPart = child.GetComponent <BodyPart>(); if (childPart == null) { continue; } childPart.Arrange(body); switch (childPart.category) { case "BODY_LOWER": if (body.bodyCategory == CreatureBody.BodyCategory.Humanoid) { childPart.transform.localPosition = new Vector3(0, bounds.min.y, 0); } else { childPart.transform.localPosition = new Vector3(0, 0, bounds.min.z); } break; case "LEG_UPPER": case "LEG": childPart.transform.localPosition = new Vector3(bounds.extents.x / 2 * (childPart.flags.left ? -1 : 1), bounds.min.y, 0); break; case "FOOT": case "FOOT_REAR": case "FOOT_FRONT": childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.min.y, bounds.center.z); break; case "TOE": toes.Add(childPart); break; case "FINGER": if (childPart.token.EndsWith("1")) //It's a thumb { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.center.y, bounds.max.z + childPart.bounds.extents.z); } else { fingers.Add(childPart); } break; case "NECK": switch (body.bodyCategory) { case CreatureBody.BodyCategory.Humanoid: childPart.transform.localPosition = new Vector3(0, bounds.max.y, 0); break; case CreatureBody.BodyCategory.Bug: case CreatureBody.BodyCategory.Fish: childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.center.y, bounds.max.z); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.down, Vector3.forward); break; case CreatureBody.BodyCategory.Quadruped: case CreatureBody.BodyCategory.Avian: default: childPart.transform.localPosition = new Vector3(0, bounds.max.y, bounds.max.z - childPart.bounds.extents.z); break; } break; case "ARM_UPPER": case "ARM": if (!childPart.flags.left && !childPart.flags.right) { multiArms.Add(childPart); } else { childPart.transform.localPosition = new Vector3((bounds.extents.x + childPart.bounds.extents.x) * (childPart.flags.left ? -1 : 1), bounds.max.y - childPart.bounds.extents.x, 0); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.down, new Vector3(child.transform.localPosition.x, 0, 0)); } break; case "ARM_LOWER": case "LEG_LOWER": case "HAND": childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.min.y, bounds.center.z); break; case "TENTACLE": tentacles.Add(childPart); break; case "HEAD": if (category == "NECK") { switch (body.bodyCategory) { case CreatureBody.BodyCategory.Fish: case CreatureBody.BodyCategory.Bug: childPart.transform.localPosition = new Vector3(0, bounds.max.y + childPart.bounds.extents.z, bounds.center.z + childPart.bounds.center.y); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.up, Vector3.back); break; case CreatureBody.BodyCategory.Humanoid: case CreatureBody.BodyCategory.Quadruped: case CreatureBody.BodyCategory.Avian: default: childPart.transform.localPosition = new Vector3(0, bounds.max.y, 0); break; } } else { switch (body.bodyCategory) { case CreatureBody.BodyCategory.Humanoid: childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.max.y, bounds.center.z); break; case CreatureBody.BodyCategory.Bug: case CreatureBody.BodyCategory.Fish: childPart.transform.localPosition = new Vector3(0, bounds.center.y - childPart.bounds.center.y, bounds.max.z - childPart.bounds.min.z); break; case CreatureBody.BodyCategory.Quadruped: case CreatureBody.BodyCategory.Avian: default: childPart.transform.localPosition = new Vector3(0, bounds.max.y, bounds.max.z - childPart.bounds.extents.z); break; } childPart.transform.localRotation = Quaternion.LookRotation(Vector3.forward, Vector3.up); } break; case "EYELID": case "EYE": if (childPart.token.StartsWith("R")) { childPart.transform.localPosition = new Vector3(bounds.center.x - bounds.extents.x / 2, bounds.center.y, bounds.max.z); } else if (childPart.token.StartsWith("L")) { childPart.transform.localPosition = new Vector3(bounds.center.x + bounds.extents.x / 2, bounds.center.y, bounds.max.z); } else { centerEyes.Add(childPart); } break; case "MOUTH": childPart.transform.localPosition = new Vector3(0, bounds.min.y, bounds.max.z - childPart.bounds.max.z); mouth = childPart; break; case "BEAK": childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.min.y - childPart.bounds.min.y, bounds.max.z); mouth = childPart; break; case "NOSE": childPart.transform.localPosition = new Vector3(0, bounds.center.y - (bounds.extents.y / 2), bounds.max.z); break; case "EAR": childPart.transform.localPosition = new Vector3(bounds.center.x + (bounds.extents.x * (childPart.flags.left ? -1 : 1)), bounds.center.y, bounds.center.z); childPart.transform.localRotation = Quaternion.LookRotation(new Vector3(child.transform.localPosition.x, 0, 0), Vector3.up); break; case "CHEEK": case "TONGUE": case "LIP": case "TOOTH": case "TUSK": mouthParts.Add(childPart); break; case "LEG_FRONT": case "LEG_REAR": if (childPart.token.StartsWith("L")) { leftLegs.Add(childPart); } else { rightLegs.Add(childPart); } break; case "WING": childPart.transform.localPosition = new Vector3(bounds.extents.x * (childPart.flags.left ? -1 : 1), bounds.max.y, bounds.center.z); childPart.transform.localRotation = Quaternion.Euler(-30, 0, 0); break; case "TAIL": if (body.bodyCategory == CreatureBody.BodyCategory.Humanoid) { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.min.y, bounds.min.z); childPart.transform.localRotation = Quaternion.LookRotation(new Vector3(0, -1, -1), Vector3.up); } else { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.max.y, bounds.min.z); childPart.transform.localRotation = Quaternion.Euler(135, 0, 0); } break; case "STINGER": childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.min.y, bounds.center.z); childPart.transform.localRotation = Quaternion.LookRotation(new Vector3(0, -1, 1), Vector3.forward); break; case "ANTENNA": { bool left = childPart.token.StartsWith("L"); childPart.transform.localPosition = new Vector3(bounds.center.x + (bounds.extents.x * (left ? -1 : 1)), bounds.max.y, bounds.max.z); childPart.transform.localRotation = Quaternion.Euler(30, left ? -15 : 15, 0); } break; case "HORN": { bool left = childPart.token.StartsWith("L"); childPart.transform.localPosition = new Vector3(bounds.center.x + (bounds.extents.x * (left ? -1 : 1)), bounds.max.y, bounds.center.z); childPart.transform.localRotation = Quaternion.Euler(30, left ? -15 : 15, 0); } break; case "SHELL": case "HUMP": if (body.bodyCategory != CreatureBody.BodyCategory.Humanoid) { if (FindChild("BODY_LOWER") == null) { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.max.y, bounds.center.z); } else { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.max.y, bounds.min.z); } } else { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.center.y, bounds.min.z); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.up, Vector3.back); } break; case "FIN": if (childPart.token.StartsWith("R")) { childPart.transform.localPosition = new Vector3(bounds.max.x, bounds.center.y, bounds.center.z); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.right, Vector3.forward); } else if (childPart.token.StartsWith("L")) { childPart.transform.localPosition = new Vector3(bounds.min.x, bounds.center.y, bounds.center.z); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.left, Vector3.forward); } else { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.max.y, bounds.center.z); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.up, Vector3.forward); } break; case "PINCER": childPart.transform.localPosition = new Vector3(bounds.min.x * (childPart.flags.left ? -1 : 1), bounds.center.y, bounds.max.z); childPart.transform.localRotation = Quaternion.LookRotation(new Vector3(childPart.flags.left ? 1 : -1, 0, 1)); break; case "FLIPPER": childPart.transform.localPosition = new Vector3(bounds.min.x * (childPart.flags.left ? -1 : 1), bounds.center.y, bounds.max.z); break; default: childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.center.y, bounds.max.z); break; } if (childPart.flags.left && !flags.left) { childPart.transform.localScale = new Vector3(-1, 1, 1); } } for (int i = 0; i < toes.Count; i++) { float basecoord = bounds.min.x; float step = bounds.size.x / toes.Count; toes[i].transform.localPosition = new Vector3(basecoord + step / 2 + step * i, bounds.min.y - toes[i].bounds.min.y, bounds.max.z); } for (int i = 0; i < fingers.Count; i++) { float basecoord = bounds.min.z; float step = bounds.size.z / fingers.Count; fingers[i].transform.localPosition = new Vector3(bounds.center.x, bounds.min.y, basecoord + step / 2 + step * i); } if (mouth != null) { foreach (var childPart in mouthParts) { switch (childPart.category) { case "TONGUE": childPart.transform.SetParent(mouth.transform, false); childPart.transform.localPosition = new Vector3(0, 0, mouth.bounds.max.z - mouth.bounds.extents.y); break; case "LIP": if (childPart.token.StartsWith("L")) { childPart.transform.SetParent(mouth.transform, false); childPart.transform.localPosition = new Vector3(0, mouth.bounds.max.y, mouth.bounds.max.z); } else { childPart.transform.localPosition = new Vector3(0, bounds.min.y, bounds.max.z); } break; case "CHEEK": childPart.transform.localPosition = new Vector3(bounds.center.x + (mouth.bounds.extents.x * (childPart.token.StartsWith("L") ? -1 : 1)), bounds.min.y, bounds.max.z); if (childPart.token.StartsWith("L")) { childPart.transform.localScale = new Vector3(-1, 1, 1); } break; case "TOOTH": if (childPart.token.StartsWith("U_F_")) { childPart.transform.localPosition = new Vector3(bounds.center.x, bounds.min.y - mouth.bounds.extents.y * 0.01f, bounds.max.z - childPart.bounds.extents.z); childPart.transform.localScale = new Vector3(1, -1, 1); } else if (childPart.token.StartsWith("L_F_")) { childPart.transform.SetParent(mouth.transform); childPart.transform.localPosition = new Vector3(mouth.bounds.center.x, mouth.bounds.max.y + mouth.bounds.extents.y * 0.01f, mouth.bounds.max.z - childPart.bounds.extents.z); } else if (childPart.token.StartsWith("U_R_B_")) { childPart.transform.localPosition = new Vector3(mouth.bounds.max.x - childPart.bounds.extents.z, bounds.min.y - mouth.bounds.extents.y * 0.50f, bounds.max.z - childPart.bounds.extents.x); childPart.transform.localScale = new Vector3(1, -1, 1); childPart.transform.localRotation = Quaternion.Euler(0, 90, 0); } else if (childPart.token.StartsWith("U_L_B_")) { childPart.transform.localPosition = new Vector3(mouth.bounds.min.x + childPart.bounds.extents.z, bounds.min.y - mouth.bounds.extents.y * 0.01f, bounds.max.z - childPart.bounds.extents.x); childPart.transform.localScale = new Vector3(1, -1, -1); childPart.transform.localRotation = Quaternion.Euler(0, 90, 0); } else if (childPart.token.StartsWith("L_R_B_")) { childPart.transform.SetParent(mouth.transform, false); childPart.transform.localPosition = new Vector3(mouth.bounds.max.x - childPart.bounds.extents.z, mouth.bounds.max.y + mouth.bounds.extents.y * 0.01f, mouth.bounds.max.z - childPart.bounds.extents.x); childPart.transform.localScale = new Vector3(1, 1, 1); childPart.transform.localRotation = Quaternion.Euler(0, 90, 0); } else if (childPart.token.StartsWith("L_L_B_")) { childPart.transform.SetParent(mouth.transform, false); childPart.transform.localPosition = new Vector3(mouth.bounds.min.x + childPart.bounds.extents.z, mouth.bounds.max.y + mouth.bounds.extents.y * 0.01f, mouth.bounds.max.z - childPart.bounds.extents.x); childPart.transform.localScale = new Vector3(1, 1, -1); childPart.transform.localRotation = Quaternion.Euler(0, 90, 0); } else if (childPart.token.StartsWith("R_EYE")) { childPart.transform.localPosition = new Vector3(mouth.bounds.max.x - childPart.bounds.extents.z, bounds.min.y, bounds.max.z); childPart.transform.localScale = new Vector3(1, 1, 1); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.down, Vector3.back); } else if (childPart.token.StartsWith("L_EYE")) { childPart.transform.localPosition = new Vector3(mouth.bounds.min.x + childPart.bounds.extents.z, bounds.min.y, bounds.max.z); childPart.transform.localScale = new Vector3(-1, 1, 1); childPart.transform.localRotation = Quaternion.LookRotation(Vector3.down, Vector3.back); } break; case "TUSK": if (childPart.token.StartsWith("R")) { childPart.transform.localPosition = new Vector3(mouth.bounds.max.x - childPart.bounds.extents.z, bounds.min.y, bounds.max.z); childPart.transform.localScale = new Vector3(1, 1, 1); } else if (childPart.token.StartsWith("L")) { childPart.transform.localPosition = new Vector3(mouth.bounds.min.x + childPart.bounds.extents.z, bounds.min.y, bounds.max.z); childPart.transform.localScale = new Vector3(-1, 1, 1); } break; default: break; } } } else if (beak != null) { foreach (var childPart in mouthParts) { switch (childPart.category) { case "TONGUE": childPart.transform.SetParent(beak.transform, false); childPart.transform.localPosition = bounds.center; break; default: break; } } } float legZ = bounds.min.z; if (category == "BODY_UPPER") { legZ = bounds.max.z; } switch (body.bodyCategory) { case CreatureBody.BodyCategory.Bug: AlignManyParts( leftLegs, new Vector3(bounds.min.x, bounds.center.y, bounds.max.z), Quaternion.Euler(-60, -45, 0), new Vector3(bounds.min.x, bounds.center.y, bounds.min.z), Quaternion.Euler(-60, -135, 0), 0); AlignManyParts( rightLegs, new Vector3(bounds.max.x, bounds.center.y, bounds.max.z), Quaternion.Euler(-60, 45, 0), new Vector3(bounds.max.x, bounds.center.y, bounds.min.z), Quaternion.Euler(-60, 135, 0), 0); break; case CreatureBody.BodyCategory.Humanoid: case CreatureBody.BodyCategory.Quadruped: case CreatureBody.BodyCategory.Avian: default: AlignManyParts( leftLegs, new Vector3(bounds.min.x, bounds.max.y, legZ), Quaternion.identity, new Vector3(bounds.min.x, bounds.max.y, legZ), Quaternion.identity, 0); AlignManyParts( rightLegs, new Vector3(bounds.max.x, bounds.max.y, legZ), Quaternion.identity, new Vector3(bounds.max.x, bounds.max.y, legZ), Quaternion.identity, 0); break; } AlignManyParts(multiArms, new Vector3(bounds.max.x, bounds.min.y, bounds.max.z), Quaternion.LookRotation(new Vector3(1, -0.5f, 1)), new Vector3(bounds.min.x, bounds.min.y, bounds.max.z), Quaternion.LookRotation(new Vector3(-1, -0.5f, 1)), 0.5f); AlignManyParts(tentacles, new Vector3(bounds.max.x, bounds.min.y, bounds.max.z), Quaternion.LookRotation(new Vector3(1, -1, 1)), new Vector3(bounds.min.x, bounds.min.y, bounds.max.z), Quaternion.LookRotation(new Vector3(-1, -1, 1)), 0.5f); AlignManyParts(centerEyes, new Vector3(bounds.center.x + bounds.extents.x, bounds.center.y + bounds.extents.y / 2, bounds.max.z), Quaternion.identity, new Vector3(bounds.center.x - bounds.extents.x, bounds.center.y + bounds.extents.y / 2, bounds.max.z), Quaternion.identity, 0.5f); }
void ArrangeModeledPart(CreatureBody body) { if (modeledPart == null) { return; } var partSize = Vector3.one; foreach (var mod in mods) { var value = 100; if (body.unit != null && body.unit.appearance != null) { value = body.unit.appearance.bp_modifiers[mod.index]; } switch (mod.type) { case "BROADNESS": partSize.x = value / 100f; break; case "HEIGHT": partSize.y = value / 100f; break; case "LENGTH": partSize.z = value / 100f; break; default: break; } } //If the're flagged as small, they don't need to worry about volume. Just need to scale according to the parent. if (!flags.small) { modeledPart.transform.localScale = MultiplyScales(body.bodyScale, partSize); modeledPart.volume = volume; modeledPart.FixVolume(); } bounds = modeledPart.GetComponentInChildren <MeshRenderer>().bounds; foreach (var renderer in GetComponentsInChildren <MeshRenderer>()) { bounds.Encapsulate(renderer.bounds); } List <ChildPlacement> placements = new List <ChildPlacement>(); foreach (Transform child in modeledPart.transform) { BodyPartChildPlaceholder bodyPartChild = child.GetComponent <BodyPartChildPlaceholder>(); if (bodyPartChild == null) { continue; } bool placedPart = false; foreach (var placement in placements) { if (placement.Matches(bodyPartChild)) { placement.Add(bodyPartChild); placedPart = true; } } if (!placedPart) { placements.Add(new ChildPlacement(bodyPartChild)); } } List <BodyPart> childParts = new List <BodyPart>(); foreach (Transform child in transform) { var childPart = child.GetComponent <BodyPart>(); if (childPart == null) { continue; } childParts.Add(childPart); } foreach (var childPart in childParts) { if (childPart.flags.small && childPart.modeledPart != null) { //Its size doesn't matter if it's considered small, so it should just take the scale directly from the parent part. //Also, this only applies to parts that actually have models defined. Procedural parts still use the old system. childPart.transform.SetParent(modeledPart.transform, false); } foreach (var placement in placements) { if (placement.Matches(childPart)) { placement.Add(childPart); break; } } childPart.Arrange(body); } foreach (var placement in placements) { placement.Arrange(); } }
public static bool GetBody(string bodyName, out CreatureBody body) { return(mBodyLookup.TryGetValue(bodyName, out body)); }
void ArrangeModeledPart(CreatureBody body) { if (modeledPart == null) { return; } var partSize = Vector3.one; foreach (var mod in mods) { var value = 100; value = mod.value; switch (mod.type) { case "BROADNESS": partSize.x = value / 100f; break; case "HEIGHT": case "ROUND_VS_NARROW": partSize.y = value / 100f; break; case "LENGTH": partSize.z = value / 100f; break; case "CLOSE_SET": modeledPart.transform.localPosition = new Vector3(Mathf.Abs(transform.localPosition.x * (value / 100f - 1)) / 2.0f, 0, 0); break; case "SPLAYED_OUT": modeledPart.transform.localRotation = Quaternion.Euler(0, -value / 200f * 90, 0); break; default: break; } } //If the're flagged as small, they don't need to worry about volume. Just need to scale according to the parent. if (flags.small) { modeledPart.transform.localScale = partSize; } if (!flags.small) { modeledPart.transform.localScale = MultiplyScales(body.bodyScale, partSize); modeledPart.volume = volume; modeledPart.FixVolume(); } bounds = modeledPart.GetComponentInChildren <MeshRenderer>().bounds; foreach (var renderer in GetComponentsInChildren <MeshRenderer>()) { bounds.Encapsulate(renderer.bounds); } List <ChildPlacement> placements = new List <ChildPlacement>(); foreach (Transform child in modeledPart.transform) { BodyPartChildPlaceholder bodyPartChild = child.GetComponent <BodyPartChildPlaceholder>(); if (bodyPartChild == null) { continue; } if (bodyPartChild.category == ":ATTACH:") { heldItemPoint = child; } bool placedPart = false; foreach (var placement in placements) { if (placement.Matches(bodyPartChild)) { placement.Add(bodyPartChild); placedPart = true; } } if (!placedPart) { placements.Add(new ChildPlacement(bodyPartChild)); } } List <BodyPart> childParts = new List <BodyPart>(); foreach (Transform child in transform) { var childPart = child.GetComponent <BodyPart>(); if (childPart == null) { continue; } childParts.Add(childPart); } foreach (var childPart in childParts) { if (childPart.flags.small && childPart.modeledPart != null) { //Its size doesn't matter if it's considered small, so it should just take the scale directly from the parent part. //Also, this only applies to parts that actually have models defined. Procedural parts still use the old system. childPart.transform.SetParent(modeledPart.transform, false); } bool placed = false; foreach (var placement in placements) { if (placement.Matches(childPart)) { placement.Add(childPart); placed = true; break; } } if (!placed) { childPart.gameObject.SetActive(false); } } foreach (var placement in placements) { placement.Arrange(); } foreach (var childPart in childParts) { childPart.Arrange(body); } }