I made a gameobject which can open an edit window o change it’s name. And it can create a clone of itself. When I set the name of the original to “First name”, and then make a clone below it and change the the name of the clone (which is currently “First name”) to “Second name” the name of the clone remains the same and the name of he orginal changes.
This is the code of the gameobject Person:
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class PersoonScript : MonoBehaviour
{
public Vector3 position;
public float childPos;
public int childCounter = 0;
public GameObject editor;
private TMP_Text _fieldName;
private TMP_Text _objectName;
public void AddChild(GameObject prefab)
{
position = new Vector3(transform.position.x, transform.position.y, transform.position.z) + Vector3.down * childPos;
Instantiate(prefab, position, transform.rotation);
childCounter++;
}
public void ActivateEditor(GameObject editor)
{
if (!editor.activeSelf)
{
_objectName = this.transform.Find("Canvas/Name").GetComponent<TextMeshProUGUI>();
_fieldName = editor.transform.Find("InputField/ObjectName").GetComponent<TextMeshProUGUI>();
_fieldName.SetText(_objectName.text);
editor.SetActive(true);
}
else
{
editor.SetActive(false);
}
}
public void ChangeName(string s)
{
_objectName = this.transform.Find("Canvas/Name").GetComponent<TextMeshProUGUI>();
_objectName.text = s;
Debug.Log(_objectName);
Debug.Log(_objectName.text);
}
}
Any help would be appreciated!
4 Answers
4
My first advice is to avoid using methods like Transform.Find.
Generally speaking, you should avoid accessing variables or getting data through hard coded values, because if you ever feel like changing the name of your child’s architecture, you’d break the code because then what you did wouldn’t end up finding the game objects you were looking for.
So instead of doing that, you could either make your TMP_Text fields public or keep them private but add a [SerializeField] attribute (I’d recommend the latter as it makes more sense in your case).
And it might also resolve your problem, because then your instances of PersoonScript would already have a references to the rights field at instantiation. I think you should do that first, and then re-assess the problem.
Another little advice, your method ActivateEditor doesn’t seem to just activate the editor but rather it toggles it. I’d recommend renaming it “ToggleEditor”, as it is more coherent. Semantic is very important.
Also, in AddChild, you could simplify the first line by doing that:
position = transform.position + Vector3.down * childPos;
Hope this helps.
Thanks for all the advice!
I followed it and the situation is… d̶i̶f̶f̶e̶r̶e̶n̶t̶ ̶n̶o̶w̶,̶ ̶W̶h̶e̶n̶ ̶I̶ ̶e̶n̶t̶t̶e̶r̶ ̶a̶ ̶n̶a̶m̶e̶ ̶i̶n̶ ̶t̶h̶e̶ ̶e̶d̶i̶t̶ ̶f̶i̶e̶l̶d̶ ̶o̶n̶l̶y̶ ̶t̶h̶e̶ ̶t̶e̶x̶t̶ ̶a̶t̶ ̶t̶h̶e̶ ̶t̶o̶p̶ ̶o̶f̶ ̶t̶h̶e̶ ̶e̶d̶i̶t̶ ̶f̶i̶e̶l̶d̶ ̶c̶h̶a̶n̶g̶e̶s̶,̶ ̶a̶n̶d̶ ̶t̶h̶e̶n̶ ̶w̶h̶e̶n̶ ̶I̶ ̶t̶o̶g̶g̶l̶e̶ ̶t̶h̶e̶ ̶e̶d̶i̶t̶ ̶f̶i̶e̶l̶d̶ ̶o̶f̶f̶ ̶a̶n̶d̶ ̶b̶a̶c̶k̶ ̶o̶n̶ ̶a̶g̶a̶i̶n̶ ̶t̶h̶e̶ ̶n̶a̶m̶e̶ ̶c̶h̶a̶n̶g̶e̶s̶ ̶o̶f̶ ̶w̶h̶a̶t̶e̶v̶e̶r̶ ̶o̶b̶j̶e̶c̶t̶ ̶I̶ ̶s̶e̶l̶e̶c̶t̶ ̶t̶h̶e̶ ̶e̶d̶i̶t̶ ̶b̶u̶t̶t̶o̶n̶ ̶f̶r̶o̶m̶.̶ ̶(̶S̶o̶ ̶i̶f̶ ̶I̶ ̶o̶p̶e̶n̶ ̶t̶h̶e̶ ̶e̶d̶i̶t̶ ̶f̶i̶e̶l̶d̶ ̶o̶n̶ ̶t̶h̶e̶ ̶c̶l̶o̶n̶e̶ ̶h̶e̶ ̶n̶a̶m̶e̶ ̶c̶h̶a̶n̶g̶e̶s̶ ̶t̶h̶e̶r̶e̶,̶ ̶a̶n̶d̶ ̶i̶f̶ ̶I̶ ̶a̶f̶t̶e̶r̶ ̶t̶h̶a̶t̶ ̶o̶p̶e̶n̶ ̶i̶t̶ ̶o̶n̶ ̶t̶h̶e̶ ̶o̶r̶i̶g̶i̶n̶a̶l̶ ̶t̶h̶e̶ ̶n̶a̶m̶e̶ ̶c̶h̶a̶n̶g̶e̶s̶ ̶t̶h̶e̶r̶e̶ ̶t̶h̶e̶ ̶s̶a̶m̶e̶ ̶w̶a̶y̶ ̶t̶o̶o̶.̶)̶ ̶S̶o̶ ̶w̶h̶a̶t̶ ̶I̶ ̶n̶o̶w̶ ̶l̶i̶k̶e̶ ̶i̶s̶ ̶f̶o̶r̶ ̶t̶h̶e̶ ̶n̶a̶m̶e̶ ̶o̶n̶ ̶t̶h̶e̶ ̶g̶a̶m̶e̶o̶b̶j̶e̶c̶t̶ ̶t̶o̶ ̶c̶h̶a̶n̶g̶e̶ ̶i̶n̶s̶t̶a̶n̶t̶l̶y̶ ̶l̶i̶k̶e̶ ̶i̶t̶ ̶u̶s̶e̶d̶ ̶t̶o̶,̶ ̶a̶n̶d̶ ̶f̶o̶r̶ ̶i̶t̶ ̶t̶o̶ ̶n̶o̶t̶ ̶c̶h̶a̶n̶g̶e̶ ̶i̶n̶s̶t̶a̶n̶t̶l̶y̶ ̶o̶n̶ ̶o̶t̶h̶e̶r̶ ̶g̶a̶m̶e̶o̶b̶j̶e̶c̶t̶s̶.̶
…exacly the same as before. But I messed up assigning the variables in the inspector 
Here is the current state of the code:
using System;
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class PersonScript : MonoBehaviour
{
public Vector3 position;
public float childPos;
public int childCounter = 0;
public GameObject editor;
[SerializeField] private TMP_Text _fieldName;
[SerializeField] private TMP_Text _objectName;
public void AddChild(GameObject prefab)
{
position = transform.position + Vector3.down * childPos;
Instantiate(prefab, position, transform.rotation);
childCounter++;
}
public void ToggleEditor(GameObject editor)
{
if (!editor.activeSelf)
{
//_objectName = this.transform.Find("Canvas/Name").GetComponent<TextMeshProUGUI>();
//_fieldName = editor.transform.Find("InputField/ObjectName").GetComponent<TextMeshProUGUI>();
_fieldName.SetText(_objectName.text);
editor.SetActive(true);
}
else
{
editor.SetActive(false);
}
}
public void ChangeName(string s)
{
//_objectName = this.transform.Find("Canvas/Name").GetComponent<TextMeshProUGUI>();
_objectName.text = s;
}
}
I’d love any more advice!
PS: I’m also thinking that maybe further down the line when I want to change the position of previously instantiated clones individually I may need to ad unique ID’s to all the gameobjects anyway, so maybe I should work on that first and than this problem maybe easier to resolve as well.
Much cleaner code already, don’t you agree ? : )
As for your problem, does every object have its own editor ?
What could happen is that your editor keeps editing another object than the one you clicked on. Is that a possibility in your code ?
When you call your method ChangeName from I assume your editor script, you might not have the instance of PersoonScript your want.
EDIT:
Here’s what you could do. Let’s say your editor code is named “PersoonRenamer”, you could pass in a reference to your target object in some Init Function to be sure your editing the right thing.
public class PersoonScript
{
//[...]
public void ToggleEditor(GameObject editor)
{
if (!editor.activeSelf)
{
//_objectName = this.transform.Find("Canvas/Name").GetComponent<TextMeshProUGUI>();
//_fieldName = editor.transform.Find("InputField/ObjectName").GetComponent<TextMeshProUGUI>();
_fieldName.SetText(_objectName.text);
editor.SetActive(true);
PersoonRenamer renamer = editor.GetComponent<PersoonRename>();
renamer.Init(this);
}
else
{
editor.SetActive(false);
}
}
//[...]
}
And in your script you could just do the following:
public class PersoonRenamer
{
private PersoonScript _CurrentlyEdited;
public void Init(PersoonScript currentlyEdited)
{
_CurrentlyEdited = currentlyEdited;
}
private void OnValidated()
{
_CurrentlyEdited.ChangeName(/* Your input field value */);
}
}
The reason the name change appears to affect the original object instead of the clone is due to how the references to the _objectName variable are shared among the instances.
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
public class PersoonScript : MonoBehaviour
{
public Vector3 position;
public float childPos;
public int childCounter = 0;
public GameObject editor;
private TMP_InputField _inputField; // Use TMP_InputField for user input
private void Awake()
{
_inputField = editor.transform.Find("InputField/ObjectName").GetComponent<TMP_InputField>();
}
public void AddChild(GameObject prefab)
{
position = new Vector3(transform.position.x, transform.position.y, transform.position.z) + Vector3.down * childPos;
Instantiate(prefab, position, transform.rotation);
childCounter++;
}
public void ActivateEditor(GameObject editor)
{
if (!editor.activeSelf)
{
_inputField.text = gameObject.name;
editor.SetActive(true);
}
else
{
editor.SetActive(false);
}
}
public void ChangeName(string s)
{
gameObject.name = s;
_inputField.text = s;
}
}