コード例 #1
0
        /// <summary>
        /// Attempts to calculate and update the transform.
        /// </summary>
        /// <param name="force">
        /// <c>true</c> to force an update even if the same parent option is
        /// selected. The default is <c>false</c>.
        /// </param>
        public virtual void UpdateTransform(bool force = false)
        {
            // If there are no parent options, nothing to do
            if (parentOptions.Count == 0)
            {
                State = AlignmentState.Inhibited;
                Debug.LogWarning($"{nameof(MultiParentAlignment)}: No parent options to select from.");
                return;
            }

            // Validate the parent options
            ValidateParentOptions();

            // Use virtual method to select the best parent option
            ParentAlignmentOptions parentOption = SelectParent();

            // If no option could be found, fail
            if (parentOption == null)
            {
                State = AlignmentState.Inhibited;
                Debug.LogWarning($"{nameof(MultiParentAlignment)}: No parent could be found that meets the minimum criteria.");
                return;
            }
            else
            {
                // Actually apply the parent
                ApplyParent(parentOption, force: force);

                // Resolved
                State = AlignmentState.Tracking;
            }
        }
コード例 #2
0
        /// <summary>
        /// Applies the specified parent options to this object.
        /// </summary>
        /// <param name="parentOption">
        /// The parent options to apply.
        /// </param>
        /// <param name="force">
        /// <c>true</c> to force an update even if reusing the same option.
        /// The default is <c>false</c>.
        /// </param>
        /// <remarks>
        /// The default implementation of this method parents the transform
        /// and applies position, rotation and scale modifications.
        /// </remarks>
        protected virtual void ApplyParent(ParentAlignmentOptions parentOption, bool force = false)
        {
            // Validate
            if (parentOption == null)
            {
                throw new ArgumentNullException(nameof(parentOption));
            }
            if (parentOption.Frame == null)
            {
                throw new InvalidOperationException($"{nameof(parentOption.Frame)} cannot be null.");
            }

            // If already parented to this object, no additional work needed
            if ((!force) && (currentParent == parentOption))
            {
                return;
            }

            // Make our transform a child of the frame
            this.transform.SetParent(parentOption.Frame.transform, worldPositionStays: false);

            // Apply transform modifications
            this.transform.localPosition = parentOption.Position;
            this.transform.localRotation = Quaternion.Euler(parentOption.Rotation);
            this.transform.localScale    = parentOption.Scale;

            // Notify of parent change
            CurrentParent = parentOption;

            // Done!
        }
コード例 #3
0
        /// <summary>
        /// Attempts to select the best parent option based on current settings.
        /// </summary>
        /// <returns>
        /// The <see cref="ParentAlignmentOptions"/> that represent the best parent,
        /// if found; otherwise <see langword = "null" />.
        /// </returns>
        /// <remarks>
        /// The default implementation examines all options where
        /// <see cref="ParentAlignmentOptions.IsValidTarget">IsValidTarget</see>
        /// returns <c>true</c> and selects the top option sorted by
        /// <see cref="ParentAlignmentOptions.SortOrder(Transform)">SortOrder</see>.
        /// </remarks>
        protected virtual ParentAlignmentOptions SelectParent()
        {
            // Attempt to get the reference transform
            Transform reference = GetReferenceTransform();

            // If no transform, can't continue
            if (reference == null)
            {
                return(null);
            }

            // Placeholder
            ParentAlignmentOptions parentOption = null;

            // If only one parent option, always use that
            if (parentOptions.Count == 1)
            {
                // Use only parent option, if valid
                parentOption = (parentOptions[0].IsValidTarget() ? parentOptions[0] : null);
            }
            else
            {
                // Find the best valid parent, sorted by logic in the ParentAlignmentOption itself
                parentOption = (from o in ParentOptions
                                where o.IsValidTarget()
                                orderby o.SortOrder(reference)
                                select o
                                ).FirstOrDefault();
            }

            // Done searching
            return(parentOption);
        }