/// <summary> /// connects a child to an adaptor. /// </summary> /// <param name="adaptor"></param> public void ConnectChildToAdaptor(Adaptor adaptor, WeaponPart child) { //checks if (AdaptorConnections == null) //sometimes this thing isn't initialized properly, don't know why { AdaptorConnections = new Dictionary <WeaponPart, Adaptor>(); } if (AdaptorConnections.ContainsValue(adaptor))//adaptor already connected { return; } if (adaptor.WeaponTypeOfAdaptor != child.PartType) //if trying to connect a wrong part { return; } //alignment child.transform.parent = adaptor.ChildPartTransform; child.transform.localPosition = Vector3.zero; child.transform.localRotation = Quaternion.Euler(0, 0, 0); //create connection AdaptorConnections.Add(child, adaptor); //make connected side visible again MaterialHider hider = new MaterialHider(); hider.DisplayHierarchy(adaptor.ChildPartTransform.gameObject, this.PartID); adaptor.isUnconnected = false; }
/// <summary> /// Inits this creator instance, always called after user clicks on menuitem /// </summary> private void Init() { partRoot = new GameObject(); partRoot.name = "WEAPONPART"; partRoot.transform.position = Vector3.zero; partRoot.transform.rotation = Quaternion.Euler(0, 0, 0); partRoot.transform.parent = this.transform; partMeshesRoot = new GameObject(); partMeshesRoot.name = "Mesh"; partMeshesRoot.transform.position = Vector3.zero; partMeshesRoot.transform.rotation = Quaternion.Euler(0, 0, 0); partMeshesRoot.transform.parent = partRoot.transform; weaponPart = partRoot.AddComponent <WeaponPart>(); currentState = WeaponPartCreationState.SetupPartInfo; Selection.activeGameObject = this.gameObject; AdaptorMeshes.Add(Resources.Load <Mesh>("AdaptorPreviewMeshes/BarrelAdaptorPreviewMesh")); AdaptorMeshes.Add(Resources.Load <Mesh>("AdaptorPreviewMeshes/LoadingMechanismAdaptorPreviewMesh")); AdaptorMeshes.Add(Resources.Load <Mesh>("AdaptorPreviewMeshes/ShootingMechanismAdaptorPreviewMesh")); AdaptorMeshes.Add(Resources.Load <Mesh>("AdaptorPreviewMeshes/BarrelAdaptorPreviewMesh")); AdaptorMeshes.Add(Resources.Load <Mesh>("AdaptorPreviewMeshes/BarrelAdaptorPreviewMesh")); AdaptorPrefabs.Add(null); AdaptorPrefabs.Add((GameObject)AssetDatabase.LoadAssetAtPath("Assets/Weapons/AdaptorLoadingMechanism/AdaptorLoadingMechanism.prefab", typeof(GameObject))); AdaptorPrefabs.Add((GameObject)AssetDatabase.LoadAssetAtPath("Assets/Weapons/AdaptorShootingMechanism/AdaptorShootingMechanism.prefab", typeof(GameObject))); AdaptorPrefabs.Add(null); AdaptorPrefabs.Add((GameObject)AssetDatabase.LoadAssetAtPath("Assets/Weapons/BarrelAdaptor/BarrelAdaptor.prefab", typeof(GameObject))); }
/// <summary> /// quick setup for tests /// </summary> /// <param name="name"></param> /// <param name="type"></param> public void TestSetup(string name, WeaponPartType type, WeaponPart _parent) { this.PartName = name; this.PartType = type; ChangeParent(_parent); Children = new List <WeaponPart>(); }
/// <summary> /// Removes a weapon part completely, including the sub-hierachy /// </summary> /// <param name="partToRemove">the part to Remove</param> public void RemoveWeaponPart(WeaponPart partToRemove) { if (partToRemove.Parent != null) { partToRemove.Parent.RemoveChild(partToRemove); } Destroy(partToRemove.gameObject); }
/// <summary> /// configures this to remove a part /// </summary> /// <param name="partToRemove"></param> public WeaponStructureAction(WeaponPart partToRemove, WeaponStructure structure) { PartToRemove = partToRemove; Structure = structure; TypeOfAction = WeaponStructureActionType.RemovePart; Finalized = false; }
/// <summary> /// configures this to add a part /// </summary> /// <param name="adaptor"></param> /// <param name="partToAdd"></param> public WeaponStructureAction(Adaptor adaptor, WeaponPart partToAdd, WeaponStructure structure) { m_Adaptor = adaptor; PartToAdd = partToAdd; Structure = structure; TypeOfAction = WeaponStructureActionType.AddPart; Finalized = false; }
/// <summary> /// configures this to replace a part /// </summary> /// <param name="partToReplace"></param> /// <param name="replacementPart"></param> public WeaponStructureAction(WeaponPart partToReplace, WeaponPart replacementPart, WeaponStructure structure) { PartToReplace = partToReplace; ReplacementPart = replacementPart; Structure = structure; TypeOfAction = WeaponStructureActionType.ReplacePart; Finalized = false; }
/// <summary> /// Adds a weapon part to the specified adaptor /// </summary> /// <param name="adaptor">the adaptor to which to add the part</param> /// <param name="partToAdd">the part to add</param> public void AddWeaponPart(Adaptor adaptor, WeaponPart partToAdd) { WeaponPart adaptorPart = FindWeaponPartRecursive(x => x.Adaptors.Contains(adaptor)); if (adaptor == null) { return; } adaptorPart.AddChild(partToAdd); adaptorPart.ConnectChildToAdaptor(adaptor, partToAdd); }
public override void OnInspectorGUI() { WeaponPart part = (WeaponPart)target; if (part.Children == null) { part.Children = new List <WeaponPart>(); } if (part.Adaptors == null) { part.Adaptors = new List <Adaptor>(); } part.PartType = (WeaponPartType)EditorGUILayout.EnumPopup("Part Type:", part.PartType); AdaptorList.DisplayList <Adaptor>(ref part.Adaptors, "Adaptor", "Adaptors"); GUI.enabled = false; EditorGUILayout.LabelField("Statistics:"); EditorGUI.indentLevel++; EditorGUILayout.TextField("Part Name:", part.PartName); EditorGUILayout.TextField("Part ID:", part.PartID); EditorGUILayout.ObjectField("Parent Part:", part.Parent, typeof(WeaponPart), true); EditorGUILayout.Space(); EditorGUILayout.LabelField("Connected Children:"); EditorGUI.indentLevel++; foreach (WeaponPart child in part.Children) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Name: " + child.PartName + "ID: " + child.PartID + "Connecting Adaptor: "); Adaptor adaptor; part.AdaptorConnections.TryGetValue(child, out adaptor); EditorGUILayout.ObjectField(adaptor, typeof(Adaptor), true); EditorGUILayout.EndHorizontal(); } GUI.enabled = true; EditorUtility.SetDirty(part); }
/// <summary> /// adds a child to this part /// </summary> /// <param name="child">the child to add</param> public void AddChild(WeaponPart child) { //checks if (Children.Contains(child))//if part is already a child { return; } if (Children.Count == Adaptors.Count) //we can't have more children than adaptors { return; } //add as child Children.Add(child); child.Parent = this; }
/// <summary> /// changes this part's Parent and automatically assigns itself to the Parent as a child /// </summary> /// <param name="newParent">the new Parent</param> public void ChangeParent(WeaponPart newParent) { //checks if (newParent == null)//passed null, TODO: what if we want to make it a toplevel part? might need to check this { return; } if (Parent != null) //if we're not toplevel part, remove from previous parent { Parent.RemoveChild(this); } //set as new parent and register as it's child Parent = newParent; Parent.AddChild(this); }
/// <summary> /// removes a child from this part /// </summary> /// <param name="child">the child to remove </param> public void RemoveChild(WeaponPart child) { //checks if (!Children.Contains(child))//if part is no child { return; } //remove child Children.Remove(child); Adaptor a = AdaptorConnections[child]; AdaptorConnections.Remove(child); if (a != null) //better nullcheck it { //hide adaptor again MaterialHider hider = new MaterialHider(); hider.HideHierarchy(a.ChildPartTransform.gameObject, this.PartID); a.isUnconnected = true; } }
/// <summary> /// finds all adaptors that are not yet connected to a child weaponpart /// </summary> /// <param name="startingPart">the part to start from, leave empty to start from the beginning</param> /// <returns>List of all unconnected adaptors</returns> public List <Adaptor> FindUnconnectedAdaptorsRecursively(WeaponPart startingPart = null) { List <Adaptor> result = new List <Adaptor>(); if (trigger == null) { return(result); } if (startingPart == null) { startingPart = trigger; } if (startingPart.AdaptorConnections == null) { startingPart.AdaptorConnections = new Dictionary <WeaponPart, Adaptor>(); } if (startingPart.AdaptorConnections.Count < startingPart.Adaptors.Count) { foreach (Adaptor adaptor in startingPart.Adaptors) { if (!startingPart.AdaptorConnections.ContainsValue(adaptor)) { result.Add(adaptor); } } } foreach (WeaponPart child in startingPart.Children) { result.AddRange(FindUnconnectedAdaptorsRecursively(child)); } return(result); }
public WeaponPart(WeaponPart _parent, List <WeaponPart> _children, string _partID, Dictionary <WeaponPart, Adaptor> _adaptorConnections = null) { //attaching to other parts has become quite a bit more challenging than this implementation, so WeaponStructureAction should be used instead, //which has the added benefit of controlling animations, too. I'll leave the code commented out if it's needed again - or should be modified throw new System.NotImplementedException("Please use the WeaponStructureAction class to perform automated connections to other parts"); // ChangeParent(_parent); // Children = _children; // PartID = _partID; // // if (_adaptorConnections != null) // AdaptorConnections = _adaptorConnections; // else // { // AdaptorConnections = new Dictionary<WeaponPart, Adaptor>(); // int i = 0; // foreach (WeaponPart child in Children) // { // ConnectChildToAdaptor(Adaptors[i], child); // AdaptorConnections.Add(child, Adaptors[i]); // i++; // } // } }
/// <summary> /// constructs this structure /// </summary> /// <param name="_trigger">the trigger, aka the first part of the weaponstructure tree</param> public WeaponStructure(WeaponPart _trigger) { trigger = _trigger; }
/// <summary> /// recursively searches the part-tree and returns the first match, or null if no match is found /// </summary> /// <param name="match">the predicate that describes the searched part</param> /// <param name="startingPart">where to start. leave at null to start with the first part in the tree, otherwise specifiy a part in the tree to check /// it and its children for a match</param> /// <returns>the weapon part that has been found or null if none has been found</returns> public WeaponPart FindWeaponPartRecursive(System.Predicate <WeaponPart> match, WeaponPart startingPart = null) { if (startingPart == null) { startingPart = trigger; } if (match(startingPart)) { return(startingPart); } else { foreach (WeaponPart child in startingPart.Children) { var result = FindWeaponPartRecursive(match, child); if (result != null) { return(result); } } } return(null); }
/// <summary> /// finds all parts of the specified type /// </summary> /// <param name="type">the type of parts to find</param> /// <param name="startingPart">what part to start searching at, leave empty for starting at the first part</param> /// <returns>list of weapon parts of type or empy list if none are found</returns> public List <WeaponPart> FindAllWeaponPartsOfTypeRecursively(WeaponPartType type, WeaponPart startingPart = null) { List <WeaponPart> result = new List <WeaponPart>(); if (trigger == null) { return(result); } if (startingPart == null) { startingPart = trigger; } if (startingPart.PartType == type) { result.Add(startingPart); } foreach (WeaponPart child in startingPart.Children) { result.AddRange(FindAllWeaponPartsOfTypeRecursively(type, child)); } return(result); }
/// <summary> /// Replaces a weapon part by another of same type, trying to keep the sub-hierachy intact /// </summary> /// <param name="partToReplace">the part that will be replaced</param> /// <param name="replacementPart">the part that it will be replaced by</param> public void ReplaceWeaponPart(WeaponPart partToReplace, WeaponPart replacementPart) { if (trigger == null) { return; } //save children var children = new List <WeaponPart>(partToReplace.Children); if (partToReplace != trigger) { //save adaptor that part is connected to Adaptor connectingAdaptor = partToReplace.Parent.AdaptorConnections[partToReplace]; //save parent part WeaponPart parent = partToReplace.Parent; //all children transform parent to null partToReplace.DetachAllChildren(); //remove from parent if (partToReplace.Parent != null) { parent.RemoveChild(partToReplace); } //add new part into hierachy parent.AddChild(replacementPart); parent.ConnectChildToAdaptor(connectingAdaptor, replacementPart); } else //is trigger aka toplevel weaponpart { replacementPart.transform.parent = partToReplace.transform.parent; //all children transform parent to null partToReplace.DetachAllChildren(); partToReplace.transform.parent = null; trigger = replacementPart; } List <WeaponPart> excessParts = new List <WeaponPart>(); List <WeaponPart> childrenCopy = new List <WeaponPart>(children); int i = 0; //reconnect children foreach (Adaptor adaptor in replacementPart.Adaptors) { var child = childrenCopy.Find(x => x.PartType == adaptor.WeaponTypeOfAdaptor); if (child == null) { continue; } replacementPart.AddChild(child); replacementPart.ConnectChildToAdaptor(adaptor, child); childrenCopy.Remove(child); i++; } excessParts = childrenCopy; //destroy all parts that could not be reconnected foreach (WeaponPart excess in excessParts) { Destroy(excess.gameObject); } //destroy the actual part Destroy(partToReplace.gameObject); }
/// <summary> /// initializes the part with just the Parent /// assigns itself to the Parent as a child /// </summary> /// <param name="_parent">the Parent object of this part</param> public WeaponPart(WeaponPart _parent, string _partID) { ChangeParent(_parent); Children = new List <WeaponPart>(); PartID = _partID; }