/// <summary>
    /// Called once in every frame.
    /// </summary>
    void Update()
    {
        // Enable/disable the button according to current selected asset's modify flags.
        if (m_lastSelectedAsset != AvatarCreatorContext.selectedAssetType)
        {
            CBaseAsset checkAsset = AvatarCreatorContext.GetLoadedAssetsByType(AvatarCreatorContext.selectedAssetType)[0];

            if ((checkAsset.GetModifyFlags() & m_buttonType) != 0)
            {
                gameObject.GetComponent <Button>().interactable = true;
            }
            else
            {
                gameObject.GetComponent <Button>().interactable = false;
            }

            m_lastSelectedAsset = AvatarCreatorContext.selectedAssetType;
        }
    }
    /// <summary>
    /// Deserializes given data and loads it to FaceObject.
    /// </summary>
    /// <param name="data">Serialized XML data.</param>
    public void Unserialize(string data)
    {
        Debug.Log("FaceObjectController:Unserialize()\n" + data);

        // Initialization
        AssetType  assetType  = AssetType.None;
        string     objectName = "";
        string     assetName  = "";
        Vector3    position   = new Vector3();
        Quaternion rotation   = new Quaternion();
        Vector3    scale      = new Vector3();
        Color      color      = new Color();

        XmlDocument doc = new XmlDocument();

        doc.LoadXml(data);

        XmlNode root = doc.DocumentElement.SelectSingleNode("/SaveFile/FaceObject");

        foreach (XmlNode node in root.ChildNodes)
        {
            foreach (XmlAttribute attr in node.Attributes)
            {
                switch (attr.Name)
                {
                case "name":
                {
                    objectName = attr.Value;
                    break;
                }

                case "asset":
                {
                    assetName = attr.Value;
                    break;
                }

                case "type":
                {
                    assetType = (AssetType)System.Enum.Parse(typeof(AssetType), attr.Value);
                    break;
                }

                case "posx":
                {
                    position.x = float.Parse(attr.Value);
                    break;
                }

                case "posy":
                {
                    position.y = float.Parse(attr.Value);
                    break;
                }

                case "posz":
                {
                    position.z = float.Parse(attr.Value);
                    break;
                }

                case "rotx":
                {
                    rotation.x = float.Parse(attr.Value);
                    break;
                }

                case "roty":
                {
                    rotation.y = float.Parse(attr.Value);
                    break;
                }

                case "rotz":
                {
                    rotation.z = float.Parse(attr.Value);
                    break;
                }

                case "rotw":
                {
                    rotation.w = float.Parse(attr.Value);
                    break;
                }

                case "scalex":
                {
                    scale.x = float.Parse(attr.Value);
                    break;
                }

                case "scaley":
                {
                    scale.y = float.Parse(attr.Value);
                    break;
                }

                case "scalez":
                {
                    scale.z = float.Parse(attr.Value);
                    break;
                }

                case "color":
                {
                    ColorUtility.TryParseHtmlString("#" + attr.Value, out color);
                    break;
                }
                }
            }

            Debug.Log(objectName + " " + assetName);

            if (assetName == "")
            {
                continue;
            }

            CBaseAsset asset = AvatarCreatorContext.FindAssetByName(assetName);

            if (asset == null)
            {
                asset = new CBaseAsset(AssetGender.NoGender, assetType, 0, "");
            }

            GameObject gObject = GameObject.Find(objectName);
            if (gObject)
            {
                gObject.transform.position   = position;
                gObject.transform.rotation   = rotation;
                gObject.transform.localScale = scale;

                if (gObject.GetComponent <Image>() != null)
                {
                    gObject.GetComponent <Image>().color = color;
                }
            }

            SetFaceObjectPart(asset, false);
        }
    }
    /// <summary>
    /// Loads an asset object to the transform for displaying it on the face.
    /// </summary>
    /// <param name="asset">An asset object.</param>
    /// <param name="isUserAction">True: Loaded by user. False: Loaded by codebase.</param>
    public void SetFaceObjectPart(CBaseAsset asset, bool isUserAction = true)
    {
        // If asset parameter is null, we will manupilate the last selected asset.
        if (asset == null)
        {
            asset = m_currentAsset;
        }

        // If asset is invalid, return.
        if (asset.GetAssetType() == AssetType.None)
        {
            return;
        }

        // Get transforms of the specified asset's type from FaceObject.
        Transform currentTransform = m_transforms[asset.GetAssetType()];

        // If current asset type is Hair, that means currently used asset is a Hair asset.
        if (asset.GetAssetType() == AssetType.Hair)
        {
            // Get transforms of Hair from FaceObject.
            Transform hairFront = currentTransform;
            Transform hairBack  = currentTransform.parent.Find("fo_hair_back");

            // If current asset has Front part, assign it with the selected realism level.
            if (asset.GetSprites().ContainsKey(SpritePart.Front))
            {
                hairFront.GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Front][(int)AvatarCreatorContext.currentRealismLevel];
            }

            // If current asset has Back part, assign it with the selected realism level.
            if (asset.GetSprites().ContainsKey(SpritePart.Back))
            {
                hairBack.GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][(int)AvatarCreatorContext.currentRealismLevel];
                ChangeAssetColor(hairFront.GetComponent <Image>().color);
            }
            else
            {
                hairBack.GetComponent <Image>().sprite = null;
            }

            // Remove ghutra. (We need to display the hair, so ghutra is not needed)
            if (asset.GetSprites()[SpritePart.Front][(int)AvatarCreatorContext.currentRealismLevel] == null)
            {
                m_transforms[AssetType.Ghutra].GetComponent <Image>().sprite = null;
                m_transforms[AssetType.Ghutra].parent.Find("fo_ghutra_back").GetComponent <Image>().sprite = null;
            }
        }
        // If current asset type is Eyebrows or Ears
        else if (asset.GetAssetType() == AssetType.Eyebrows ||
                 asset.GetAssetType() == AssetType.Ears)
        {
            // Assign selected asset.
            for (int i = 0; i < currentTransform.childCount; ++i)
            {
                currentTransform.GetChild(i).GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
            }
        }
        // If current asset type is Eyes.
        else if (asset.GetAssetType() == AssetType.Eyes)
        {
            // Get transforms of left and right eyes.
            Transform eye_left  = currentTransform.Find("fo_eye_left");
            Transform eye_right = currentTransform.Find("fo_eye_right");

            // Assign assets for left and right eye.
            eye_left.Find("fo_eye_left_L0").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Reserved][(int)AvatarCreatorContext.currentRealismLevel];
            eye_left.Find("fo_eye_left_L1").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][(int)AvatarCreatorContext.currentRealismLevel];
            eye_left.Find("fo_eye_left_L2").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
            eye_left.Find("fo_eye_left_L3").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Front][(int)AvatarCreatorContext.currentRealismLevel];

            eye_right.Find("fo_eye_right_L0").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Reserved][(int)AvatarCreatorContext.currentRealismLevel];
            eye_right.Find("fo_eye_right_L1").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][(int)AvatarCreatorContext.currentRealismLevel];
            eye_right.Find("fo_eye_right_L2").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
            eye_right.Find("fo_eye_right_L3").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Front][(int)AvatarCreatorContext.currentRealismLevel];
        }
        // If current asset type is Mouth
        else if (asset.GetAssetType() == AssetType.Mouth)
        {
            // Assign assets for mouth.
            currentTransform.Find("fo_mouth_L1").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][(int)AvatarCreatorContext.currentRealismLevel];
            currentTransform.Find("fo_mouth_L2").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
        }
        // If current asset type is Body
        else if (asset.GetAssetType() == AssetType.Body)
        {
            // Assign assets for body.
            currentTransform.Find("fo_body_L1").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][(int)AvatarCreatorContext.currentRealismLevel];
            currentTransform.Find("fo_body_L2").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];

            m_transforms[AssetType.Body].gameObject.SetActive(true);
            m_transforms[AssetType.SpecialBody].gameObject.SetActive(false);
            gameObject.transform.Find("fo_mask").gameObject.GetComponent <Mask>().enabled = false;
        }
        else if (asset.GetAssetType() == AssetType.SpecialBody)
        {
            if (asset.GetSprites().ContainsKey(SpritePart.Back))
            {
                currentTransform.Find("fo_specialbody_L1").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][(int)AvatarCreatorContext.currentRealismLevel];
            }
            else
            {
                currentTransform.Find("fo_specialbody_L1").GetComponent <Image>().sprite = null;
            }

            if (asset.GetSprites().ContainsKey(SpritePart.Default))
            {
                currentTransform.Find("fo_specialbody_L2").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
            }
            else
            {
                currentTransform.Find("fo_specialbody_L2").GetComponent <Image>().sprite = null;
            }

            if (asset.GetSprites().ContainsKey(SpritePart.Front))
            {
                currentTransform.Find("fo_specialbody_L3").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Front][(int)AvatarCreatorContext.currentRealismLevel];
            }
            else
            {
                currentTransform.Find("fo_specialbody_L3").GetComponent <Image>().sprite = null;
            }

            m_transforms[AssetType.Body].gameObject.SetActive(false);
            m_transforms[AssetType.SpecialBody].gameObject.SetActive(true);
            gameObject.transform.Find("fo_mask").gameObject.GetComponent <Mask>().enabled = true;
        }
        else if (asset.GetAssetType() == AssetType.Ghutra)
        {
            currentTransform.GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Front][0];
            currentTransform.parent.Find("fo_ghutra_back").GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Back][0];
        }
        else if (asset.GetAssetType() == AssetType.Beard ||
                 asset.GetAssetType() == AssetType.Moustache)
        {
            if (asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel] == null)
            {
                if (asset.GetAssetType() == AssetType.Beard)
                {
                    currentTransform.GetComponent <Image>().sprite = null;
                    currentTransform.parent.Find("fo_mask").Find("fo_moustache").GetComponent <Image>().sprite = null;
                }
                else
                {
                    currentTransform.GetComponent <Image>().sprite = null;
                    currentTransform.parent.parent.Find("fo_beard").GetComponent <Image>().sprite = null;
                }
            }
            else
            {
                currentTransform.GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
            }
        }
        else
        {
            currentTransform.GetComponent <Image>().sprite = asset.GetSprites()[SpritePart.Default][(int)AvatarCreatorContext.currentRealismLevel];
        }

        m_currentAsset = asset;
    }