public static Vector2 FixtureOffset(this Fixture value, BodyCategory category, Vector2 position, Vector2 shapeOffset) { Vector2 offset = Vector2.Zero; if (value != null) { Transform bodyTrans; value.Body.GetTransform(out bodyTrans); AABB bounds; value.Shape.ComputeAABB(out bounds, ref bodyTrans, 0); switch (category) { case BodyCategory.ChainShape: case BodyCategory.CompoundPolygon: case BodyCategory.Gear: case BodyCategory.Polygon: case BodyCategory.RoundedRectangle: case BodyCategory.SolidArc: offset = bounds.LowerBound.ToDisplayUnits() - position + shapeOffset; break; case BodyCategory.LineArc: offset = new Vector2(-2.5f, 0); // Slight offset for generated arc textures break; } } return(offset); }
public void MakeBody() { if (!gotShaderIds) { GetShaderIDs(); } flags = new CreatureRawFlags(race.flags); bodyCategory = FindBodyCategory(caste); //If there's already any spawned parts, we need to clear them so we can remake the body from scratch. if (spawnedParts.Count > 0) { foreach (var part in spawnedParts) { if (part.Value != null) { if (Application.isPlaying) { Destroy(part.Value.gameObject); } else { DestroyImmediate(part.Value.gameObject); } } } spawnedParts.Clear(); } //Clearing this will serve the purpose of resetting the inventory. inventoryModes = new InventoryMode[0]; //They're made standing, so the current state should reflect that. onGround = false; float unitVolume = caste.adult_size; if (unit != null && unit.size_info != null) { unitVolume = unit.size_info.size_cur; } unitVolume = UnitScaler.GetAdjustedUnitSize(unitVolume); float scale = unitVolume / caste.total_relsize * 10; MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock(); bodyScale = BodyDefinition.GetBodyScale(bodyCategory, race, caste); Vector3 unitShape = Vector3.one; for (int i = 0; i < caste.body_appearance_modifiers.Count; i++) { var mod = caste.body_appearance_modifiers[i]; int value = 100; if (unit != null && unit.appearance != null) { value = unit.appearance.body_modifiers[i]; } else { value = UnityEngine.Random.Range(mod.mod_min, mod.mod_max); } switch (mod.type) { case "BROADNESS": unitShape.x = value / 100f; break; case "HEIGHT": unitShape.y = value / 100f; break; case "LENGTH": unitShape.z = value / 100f; break; default: break; } } bodyScale = BodyPart.MultiplyScales(bodyScale, unitShape); for (int i = 0; i < caste.body_parts.Count; i++) { var part = caste.body_parts[i]; if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } var spawnedPart = new GameObject().AddComponent <BodyPart>(); spawnedPart.name = string.Format("{0} ({1})", part.token, part.category); spawnedPart.token = part.token; spawnedPart.category = part.category; spawnedPart.flags = new BodyPartFlags(part.flags); spawnedPart.volume = part.relsize * scale; spawnedPart.layers = part.layers; var model = BodyDefinition.GetPart(bodyCategory, race, caste, part); if (model != null) { #if UNITY_EDITOR var placedModel = (BodyPartModel)UnityEditor.PrefabUtility.InstantiatePrefab(model); #else var placedModel = Instantiate(model); #endif placedModel.transform.SetParent(spawnedPart.transform); placedModel.CollectEquipment(); spawnedPart.modeledPart = placedModel; } if (spawnedPart.modeledPart == null) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent <VolumeKeeper>(); if ((Application.isPlaying)) { Destroy(cube.GetComponent <BoxCollider>()); } else { DestroyImmediate(cube.GetComponent <BoxCollider>()); } cube.name = spawnedPart.name + " cube"; cube.transform.SetParent(spawnedPart.transform); cube.volume = spawnedPart.volume; cube.FixVolume(); cube.gameObject.AddComponent <BodyLayer>(); spawnedPart.placeholder = cube; if (skinMat == null) { skinMat = Resources.Load <Material>("Skin"); } cube.GetComponent <MeshRenderer>().sharedMaterial = skinMat; } if (spawnedPart.flags.upperbody) { upperBody = spawnedPart; foreach (var item in spawnedPart.GetComponentsInChildren <BodyPartChildPlaceholder>()) { if (item.category == ":ATTACH:") { riderPosition = item.transform; break; } } } if (spawnedPart.flags.lowerbody) { lowerBody = spawnedPart; } var modeledLayers = spawnedPart.GetComponentsInChildren <BodyLayer>(); foreach (var modeledLayer in modeledLayers) { modeledLayer.parentPart = spawnedPart; } foreach (var layer in part.layers) { var matchedLayers = Array.FindAll(modeledLayers, x => x.layerName == layer.layer_name); if (matchedLayers.Length == 0) { matchedLayers = Array.FindAll(modeledLayers, x => string.IsNullOrEmpty(x.layerName)); if (matchedLayers.Length == 0) { spawnedPart.layerModels.Add(new BodyLayerPlaceholder(layer)); } else { bool matchedAny = false; foreach (var matchedLayer in matchedLayers) { if (!matchedLayer.placed) { matchedLayer.layerRaw = layer; spawnedPart.layerModels.Add(matchedLayer); matchedLayer.placed = true; matchedAny = true; break; } } if (!matchedAny) { spawnedPart.layerModels.Add(new BodyLayerPlaceholder(layer)); } } } else { bool matchedAny = false; foreach (var matchedLayer in matchedLayers) { if (!matchedLayer.placed) { matchedLayer.layerRaw = layer; spawnedPart.layerModels.Add(matchedLayer); matchedLayer.placed = true; matchedAny = true; break; } } if (!matchedAny) { spawnedPart.layerModels.Add(new BodyLayerPlaceholder(layer)); } } } foreach (var modeledLayer in modeledLayers) { if (!modeledLayer.placed) { modeledLayer.gameObject.SetActive(false); } } foreach (var layerModel in spawnedPart.layerModels) { if (layerModel == null || !(layerModel is BodyLayer)) { continue; } ((BodyLayer)layerModel).ApplyMaterials(race, propertyBlock); } spawnedParts[i] = spawnedPart; } for (int modNum = 0; modNum < caste.modifier_idx.Count; modNum++) { if (!spawnedParts.ContainsKey(caste.part_idx[modNum])) { continue; } var mod = caste.modifiers[caste.modifier_idx[modNum]]; var part = spawnedParts[caste.part_idx[modNum]]; if (caste.layer_idx[modNum] >= 0) { var layer = part.layerModels[caste.layer_idx[modNum]]; if (layer != null) { layer.AddMod(new BodyPart.ModValue(mod, (unit != null && unit.appearance != null) ? unit.appearance.bp_modifiers[modNum] : 100)); } } else { part.mods.Add(new BodyPart.ModValue(mod, (unit != null && unit.appearance != null) ? unit.appearance.bp_modifiers[modNum] : 100)); } } for (int modNum = 0; modNum < caste.color_modifiers.Count; modNum++) { var colorMod = caste.color_modifiers[modNum]; int seed = Mathf.Abs(GetInstanceID() * modNum) % colorMod.patterns.Count; for (int i = 0; i < colorMod.body_part_id.Count; i++) { var part = spawnedParts[colorMod.body_part_id[i]]; if (part == null || !part.gameObject.activeSelf) { continue; } var layer = part.layerModels[colorMod.tissue_layer_id[i]]; if (layer == null || !layer.IsActive || !(layer is BodyLayer)) { continue; } PatternDescriptor pattern; if (unit != null && unit.appearance != null) { pattern = colorMod.patterns[unit.appearance.colors[modNum]]; } else { pattern = colorMod.patterns[seed]; } var matIndex = ContentLoader.GetPatternIndex(race.tissues[layer.TissueID].material); var shapeIndex = ContentLoader.GetShapeIndex(race.tissues[layer.TissueID].material); if (colorMod.start_date > 0 && unit != null) { ((BodyLayer)layer).ApplyPattern(pattern, Mathf.InverseLerp(colorMod.start_date * 1200, colorMod.end_date * 1200, unit.age), propertyBlock, matIndex, shapeIndex); } else { ((BodyLayer)layer).ApplyPattern(pattern, 1, propertyBlock, matIndex, shapeIndex); } } } for (int i = 0; i < caste.body_parts.Count; i++) { if (!spawnedParts.ContainsKey(i)) { continue; } var part = caste.body_parts[i]; if (!spawnedParts.ContainsKey(part.parent)) { spawnedParts[i].transform.SetParent(transform); } else { spawnedParts[i].transform.SetParent(spawnedParts[part.parent].transform); spawnedParts[i].parent = spawnedParts[part.parent]; spawnedParts[part.parent].children.Add(spawnedParts[i]); } if (part.parent < 0) { rootPart = spawnedParts[i]; } if (spawnedParts[i].flags.stance) { stanceCount++; } } foreach (var part in spawnedParts) { foreach (var layer in part.Value.layerModels) { if (layer != null && (layer is BodyLayer)) { ((BodyLayer)layer).ApplyMods(); } } } if (rootPart == null) { return; //There's no root part, means there's no body. } //Use this when we do body part mods. //for(int i = 0; i < caste.modifier_idx.Count; i++) //{ // var modifier = caste.modifiers[caste.modifier_idx[i]]; // var part = caste.body_parts[caste.part_idx[i]]; //} rootPart.Arrange(this); foreach (var part in spawnedParts) { if (part.Value.flags.head) { part.Value.transform.localScale *= GameSettings.Instance.units.chibiness; } } if (unit != null && unit.wounds != null) { foreach (var wound in unit.wounds) { foreach (var woundPart in wound.parts) { if (spawnedParts.ContainsKey(woundPart.body_part_id)) { spawnedParts[woundPart.body_part_id].gameObject.SetActive(!wound.severed_part); } } } } bounds = rootPart.GetComponentInChildren <MeshRenderer>().bounds; foreach (var item in rootPart.GetComponentsInChildren <MeshRenderer>()) { bounds.Encapsulate(item.bounds); } rootPart.transform.localPosition = new Vector3(0, -bounds.min.y, 0); }
public void MakeBody() { flags = new CreatureRawFlags(race.flags); bodyCategory = FindBodyCategory(caste); if (spawnedParts.Count > 0) { foreach (var part in spawnedParts) { Destroy(part.Value.gameObject); } spawnedParts.Clear(); } float scale = caste.adult_size / (float)caste.total_relsize * 10; if (unit != null && unit.size_info != null) { scale = unit.size_info.size_cur / (float)caste.total_relsize * 10; } MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock(); bodyScale = BodyDefinition.GetBodyScale(bodyCategory, race, caste); Vector3 unitShape = Vector3.one; for (int i = 0; i < caste.body_appearance_modifiers.Count; i++) { var mod = caste.body_appearance_modifiers[i]; int value = 100; if (unit != null && unit.appearance != null) { value = unit.appearance.body_modifiers[i]; } else { value = UnityEngine.Random.Range(mod.mod_min, mod.mod_max); } switch (mod.type) { case "BROADNESS": unitShape.x = value / 100f; break; case "HEIGHT": unitShape.y = value / 100f; break; case "LENGTH": unitShape.z = value / 100f; break; default: break; } } bodyScale = BodyPart.MultiplyScales(bodyScale, unitShape); for (int i = 0; i < caste.body_parts.Count; i++) { var part = caste.body_parts[i]; if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } var spawnedPart = new GameObject().AddComponent <BodyPart>(); spawnedPart.name = string.Format("{0} ({1})", part.token, part.category); spawnedPart.token = part.token; spawnedPart.category = part.category; spawnedPart.flags = new BodyPartFlags(part.flags); spawnedPart.volume = part.relsize * scale; spawnedPart.layers = part.layers; var model = BodyDefinition.GetPart(bodyCategory, race, caste, part); if (model != null) { var placedModel = Instantiate(model); placedModel.transform.SetParent(spawnedPart.transform); placedModel.CollectEquipment(); spawnedPart.modeledPart = placedModel; } if (spawnedPart.modeledPart == null) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent <VolumeKeeper>(); if ((Application.isPlaying)) { Destroy(cube.GetComponent <BoxCollider>()); } else { DestroyImmediate(cube.GetComponent <BoxCollider>()); } cube.name = spawnedPart.name + " cube"; cube.transform.SetParent(spawnedPart.transform); cube.volume = spawnedPart.volume; cube.FixVolume(); cube.gameObject.AddComponent <BodyLayer>(); spawnedPart.placeholder = cube; if (skinMat == null) { skinMat = Resources.Load <Material>("Skin"); } cube.GetComponent <MeshRenderer>().sharedMaterial = skinMat; } if (spawnedPart.flags.upperbody) { upperBody = spawnedPart; foreach (var item in spawnedPart.GetComponentsInChildren <BodyPartChildPlaceholder>()) { if (item.category == ":ATTACH:") { riderPosition = item.transform; break; } } } if (spawnedPart.flags.lowerbody) { lowerBody = spawnedPart; } var modeledLayers = spawnedPart.GetComponentsInChildren <BodyLayer>(); foreach (var layer in part.layers) { var matchedLayers = Array.FindAll(modeledLayers, x => x.layerName == layer.layer_name); if (matchedLayers.Length == 0) { matchedLayers = Array.FindAll(modeledLayers, x => string.IsNullOrEmpty(x.layerName)); if (matchedLayers.Length < 0) { spawnedPart.layerModels.Add(null); } else { bool matchedAny = false; foreach (var matchedLayer in matchedLayers) { if (!matchedLayer.placed) { matchedLayer.layerRaw = layer; spawnedPart.layerModels.Add(matchedLayer); matchedLayer.placed = true; matchedAny = true; break; } } if (!matchedAny) { spawnedPart.layerModels.Add(null); } } } else { bool matchedAny = false; foreach (var matchedLayer in matchedLayers) { if (!matchedLayer.placed) { matchedLayer.layerRaw = layer; spawnedPart.layerModels.Add(matchedLayer); matchedLayer.placed = true; matchedAny = true; break; } } if (!matchedAny) { spawnedPart.layerModels.Add(null); } } } foreach (var modeledLayer in modeledLayers) { if (!modeledLayer.placed) { modeledLayer.gameObject.SetActive(false); } } foreach (var layerModel in spawnedPart.layerModels) { if (layerModel == null) { continue; } var renderer = layerModel.GetComponentInChildren <MeshRenderer>(); if (renderer != null) { var tissue = race.tissues[layerModel.layerRaw.tissue_id]; var color = ContentLoader.GetColor(tissue.material); var index = ContentLoader.GetPatternIndex(tissue.material); propertyBlock.SetColor("_MatColor", color); propertyBlock.SetFloat("_MatIndex", index); renderer.SetPropertyBlock(propertyBlock); } } spawnedParts[i] = spawnedPart; } for (int modNum = 0; modNum < caste.modifier_idx.Count; modNum++) { if (!spawnedParts.ContainsKey(caste.part_idx[modNum])) { continue; } var mod = caste.modifiers[caste.modifier_idx[modNum]]; var part = spawnedParts[caste.part_idx[modNum]]; if (caste.layer_idx[modNum] >= 0) { var layer = part.layerModels[caste.layer_idx[modNum]]; if (layer != null) { layer.mods.Add(new BodyPart.ModValue(mod, modNum)); } } else { part.mods.Add(new BodyPart.ModValue(mod, modNum)); } } for (int modNum = 0; modNum < caste.color_modifiers.Count; modNum++) { var mod = caste.color_modifiers[modNum]; //Temp fix until actual creatures are being read. if (mod.start_date > 0) { continue; } int seed = Mathf.Abs(GetInstanceID() * modNum) % mod.patterns.Count; for (int i = 0; i < mod.body_part_id.Count; i++) { var part = spawnedParts[mod.body_part_id[i]]; if (part == null || !part.gameObject.activeSelf) { continue; } var layer = part.layerModels[mod.tissue_layer_id[i]]; if (layer == null || !layer.gameObject.activeSelf) { continue; } ColorDefinition colorDef; if (unit != null && unit.appearance != null) { colorDef = mod.patterns[unit.appearance.colors[modNum]].colors[0]; } else { colorDef = mod.patterns[seed].colors[0]; } var color = new Color32((byte)colorDef.red, (byte)colorDef.green, (byte)colorDef.blue, 128); var index = ContentLoader.GetPatternIndex(race.tissues[layer.layerRaw.tissue_id].material); propertyBlock.SetColor("_MatColor", color); propertyBlock.SetFloat("_MatIndex", index); var renderer = layer.GetComponentInChildren <MeshRenderer>(); if (renderer != null) { renderer.SetPropertyBlock(propertyBlock); } } } for (int i = 0; i < caste.body_parts.Count; i++) { if (!spawnedParts.ContainsKey(i)) { continue; } var part = caste.body_parts[i]; if (!spawnedParts.ContainsKey(part.parent)) { spawnedParts[i].transform.SetParent(transform); } else { spawnedParts[i].transform.SetParent(spawnedParts[part.parent].transform); spawnedParts[i].parent = spawnedParts[part.parent]; spawnedParts[part.parent].children.Add(spawnedParts[i]); } if (part.parent < 0) { rootPart = spawnedParts[i]; } if (spawnedParts[i].flags.stance) { stanceCount++; } } if (rootPart == null) { return; //There's no root part, means there's no body. } //Use this when we do body part mods. //for(int i = 0; i < caste.modifier_idx.Count; i++) //{ // var modifier = caste.modifiers[caste.modifier_idx[i]]; // var part = caste.body_parts[caste.part_idx[i]]; //} rootPart.Arrange(this); bounds = rootPart.GetComponentInChildren <MeshRenderer>().bounds; foreach (var item in rootPart.GetComponentsInChildren <MeshRenderer>()) { bounds.Encapsulate(item.bounds); } rootPart.transform.localPosition = new Vector3(0, -bounds.min.y, 0); }
public void MakeBody() { bodyCategory = FindBodyCategory(caste); var spawnedParts = new Dictionary <int, BodyPart>(); float scale = caste.adult_size / (float)caste.total_relsize * 10; for (int i = 0; i < caste.body_parts.Count; i++) { var part = caste.body_parts[i]; if (part.flags[(int)BodyPartFlags.BodyPartRawFlags.INTERNAL]) { continue; } var spawnedPart = new GameObject().AddComponent <BodyPart>(); spawnedPart.name = string.Format("{0} ({1})", part.token, part.category); spawnedPart.token = part.token; spawnedPart.category = part.category; spawnedPart.flags = new BodyPartFlags(part.flags); spawnedPart.volume = part.relsize * scale; bodyScale = BodyDefinition.GetBodyScale(bodyCategory, race, caste); var model = BodyDefinition.GetPart(bodyCategory, race, caste, part); if (model != null) { var placedModel = Instantiate(model); placedModel.transform.SetParent(spawnedPart.transform); placedModel.volume = spawnedPart.volume; placedModel.FixVolume(); spawnedPart.modeledPart = placedModel; } if (spawnedPart.modeledPart == null) { var cube = GameObject.CreatePrimitive(PrimitiveType.Cube).AddComponent <VolumeKeeper>(); cube.name = spawnedPart.name + " cube"; cube.transform.SetParent(spawnedPart.transform); cube.volume = spawnedPart.volume; cube.FixVolume(); spawnedPart.placeholder = cube; } spawnedParts[i] = spawnedPart; } for (int i = 0; i < caste.body_parts.Count; i++) { if (!spawnedParts.ContainsKey(i)) { continue; } var part = caste.body_parts[i]; if (!spawnedParts.ContainsKey(part.parent)) { spawnedParts[i].transform.SetParent(transform); } else { spawnedParts[i].transform.SetParent(spawnedParts[part.parent].transform); } if (part.parent < 0) { rootPart = spawnedParts[i]; } if (spawnedParts[i].flags.stance) { stanceCount++; } } if (rootPart == null) { return; //There's no root part, means there's no body. } rootPart.Arrange(this); bounds = rootPart.GetComponentInChildren <MeshRenderer>().bounds; foreach (var item in rootPart.GetComponentsInChildren <MeshRenderer>()) { bounds.Encapsulate(item.bounds); } rootPart.transform.localPosition = new Vector3(0, -bounds.min.y, 0); }