Example #1
0
        private static TextMeshProUGUI GetTMProText(ReplaceUnit updatedReference, TextInformation textInfo, GameObject root)
        {
            TextMeshProUGUI newText;

            GameObject textParent = FabulousExtensions
                                    .GetGameObjectAtAddress(root, updatedReference.TextAddress);

            Text oldText = textParent.GetComponent <Text>();

            if (oldText != null)
            {
                UnityEngine.Object.DestroyImmediate(oldText, true);
                newText = textParent.AddComponent <TextMeshProUGUI>();
            }
            else
            {
                newText = FabulousExtensions
                          .GetGameObjectAtAddress(root, updatedReference.TextAddress)
                          .GetComponent <TextMeshProUGUI>();
            }

            if (newText == null)
            {
                Debug.LogError($"TMPro text component is null");
            }

            return(newText);
        }
Example #2
0
        //
        // ─── TEXT COMPONENT REPLACEMENT ──────────────────────────────────
        //

        #region TEXT COMPONENT REPLACEMENT

        private void ReplaceTextComponent(ReplaceUnit updatedReference)
        {
            TextInformation textInfo = updatedReference.textInformation;

            // * Don't even think of performing below operations on previously saved prefabs loaded into the memory
            // * They are like lost souls that want to trap your innocent code
            // * Whatever you execute on them gets lost in a limbo and flushed down along the garbage collection
            // * If you want to edit a prefab, make sure you just loaded it and you work on a fresh, crunchy instance

            using (var editScope = new EditPrefabAssetScope(updatedReference.prefabPath))
            {
                GameObject      root      = editScope.prefabRoot;
                TextMeshProUGUI tmProText = GetTMProText(updatedReference, textInfo, root);
                textInfo.StyleTMProText(tmProText, _fontAssetMap);

                if (updatedReference.isReferenced)
                {
                    TMProAdapter tmProAdapter = GetTextAdapter(updatedReference, root, tmProText);
                    if (tmProAdapter == null)
                    {
                        return;
                    }
                    AssignTMProReference(updatedReference, tmProAdapter, root);
                }
            }
        }
Example #3
0
        private static object GetFieldOwner(ReplaceUnit replaceUnit, GameObject root)
        {
            object           fieldOwner       = null;
            FieldInformation fieldInformation = replaceUnit.fieldInformation;

            Type monoType = fieldInformation.FieldOwnerType;

            Component mono = FabulousExtensions
                             .GetGameObjectAtAddress(root, replaceUnit.MonoAddress)
                             .GetComponent(monoType);

            if (mono == null)
            {
                throw new NullReferenceException($"Failed to find mono {monoType} for field {fieldInformation.FieldName} and type {fieldInformation.FieldType} by its address for prefab: {root} at path {replaceUnit.prefabPath} and address {string.Join(",", replaceUnit.MonoAddress.ToArray())}");
            }

            if (fieldInformation.FieldType.HasOneOfTheFlags(FieldType.Nested | FieldType.External))
            {
                ExternallyOwnedFieldInformation eofi = fieldInformation.GetFieldInformationParamter <ExternallyOwnedFieldInformation>();

                FieldInfo externalObjectFieldInfo = monoType.GetField(eofi.ExternalOwnerFieldName, ReferenceFinder.GENEROUS_NONSTATIC_FIELD_SEARCH_FLAGS);

                if (eofi.fieldInformation.FieldType.HasOneOfTheFlags(FieldType.Arrayed | FieldType.Listed))
                {
                    var         efi = eofi.fieldInformation.GetFieldInformationParamter <EnumerableFieldInformation>();
                    IEnumerable enumberableOwner = (IEnumerable)externalObjectFieldInfo.GetValue(mono);

                    int index = 0;
                    foreach (var item in enumberableOwner)
                    {
                        if (index == efi.index)
                        {
                            fieldOwner = item;
                        }
                        index++;
                    }
                }
                else
                {
                    fieldOwner = externalObjectFieldInfo.GetValue(mono);
                }
            }
            else
            {
                fieldOwner = mono;
            }

            return(fieldOwner);
        }
        //
        // ─── SCRIPT REPLACEMENT ──────────────────────────────────────────
        //

        #region SCRIPT REPLACEMENT

        private void GatherFieldsToUpdate(ReplaceUnit reference)
        {
            if (reference.isReferenced)
            {
                Type             declaringType    = reference.fieldInformation.FieldDeclaringType;
                FieldInformation fieldInformation = reference.fieldInformation;

                if (!_fieldsToUpdateByFieldOwnerType.ContainsKey(declaringType))
                {
                    _fieldsToUpdateByFieldOwnerType[declaringType] = new List <FieldInformation>();
                }

                _fieldsToUpdateByFieldOwnerType[declaringType].Add(fieldInformation);
            }
        }
Example #5
0
        private void SaveTextReferences(string sourcePrefabPath, GameObject prefabParent, Text textComponent)
        {
            //* 1. Separately add each text component as unreferenced version of replace unit
            // ? This is quite a dirty trick, I'm sorry, more about it in ReplaceUnit
            ReplaceUnit unreferencedTextComponent = new ReplaceUnit(prefabParent, textComponent);

            UpdatedReferenceAddressBook[sourcePrefabPath].Add(unreferencedTextComponent);

            //* 2. Add all referenced versions of replace unit
            var updatedReferences = CheckTextAgainstFoundMonobehaviours(textComponent, prefabParent);

            foreach (ReplaceUnit updatedReference in updatedReferences)
            {
                UpdatedReferenceAddressBook[sourcePrefabPath].Add(updatedReference);
            }
        }
Example #6
0
        private static void SetAdapterAndTMProFieldValues(TMProAdapter tmProAdapter, ReplaceUnit replaceUnit, object fieldOwner, FieldInfo adapterFieldInfo, FieldInfo tmProFieldInfo)
        {
            FieldInformation fieldInformation = replaceUnit.fieldInformation;
            FieldType        fieldType        = fieldInformation.FieldType;

            if (fieldType.HasOneOfTheFlags(FieldType.Listed | FieldType.Arrayed))
            {
                var adpaterField = adapterFieldInfo.GetValue(fieldOwner);
                var tmProField   = tmProFieldInfo.GetValue(fieldOwner);

                EnumerableFieldInformation efi = fieldInformation.GetFieldInformationParamter <EnumerableFieldInformation>();

                if (adpaterField != null && tmProField != null)
                {
                    if (adpaterField is List <TMProAdapter> adapterList)
                    {
                        adapterList[efi.index] = tmProAdapter;
                        (tmProField as List <TextMeshProUGUI>).Add(tmProAdapter.TMProText);
                    }
                    else if (adpaterField is TMProAdapter[] adapterArray)
                    {
                        adapterArray[efi.index] = tmProAdapter;

                        //* We don't need to do the same with above adapterArray since it already has the correct size as it
                        //* replaced the old array of text components
                        TextMeshProUGUI[] tmproFieldArray    = tmProField as TextMeshProUGUI[];
                        TextMeshProUGUI[] newTMProFieldArray = new TextMeshProUGUI[tmproFieldArray.Length + 1];
                        tmproFieldArray.CopyTo(newTMProFieldArray, 0);
                        newTMProFieldArray[tmproFieldArray.Length] = tmProAdapter.TMProText;
                        tmProFieldInfo.SetValue(fieldOwner, newTMProFieldArray);
                    }
                    else
                    {
                        Debug.LogError($"Huh? Thats weird");
                    }
                }
                else
                {
                    Debug.LogError($"Either adapter field: {adpaterField} or tmpro field: {tmProField} is null.");
                }
            }
            else
            {
                adapterFieldInfo.SetValue(fieldOwner, tmProAdapter);
                tmProFieldInfo.SetValue(fieldOwner, tmProAdapter.TMProText);
            }
        }
Example #7
0
        private static TMProAdapter GetOrCreateAdapter(ReplaceUnit updatedReference, TextMeshProUGUI newTextComponent, GameObject adaptersParent)
        {
            TMProAdapter adapter;
            string       fieldName   = GetAdapterGameObjectName(updatedReference.fieldInformation);
            string       adapterName = String.Format(ADAPTER_GAMEOBJECT_NAME, fieldName);

            Transform adapterTransform = adaptersParent.transform.Find(adapterName);

            if (adapterTransform == null)
            {
                adapter = CreateNewAdapter(newTextComponent, adaptersParent, fieldName, adapterName);
            }
            else
            {
                adapter = adaptersParent.GetComponent <TMProAdapterParent>()[fieldName];
            }

            return(adapter);
        }
Example #8
0
        private static TMProAdapter GetTextAdapter(ReplaceUnit updatedReference, GameObject root, TextMeshProUGUI newTextComponent)
        {
            TMProAdapter adapter = null;

            try
            {
                string fieldOwnerName    = updatedReference.fieldInformation.FieldOwnerType.Name;
                string adapterParentName = String.Format(ADAPTER_PARENT_NAME, fieldOwnerName);

                GameObject adaptersParent = GetAdaptersParent(root, adapterParentName);
                adapter = GetOrCreateAdapter(updatedReference, newTextComponent, adaptersParent);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Exception occured for {updatedReference.rootPrefab} at path {updatedReference.prefabPath}, message:  {ex.Message}");
            }

            return(adapter);
        }
Example #9
0
        private void AssignTMProReference(ReplaceUnit reference, TMProAdapter tmProAdapter, GameObject root)
        {
            try
            {
                if (tmProAdapter == null)
                {
                    Debug.LogError($"Adapter is null for {reference.prefabPath} field {reference.fieldInformation.FieldName}");
                }

                object fieldOwner = GetFieldOwner(reference, root);

                GetAdapterAndTmproFieldInfos(
                    reference.fieldInformation,
                    out FieldInfo adapterFieldInfo,
                    out FieldInfo tmProFieldInfo);

                SetAdapterAndTMProFieldValues(tmProAdapter, reference, fieldOwner, adapterFieldInfo, tmProFieldInfo);
            }
            catch (Exception ex)
            {
                Debug.LogError($"Exception occured for {reference.rootPrefab} at path {reference.prefabPath}, message:  {ex.Message}");
            }
        }