/// <summary>
 /// Synchronize the mount point state of all common mount points using the observer's settings.
 /// </summary>
 /// <param name="to">The outfit being synchonized to. (Required)</param>
 /// <param name="from">The outfit being syncronzied from. (Required)</param>
 public virtual void Synchronize(Outfit to, Outfit from)
 {
     Outfit.SynchronizeMountPointState(to, from, m_BlockedStatus, m_Context);
 }
Exemplo n.º 2
0
 /// <summary>
 /// Called at the end of an outfit change operation.
 /// </summary>
 /// <remarks>
 /// <para>
 /// There are three situations when a forced release is performed:
 /// </para>
 /// <para>
 /// <ul>
 /// <li><see cref="SetOutfit"/> was used to initiate the forced release.</li>
 /// <li>A bake event was received from the outfit.</li>
 /// <li>
 /// The body detected that the outfit was improperly destroyed using Object.Destroy() directly, instead of
 /// <see cref="Outfit.Destroy"/>.
 /// </li>
 /// </ul>
 /// </para>
 /// </remarks>
 /// <param name="previous">The previous outfit, or null if there is none.</param>
 /// <param name="wasForced">True if a forced release was performed.</param>
 protected virtual void OnOutfitChange(Outfit previous, bool wasForced)
 {
     // Do nothing.
 }
 protected sealed override void OnOutfitChange(Body sender, Outfit previous, bool wasForced)
 {
     Synchronize(sender.Outfit, previous);
 }
Exemplo n.º 4
0
 void IOutfitObserver.OnReleaseAccessory(Outfit sender, Accessory accessory)
 {
     // Do nothing.
 }
Exemplo n.º 5
0
 private void SendOutfitChange(Outfit previous, bool wasForced)
 {
     OnOutfitChange(previous, wasForced);
     Observers.SendOutfitChange(this, previous, wasForced);
 }
Exemplo n.º 6
0
        public sealed override Outfit SetOutfit(Outfit outfit, bool forceRelease)
        {
            // Warning: This method can be called by CheckOutfitLost(), so make sure no code paths trigger that
            // method.

            if (outfit)
            {
                if (outfit == m_Outfit)
                {
                    Debug.LogWarning("Outfit is already set. No action taken.", this);
                    return(null);
                }

                if (outfit && outfit.IsManaged && (outfit.Owner && outfit.Owner != gameObject))
                {
                    Debug.LogErrorFormat(this,
                                         "Outfit is managed by another object.  Can't set outfit.  Outfit: {0}, Owner: {1}",
                                         outfit.name, outfit.Owner.name);
                    return(outfit);
                }
            }

            if (forceRelease && !m_HasOutfit)
            {
                Debug.LogWarning("Force release ignored.  Body has no outfit to release.", this);
                forceRelease = false;
            }

            forceRelease = forceRelease || (m_HasOutfit && !m_Outfit);

            var origOutfit = m_Outfit ? m_Outfit : null;  // Get rid of potential destoryed reference early.

            if (m_Outfit)
            {
                m_Outfit.RemoveObserver(this);  // Keep this early.

                // Note: The state of the outfit it set at the end of the method, just before final release.

                if (m_Outfit.transform.parent == transform)
                {
                    m_Outfit.transform.parent = null;
                }

                // Preserve the outfit's position.
                DefaultMotionRoot.position = m_Outfit.MotionRoot.position;
                DefaultMotionRoot.rotation = m_Outfit.MotionRoot.rotation;

                // Assumption: The body should never be the context of outfit compoenents for an outfit it isn't
                // managing.

                for (int i = 0; i < m_Outfit.BodyPartCount; i++)
                {
                    var item = m_Outfit.GetBodyPart(i);
                    if (item && item.Context == gameObject)
                    {
                        item.Context = null;
                    }
                }

                for (int i = 0; i < m_Outfit.MountPointCount; i++)
                {
                    var item = m_Outfit.GetMountPoint(i);
                    if (item && item.Context == gameObject)
                    {
                        item.Context = null;
                    }
                }
            }

            m_Outfit    = outfit;
            m_HasOutfit = m_Outfit;

            if (m_Outfit)
            {
                m_Outfit.SetState(OutfitStatus.InUse, gameObject);
                m_Outfit.transform.parent = transform;

                // Persist the previous outfit's position.
                m_Outfit.MotionRoot.position = DefaultMotionRoot.position;
                m_Outfit.MotionRoot.rotation = DefaultMotionRoot.rotation;

                m_Outfit.AddObserver(this);  // Keep this late.
            }

            AccessoriesLocal.SetOutfit(outfit, forceRelease);
            SendOutfitChange(origOutfit, forceRelease);

            // Keep this last.  There may be outfit observers that take action when the outfit transitions state.
            // Don't want to trigger them until the outfit is truley free.
            if (origOutfit && origOutfit.Owner == gameObject)
            {
                origOutfit.SetState(OutfitStatus.Unmanaged, null);
            }

            return(origOutfit);
        }
Exemplo n.º 7
0
 void IOutfitObserver.OnMountAccessory(Outfit sender, Accessory accessory)
 {
     // Do nothing.
 }
Exemplo n.º 8
0
 void IBodyObserver.OnOutfitChange(Body sender, Outfit previous, bool wasForced)
 {
     OnOutfitChange(sender, previous, wasForced);
 }
Exemplo n.º 9
0
 protected abstract void OnOutfitChange(Body sender, Outfit previous, bool wasForced);
Exemplo n.º 10
0
 void IOutfitObserver.OnReleaseAccessory(Outfit sender, Accessory accessory)
 {
     // Handled by accesory manager.
 }
Exemplo n.º 11
0
 protected virtual void LocalOutfitChange(Outfit previous)
 {
     // Do nothing.
 }
Exemplo n.º 12
0
 private void SendOutfitChange(Outfit previous)
 {
     LocalOutfitChange(previous);
     Observers.SendOutfitChange(this, previous);
 }
Exemplo n.º 13
0
 /// <summary>
 /// Get the outfit's animator, or null if there is none.
 /// </summary>
 /// <remarks>
 /// <para>
 /// The default behavior is to use <see cref="Outfit.GetAnimator()"/>.
 /// </para>
 /// </remarks>
 /// <param name="outfit">The outfit. (May be null.)</param>
 /// <returns>The outfit's animator, or null if none found.</returns>
 protected virtual Animator GetAnimator(Outfit outfit)
 {
     return(outfit ? outfit.GetAnimator() : null);
 }
Exemplo n.º 14
0
        //////////////////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Destroy the outfit.
        /// </summary>
        /// <remarks>
        /// <para>
        /// Important: Only the owner of the oufit should call this method.
        /// </para>
        /// <para>
        /// This is the best way of destroying an outfit since the outfit will send events to its observers and
        /// other associated components so they can properly respond.
        /// </para>
        /// <para>
        /// The component is responsible for destroying itself as appropriate.  So he client only needs to call this
        /// method then dispose of its references to the component.
        /// </para>
        /// <para><strong>Baking</strong>
        /// </para>
        /// Baking is the process of converting the outfit into a non-outfit state.  What exactly happens during
        /// the bake is implemenation specific.  It may result in the baking of skinned meshes into static meshes.
        /// It may result in conversion to a ragdoll configuration. Etc.
        /// <para>
        /// </remarks>
        /// <param name="typ">The type of destruction.</param>
        /// <param name="referenceOutfit">
        /// The outfit that the the current outfit is derived from.  (E.g. Was instanced from.) Or null if the outfit
        /// has no known source. (Only applies to the 'bake' type.)
        /// </param>
        public abstract void Destroy(DestroyType typ, Outfit referenceOutfit);