/// <summary> /// Clones the PrefabLink, but targets a different GameObject. /// </summary> /// <param name="newObj">The GameObject which the clone is connected to.</param> /// <returns>A cloned version of this PrefabLink</returns> public PrefabLink Clone(GameObject newObj) { PrefabLink clone = this.Clone(); clone.obj = newObj; return(clone); }
/// <summary> /// Relocates the internal change list from this PrefabLink to a different, hierarchially lower PrefabLink. /// </summary> /// <param name="other"> /// The PrefabLink to which to relocate changes. It needs to be hierarchially lower than /// this one for the relocation to succeed. /// </param> /// <remarks> /// <para> /// In general, each PrefabLink is responsible for all hierarchially lower GameObjects. If one of them has /// a PrefabLink on its own, then the higher PrefabLinks responsibility ends there. /// </para> /// <para> /// Change relocation is done when linking an existing GameObject to a Prefab although it is already affected by a /// hierarchially higher PrefabLink. In order to prevent both PrefabLinks to interfere with each other, /// all higher PrefabLink change list entries referring to that GameObject are relocated to the new, lower /// PrefabLink that is specifically targetting it. /// </para> /// <para> /// This way, the above responsibility guideline remains applicable. /// </para> /// </remarks> public void RelocateChanges(PrefabLink other) { if (this.changes == null || this.changes.Count == 0) { return; } if (!other.obj.IsChildOf(this.obj)) { return; } List <int> childPath = this.obj.IndexPathOfChild(other.obj); for (int i = this.changes.Count - 1; i >= 0; i--) { if (this.changes[i].childIndex.Take(childPath.Count).SequenceEqual(childPath)) { object target; GameObject targetObj = this.obj.ChildAtIndexPath(this.changes[i].childIndex); if (this.changes[i].componentType != null) { target = targetObj.GetComponent(this.changes[i].componentType); } else { target = targetObj; } other.PushChange(target, this.changes[i].prop, this.changes[i].val); this.changes.RemoveAt(i); } } }
/// <summary> /// Clones the PrefabLink, but targets a different GameObject and Prefab. /// </summary> /// <param name="newObj">The GameObject which the clone is connected to.</param> /// <param name="newPrefab">The Prefab which the clone will connect its GameObject to.</param> /// <returns>A cloned version of this PrefabLink</returns> public PrefabLink Clone(GameObject newObj, ContentRef <Prefab> newPrefab) { PrefabLink clone = this.Clone(); clone.obj = newObj; clone.prefab = newPrefab; return(clone); }
/// <summary> /// A <see cref="Duality.Serialization.Formatter.FieldBlockers">FieldBlocker</see> to prevent /// fields of <see cref="Duality.Resources.PrefabLink">PrefabLink-ed</see> objects from being serialized unnecessarily. /// </summary> /// <param name="field"></param> /// <param name="obj"></param> /// <returns></returns> public static bool PrefabLinkedFieldBlocker(FieldInfo field, object obj) { Component cmp = obj as Component; if (cmp == null || cmp.GameObj == null) { return(false); } Resources.PrefabLink link = cmp.GameObj.AffectedByPrefabLink; if (link == null || !link.AffectsObject(cmp)) { return(false); } return(field.DeclaringType != typeof(Component)); }
void ICloneExplicit.CopyDataTo(object targetObj, CloneProvider provider) { PrefabLink castObj = targetObj as PrefabLink; castObj.prefab = this.prefab; castObj.obj = this.obj; castObj.changes = null; if (this.changes != null) { castObj.changes = new List <VarMod>(this.changes.Count); for (int i = 0; i < this.changes.Count; i++) { VarMod newVarMod = this.changes[i]; newVarMod.childIndex = new List <int>(newVarMod.childIndex); castObj.changes.Add(newVarMod); } } }
/// <summary> /// Applies all <see cref="Duality.Resources.PrefabLink">PrefabLinks</see> contained withing this /// Scenes <see cref="GameObject">GameObjects</see>. /// </summary> public void ApplyPrefabLinks() { PrefabLink.ApplyAllLinks(this.objectManager.AllObjects); }
/// <summary> /// Relocates the internal change list from this PrefabLink to a different, hierarchially lower PrefabLink. /// </summary> /// <param name="other"> /// The PrefabLink to which to relocate changes. It needs to be hierarchially lower than /// this one for the relocation to succeed. /// </param> /// <remarks> /// <para> /// In general, each PrefabLink is responsible for all hierarchially lower GameObjects. If one of them has /// a PrefabLink on its own, then the higher PrefabLinks responsibility ends there. /// </para> /// <para> /// Change relocation is done when linking an existing GameObject to a Prefab although it is already affected by a /// hierarchially higher PrefabLink. In order to prevent both PrefabLinks to interfere with each other, /// all higher PrefabLink change list entries referring to that GameObject are relocated to the new, lower /// PrefabLink that is specifically targetting it. /// </para> /// <para> /// This way, the above responsibility guideline remains applicable. /// </para> /// </remarks> public void RelocateChanges(PrefabLink other) { if (this.changes == null || this.changes.Count == 0) return; if (!other.obj.IsChildOf(this.obj)) return; List<int> childPath = this.obj.IndexPathOfChild(other.obj); for (int i = this.changes.Count - 1; i >= 0; i--) { if (this.changes[i].childIndex.Take(childPath.Count).SequenceEqual(childPath)) { object target; GameObject targetObj = this.obj.ChildAtIndexPath(this.changes[i].childIndex); if (this.changes[i].componentType != null) target = targetObj.GetComponent(this.changes[i].componentType); else target = targetObj; other.PushChange(target, this.changes[i].prop, this.changes[i].val); this.changes.RemoveAt(i); } } }