Remplacer l'instance d'un objet à un autre en C#
Dans cette question, je voudrais savoir si et comment cela est possible. Cette technique semble très mauvaise pratique, mais il semble que l'API (UnityEditor) que j'utilise, est en train de faire quelque chose de ce genre et je suis juste curieux.
Si il y a plusieurs références pour le même objet, est-il possible d'instancier un nouvel objet dans le même emplacement de mémoire de sorte que toutes les précédentes références pointer vers le nouvel objet?
J'ai compris que le seul moyen de le faire est d'utiliser le C++. Essentiellement les suivants qui se passe:
//Original prefab
GameObject prefab = x;
prefab.tag = "Untagged";
//A copy of the original prefab
GameObject prefabCopy = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
prefabCopy.tag = "EditorOnly"; //Change from initial value "Untagged"
Debug.Log(prefab.tag); //"Untagged" - expected
Debug.Log(prefabCopy.tag); //"EditorOnly" - expected
//Replace contents of prefab file with `prefabCopy`
PrefabUtility.ReplacePrefab(prefabCopy, prefab);
//Destroy the copy
DestroyImmediate(prefabCopy);
Debug.Log(prefab.tag); //"EditorOnly" - whoa?
Certains comment prefab
est maintenant pointe vers un objet différent?
Remarque: gardez à l'esprit que l'Unité est construite au-dessus de la Mono saveur .NET
- Ce qui se passe à l'intérieur de
PrefabUtility.ReplacePrefab(prefabCopy, prefab);
? PrefabUtility.ReplacePrefab
invoque une méthode interne (selon l'assemblée navigateur).
Vous devez vous connecter pour publier un commentaire.
Depuis un état de l'objet est définie par les valeurs de champ, vous pouvez copier de la mémoire, contenant les valeurs des champs d'un objet à un autre, effectivement "remplaçant" c':
Noter que ce code nécessite
[StructLayout(LayoutKind.Sequential)]
(ouLayoutKind.Explicit
) attribut défini pour une classe.UnityEngine.Object
a[StructLayout (LayoutKind.Sequential)]
null
après avoir été détruit. Est-il un moyen avecMarshal
pour afficher une représentation sous forme de chaîne d'un pointeur? Je voudrais comparer la référence deprefab
avec la valeur de retour dePrefabUtility.ReplacePrefab
sans Unité est en mesure de réaliser toute sorte de magie noire.var gch = GCHandle.Alloc(obj, GCHandleType.Pinned); var address = gch.AddrOfPinnedObject(); gch.Free()
, mais il ne fonctionne pas pour la plupart des types d'objet. Je pense que c'est aussi proche de l'adresse d'objet que vous pouvez obtenir. De toute façon, je ne pense pas qu'il y est une chance que quelque chose est en train de changer les références de votre code à la place d'instances de l'objet (sauf pour le garbage collector, bien sûr).ArgumentException: Object contains non-primitive or non-blittable data.
Cheers 🙂StructLayout
attribut est présent.Vous pouvez le faire si vous incorporez votre objet en un autre, qui est utilisé pour accéder à l'objet.
Maintenant, vous pouvez créer de multiples références à un objet de type
MyObjectReference
et de ne modifier que l'objet local. Le "vrai" objet serait accessible via leValue
propriétéUne approche légèrement différente, c'est que vous créez un wrapper qui implémente la même interface que votre "réel" de l'objet, ce qui rend cet emballage transparent.
Maintenant le wrapper peut être utilisé comme si c'était le "réel" de l'objet. Vous pouvez également passer une première instance de la "vraie" objet dans l'emballage du constructeur et de supprimer l'initialiseur de
_obj
.Non, ce n'est pas possible.
D'en changer toutes les références à un objet, vous devez geler tous les threads du processus, et d'accéder à leurs jeux de registre et de la pile. C'est ce que le garbage collector ne, mais il n'est pas possible pour le code standard.
Ce que la méthode la plus probable n'est de faire une copie d'un objet sur l'autre.
UnityEngine.Object
's ne sont pas thread-safe.Si c'est une Classe personnalisée que vous souhaitez pour référence, je pense que vous pouvez avoir toutes les références point à un Faux de Référence...
J'ai Ajouté un opérateur d'Affectation, donc j'ai tout Un des Objets que l'ACs.
Maintenant, si vous le souhaitez, vous pouvez utiliser le ChangeReference méthode pour passer tous à la nouvelle Référence..
en C++, vous utilisez référence à la Référence
Bonne chance