I have a GameObject with a RectTransform that I would like to remove via script.
In other words, I want to replace the RectTransform with a regular Transform in the inspector using a script.
In the inspector, you can simply click the RectTransform dropdown and select Remove Component from there and the RectTransform is replaced with Transform. Of course this only works if there are no Components that rely on the RectTransform directly.
If I try this approach with a script like: Destroy(GetComponent<RectTransform>()) I get an error stating:
Can't destroy RectTransform component of
'MyGameObject'. If you want to destroy the game
object, please call 'Destroy' on the game object instead. Destroying
the RectTransform component is not allowed.
Of course, this is somewhat expected, since you can't remove a transform from a gameObject. In the case where I am trying to get back the old Transform component however, this behavior is undesirable.
So my question is: is there a way to replace the current RectTransform with a simple Transform component via script, and how is this done?
You can't delete a conversion.Alternatively, create an empty object and move the entire hierarchy located on that object there. You can simply change the parent of the first child and align the local position, or implement a more complex system, depending on what you need it for.
Related
I am creating a canvas with a table containing TextmeshPro Input fields on a row. I'm using the XR Input System for the Oculus Quest Vr Headset and wish to handle input from the controllers so they can interact with the Input fields (Select and DeSelect).
There will be many Rows on this canvas and the number of rows can vary according to the data they look up. So they have to be added dynamically
The input fields are part of a GameObject collection.
I've created a prefab for this collection.
I modified the prefab by placing it in a scene. Assigned to the GameObject the Callback scripts for "On Select" and "On DeSelect" and updated the prefab.
When I check the updated prefab, I see that it has lost the callback references. So I assume they need to be added in code after the GameObject has been instantiated. Can this be done or is this the wrong approach?
Mark
Ok, so I've found a solution to my own question.
I've created a script in the root prefab object.
The child callback then references the root prefab and relevant functions within the prefabs said script.
The code in the root script can pass reference or search for any global gameobjects that need to be aware of the interaction and call their callbacks.
The script is automatically saved along with the prefab and accessible for every instantiation.
Problem solved!
So I'm following video tutorials on Unity and the first teacher, that I had for the 2D part, always instantiate the bullets as GameObject while the second one, on the 3D part, always instantiate the bullets as Transform.
And the result seems to be the same but what are the differences? Is it just personal preferences?
You can consider the GameObject as a place holder of different components and Transform is a specific component.
In the image below GameObject is the cube itself and in that cube we have attached different components like Transform, Cube(Mesh Filter) Mesh Renderer and Box Collider
So now in your case you can Instantiate by referencing the GameObject as a whole or its Transform component. Usually because people will possibly modify the Transform of the GameObject they will shorten the path a bit and directly Instantiate it by referring to its Transform. However it will be the same if you would Instantiate it as a GameObject only in that case if you want to modify the Transform of the object you would need to firstly access the component then modify it.
There's not a significant difference, it's partially personal preference, and partially convenience if you are going to be referring to one more than the other.
It can mean less typing to use Transform if you'll be referring to the transform more, or use GameObject if you'll be referring to the gameobject more.
I am initiating prefabs as objects and then trying to do something using these objects that have those prefabs. However, in the inspector, its asking to attach objects that are actually already attached via code.
Code
public float hitspeed=2f;
public GameObject target, mytarget;
public GameObject arrow,myarrow;
//Use this for initialization
void Start (){
myarrow = Instantiate(arrow, new Vector3(0.02f, -3.98f, 0), transform.rotation);
mytarget = Instantiate(target, new Vector3(-0.06435323f, 2.325303f, 0f), transform.rotation);
}
Inspector
Error
[06:34:34] UnassignedReferenceException: The variable arrow of knife has not been assigned. You probably need to assign the arrow variable of the knife script in the inspector.
[06:34:39] UnassignedReferenceException: The variable myarrow of knife has not been assigned. You probably need to assign the myarrow variable of the knife script in the inspector.
With your object selected so you can see the inspector shown in the image
Go to your Project window, find your prefab.
Drag it to the the inspector where it says "none."
You can also click the little target/circle next to "none" and choose from a list.
It is true that you seem to have assigned myarrow and mytarget, however, you have instantiated them using target and arrow. You have set target using the gui, but not arrow. You must also set arrow.
In general, and to quote from another answer:
[arrow and target have] to be a prefab that you've already created in the Editor and
dragged/dropped onto the Inspector window for this object.
Ensure you:
Created a prefab
Selected this object in the Editor, so the Inspector appears
Drag/dropped that prefab onto the "arrow"/"target" field in the Inspector
In the inspector tab I see public variables, checkboxes and buttons as a part of some complex script.
How can I use C# to "press" a button/checkbox or set a value to a variable in the inspector tab, without finding and calling the corresponding functions inside this script?
So I want just to trigger the same effect which would happen if I would manually press a button in the inspector tab.
public Button myButton;
myButton.onClick.Invoke();
Is this what you're looking for?
Inspector shows you the Components of a game object , if you create an empty GameObject You will see the Transform Component Which you can add a reference To that in your Script on another GameObject like public GameObject nameYouWanted and then a slot will appears in in the inspector of the GameObject that script is attached to that which named nameYouWanted and then you can drop the game object that you created in there.
so far you just created a script on another Gameobject and then created a empty GameObject , in this step you can access the transform Component of Second GameObject by just writing someVariable = nameYouWanted.transform.position in start Or update Function in your Script! JUST LIKE THAT! simple as it is , you can access camera component of mainCamera by writing public Camera mainCamera and then access camera components
JUST KEEP IN MIND THAT:
in case of:
public GameObject varName
public is the variables accessibility level
GameObject is Component type
varName is obvious is the variable name
so here is the tricky part for beginners:
for example i have this components on my Camera
How can I access for example the LensDistortionBlur variables?
or another one i.e. Frost Component ?
ANSWER IS:
You Just have to add a reference to that in Your Script like
public LensDistortionBlur LensDistortionBlurEffect;
this image is related to glitch effect:
you see how monodevelop suggests the components variables to use ???
and then in inspector add the target GameObject in this slot (which contains LensDistortionBlur) , here is the good thing: Just because you specified the LensDistortionBlur as Component type, script just asks from that gameobject the LensDistortionBlur component and dont uses other ones, then Use that inside of any function that you want,
More Important thing in that is Component TYPE which is LensDistortionBlur , Yes you should use the component name that you want to access it , More info is Here
IN YOUR CASE
Those bools and variables you mentioned can be accessed by solution that explained above!
Here's the code I'm having problems with:
public class PlaneBehaviour : MonoBehaviour {
public GameObject ClickSymbol;
public void Update() {
if (Input.GetMouseButtonDown(0)) {
Instantiate(ClickSymbol, Input.mousePosition, Quaternion.identity);
}
}
}
When user clicks the left mouse button, then multiple ClickSymbol's will be instantiated. How to prevent that behavior (create the object only once) ?
As for the PlaneBehaviour script, it's attached to multiple (not
intersecting, not overlapping) objects on a plane
That's what I thought you are doing and wanted to verify this before adding an answer. Joe's answer should work but this is a bad design.
You get the multiple Objects instead of one because the script is attached to multiple Objects.
The proper solution here is to have one script that reads from the Input then call a function or trigger an event in another script if required. Create a new script called InputReader or with similar name then move your if (Input.GetMouseButtonDown(0))... Make that that this new script is only attached to one GameObject. Just attach it to an empty GameObject. That's it.
It will prevent problems such as executing code twice when there is an input event.
Now, let;s say that you want to notify another script attached to another GameObject when key is pressed, you can find that GameObject, get that script that is attached to it then call its function.
GameObject obj = GameObject.Find("YourOtherObjectName");
Script script = obj.GetComponent<Script >();
script.notifyKeyPress();
I attached it to multiple game objects to be able to detect which game
object was clicked
That's not how to detect which GameObject is clicked. Since this is a plane, I assume it is a 3D Object with a 3D collider. See 6.For 3D Object (Mesh Renderer/any 3D Collider) from my other post on how to do this.