using UnityEngine; using System.Collections.Generic; using System; namespace FORGE3D { [Serializable] public class F3DTurretConstructor : MonoBehaviour { public GameObject[] Breeches; //breeches public GameObject[] Barrels; //barrels public GameObject Base; public GameObject Swivel; public GameObject Mount; public GameObject Head; public int turretIndex = 0; public bool needUpdateListOfTemplates = false; //Returns selected turret type public int GetSelectedType() { return turretIndex; } //Changes selected turret index to new value with new turret structure public void ChangeTurretIndex(int index, TurretStructure struc) { turretIndex = index; UpdateFullTurret(struc); } //Checks if name contains in array bool CheckForName(string[] names, string name) { for (int i = 0; i < names.Length; i++) { if (names[i] == name) { return true; } } return false; } //Updates turret structure to another public void UpdateFullTurret(TurretStructure struc) { if (!Application.isPlaying) { UpdateTurret(struc); if (struc.NeedLOD) { InstallLods(); } if (struc.HasTurretScript) { InstallTurretController(); } else { var tmp = GetComponent(); if (tmp != null) { tmp.destroyIt = true; } } } } //Unlinks turret from global constructor public void UnlinkGameObject() { DestroyImmediate(this); } //Install LOD information void InstallLods() { if (this.transform == null || this.transform.childCount == 0) return; Transform baseTurrel = this.transform.GetChild(0); if (baseTurrel != null) { LODGroup oldLod = baseTurrel.gameObject.GetComponent(); if (oldLod == null) { LODGroup lod = baseTurrel.gameObject.AddComponent(); Renderer[] rends = baseTurrel.gameObject.GetComponentsInChildren(); List> renderers = new List>(); for (int i = 0; i < rends.Length; i++) { string curName = rends[i].gameObject.name; if (curName[curName.Length - 1] == ')') { string cuting = "(Clone)"; curName = curName.Replace(cuting, ""); } int lodGroup = -1; if (int.TryParse(curName[curName.Length - 1].ToString(), out lodGroup)) { if (renderers.Count <= lodGroup + 1) { for (int j = 0; j < lodGroup + 1 - renderers.Count; j++) { renderers.Add(new List()); } } renderers[lodGroup].Add(rends[i]); } } LOD[] lods = new LOD[renderers.Count]; for (int i = 0; i < lods.Length; i++) { lods[i].renderers = renderers[i].ToArray(); float x = 10f / lods.Length * (i + 1); if (i < lods.Length * 0.5f) { lods[i].screenRelativeTransitionHeight = (-1.5f * x + 10f) / 10f + 0.02f; } else { lods[i].screenRelativeTransitionHeight = (-0.5f * x + 5f) / 10f + 0.02f; } } lod.SetLODs(lods); lod.RecalculateBounds(); } } } /// /// Installs controller of turret /// void InstallTurretController() { F3DTurret turretController = this.gameObject.GetComponent(); if (turretController == null) { F3DTurret[] turretControllers = this.gameObject.GetComponentsInChildren(); int i; for (i = 0; i < turretControllers.Length; i++) { if (turretControllers[i] != null) { turretControllers[i].destroyIt = true; } } F3DTurret newScript = this.gameObject.AddComponent(); newScript.HeadingLimit.x = -60f; newScript.HeadingLimit.y = 60; newScript.ElevationLimit.x = -60f; newScript.ElevationLimit.y = 60f; newScript.ElevationTrackingSpeed = 30f; newScript.HeadingTrackingSpeed = 30f; string[] namesMount = new string[] { "MOUNT", "Mount" }; newScript.Mount = FindGameObject(namesMount, this.gameObject); string[] namesSwivel = new string[] { "SWIVEL", "Swivel" }; newScript.Swivel = FindGameObject(namesSwivel, this.gameObject); } else if (turretController.Swivel == null || turretController.Mount == null) { string[] namesMount = new string[] { "MOUNT", "Mount" }; turretController.Mount = FindGameObject(namesMount, this.gameObject); string[] namesSwivel = new string[] { "SWIVEL", "Swivel" }; turretController.Swivel = FindGameObject(namesSwivel, this.gameObject); } } /// /// This function used to find child by part of it's name, separated by "_" /// /// Array of available name part /// Parent /// GameObject FindGameObject(string[] names, GameObject parent) { int i; Transform[] childrens = parent.GetComponentsInChildren(); foreach (Transform child in childrens) { if (child != null) { string[] nameParts = child.name.Split('_'); for (i = 0; i < nameParts.Length; i++) { if (CheckForName(names, nameParts[i])) { return child.gameObject; } } } } return null; } /// /// This function used to update turret's structure /// /// public void UpdateTurret(TurretStructure curStructure) { if (curStructure == null) return; UpdateBase(curStructure.Base); UpdateSwivel(curStructure.Swivel, curStructure.SwivelPrefix); UpdateHead(curStructure.Head, curStructure.HeadPrefix); UpdateMount(curStructure.Mount, curStructure.MountPrefix); UpdateBreeches(curStructure.WeaponBreeches, curStructure.WeaponSlotsNames, curStructure.WeaponBarrels, curStructure.WeaponBarrelSockets); } /// /// Function updates breeches /// /// List of breech prefabs /// List of breech names void UpdateBreeches(List breeches, List socketNames, List barrels, List barrelSocketNames) { int i = 0; if (Breeches != null) { for (i = 0; i < Breeches.Length; i++) { DestroyImmediate(Breeches[i]); } } List generatedBreeches = new List(); List tempBreeches = breeches; List tempSockets = socketNames; List generatedBarrels = new List(); if (Base != null) { Transform[] childrens = Base.GetComponentsInChildren(); foreach (Transform child in childrens) { for (i = 0; i < tempSockets.Count; i++) { if (child.name == tempSockets[i]) { if (tempBreeches[i] != null) { GameObject newGO = Instantiate(tempBreeches[i], Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = child; newGO.transform.position = child.position; newGO.transform.rotation = child.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); generatedBarrels.Add(UpdateBarrel(barrels[i], newGO, barrelSocketNames[i])); generatedBreeches.Add(newGO); } else { generatedBarrels.Add(UpdateBarrel(barrels[i], child.gameObject, barrelSocketNames[i])); generatedBreeches.Add(null); } } } } Breeches = generatedBreeches.ToArray(); } } // Installs new barrel to parent GameObject UpdateBarrel(GameObject barrelGO, GameObject parentGO, string socket) { if (parentGO == null || barrelGO == null) return null; Transform[] transforms = parentGO.GetComponentsInChildren(); foreach (Transform child in transforms) { if (child.name == socket) { GameObject newGO = Instantiate(barrelGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = child; newGO.transform.position = child.position; newGO.transform.rotation = child.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); return newGO; } } GameObject newGOParented = Instantiate(barrelGO, Vector3.zero, Quaternion.identity) as GameObject; newGOParented.transform.parent = parentGO.transform; newGOParented.transform.position = parentGO.transform.position; newGOParented.transform.rotation = parentGO.transform.rotation; newGOParented.transform.localScale = new Vector3(1f, 1f, 1f); return newGOParented; } /// /// This function deletes all current childrens and creates new HEAD /// /// Head prefab /// Head socket name void UpdateHead(GameObject headGO, string prefix) { if (Head != null) { if (Head.transform.childCount > 0) { Transform[] childs = Head.GetComponentsInChildren(); foreach (Transform child in childs) { if (child != null && child != Head.transform) { if (child.gameObject != this.gameObject) { DestroyImmediate(child.gameObject); } } } } DestroyImmediate(Head); } if (headGO != null) { if (Base != null) { Transform[] transforms = Base.GetComponentsInChildren(); foreach (Transform child in transforms) { if (child.name == prefix) { GameObject newGO = Instantiate(headGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = child; newGO.transform.position = child.position; newGO.transform.rotation = child.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Head = newGO; break; } } } else { GameObject newGO = Instantiate(headGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = this.gameObject.transform; newGO.transform.position = this.gameObject.transform.position; newGO.transform.rotation = this.gameObject.transform.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Head = newGO; } } } /// /// This function deletes all current childrens and creates new MOUNT /// /// Mount prefab /// Mount socket name void UpdateMount(GameObject mountGO, string prefix) { if (Mount != null) { if (Mount.transform.childCount > 0) { Transform[] childs = Mount.GetComponentsInChildren(); foreach (Transform child in childs) { if (child != null && child != Mount.transform) { if (child.gameObject != this.gameObject) { DestroyImmediate(child.gameObject); } } } } DestroyImmediate(Mount); } if (mountGO != null) { if (Base != null) { Transform[] transforms = Base.GetComponentsInChildren(); foreach (Transform child in transforms) { if (child.name == prefix) { GameObject newGO = Instantiate(mountGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = child; newGO.transform.position = child.position; newGO.transform.rotation = child.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Mount = newGO; if (Base == null) { Base = Mount; Swivel = Mount; } break; } } } else { GameObject newGO = Instantiate(mountGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = this.gameObject.transform; newGO.transform.position = this.gameObject.transform.position; newGO.transform.rotation = this.gameObject.transform.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Mount = newGO; Base = Mount; Swivel = Mount; } } } /// /// This function deletes all current childrens and creates new SWIVEL /// /// Swivel prefab /// Swivel socket name void UpdateSwivel(GameObject swivelGO, string prefix) { if (Swivel != null) { if (Swivel.transform.childCount > 0) { Transform[] childs = Swivel.GetComponentsInChildren(); foreach (Transform child in childs) { if (child != null && child != Swivel.transform) { if (child.gameObject != this.gameObject) { DestroyImmediate(child.gameObject); } } } } DestroyImmediate(Swivel); } if (swivelGO != null) { if (Base != null) { Transform[] transforms = Base.GetComponentsInChildren(); foreach (Transform child in transforms) { if (child.name == prefix) { GameObject newGO = Instantiate(swivelGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = child; newGO.transform.position = child.position; newGO.transform.rotation = child.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Swivel = newGO; if (Base == null) { Base = Swivel; } break; } } } else { GameObject newGO = Instantiate(swivelGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = this.gameObject.transform; newGO.transform.position = this.gameObject.transform.position; newGO.transform.rotation = this.gameObject.transform.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Swivel = newGO; Base = Swivel; } } } /// /// This function deletes all current childrens and creates new BASE /// /// Base prefab void UpdateBase(GameObject baseGO) { if (this.gameObject.transform.childCount > 0) { Transform[] childs = this.GetComponentsInChildren(); foreach (Transform child in childs) { if (child != null) { if (child.gameObject != this.gameObject) { DestroyImmediate(child.gameObject); } } } } if (baseGO != null) { GameObject newGO = Instantiate(baseGO, Vector3.zero, Quaternion.identity) as GameObject; newGO.transform.parent = this.gameObject.transform; newGO.transform.position = this.gameObject.transform.position; newGO.transform.rotation = this.gameObject.transform.rotation; newGO.transform.localScale = new Vector3(1f, 1f, 1f); Base = newGO; } else { Base = null; } } } }