Unity Add callbacks to prefab objects dynamically in code - c#

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!

Related

Unity Playground PICKUP & HOLD script not working properly

I am using Unity Playground with students and we are trying to use the PICK-UP AND HOLD script, but we don't think it is working properly. We have everything mentioned in the reference guide on the object, but the character doesn't pick up the object. When the is trigger is marked the player will just go through the object. When the is trigger is marked off, the player will collide with the object and it moves. Clicking the button to pick up the object just causes the object to float through colliders but the game object doesn't follow the character. I am guessing something is wrong with the parent-child part of the script but unsure as there are no errors. Here is the script down below.
Thanks!
PICKUP Script Part 1
Part 2

Assigning player prefab based on playerIndex at runtime using Unity input system

I want to have some prefabs already in the scene and then assign the players each one to control. The Input Manager is pretty clear for assigning prefabs when a player joins, but can this be changed later?
I know I can have a parent game object with several inactive prefabs as children and activate as needed, but this won't work with my current situation. Really need to just switch altogether if possible.
I'd like to use the "join manually" option which requires me to drag prefabs into the scene in the editor, then how do I assign players to them once the scene starts?
Something like:
if (GetComponent<PlayerInput>().playerIndex == 0)
{
"the player becomes prefab 1"
}
if (GetComponent<PlayerInput>().playerIndex == 1)
{
"the player becomes prefab 2"
}
I'm not sure how to access this by code (I'm pretty new) The input manager script appears uneditable, but before I realized this I tried adding some additional public game objects.
If i understand correctly your intend is to keep the players on scene while changing who controls them, right?
You should be able to get the player disconnected an reconnected to a new index without deleting the Player object from scene. Make shure you use methods properly using the docs: Player Input Manager Docs.
Otherwise I think you need an extra layer or some twist. Maybe keep the players on their indexes but change whos controlling the Player GameObjects?
By the way you can instantiate Prefabs by code using Instantiate()
You can also use inheritance to extend PlayerInputManager and maybe add some SwitchPlayer() function if really needed.
public class CustomPIM : PlayerInputManager {}
The custom class will inherit all methods from PlayerInputManager plus whatever you add.

How to "press" a button in the inspector tab from script?

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!

Click to move should i verify by tag or by game object?

Recently i came across developing a RPG game as diablo and basically the movement control needs to be carefuly made and verify every element we click before move. I was wondering by having alot of prefab of enemy gameobject, the UI and myself if i must verify by the elements with the tag i want or by the gameobject.
Well for example if i have all UI gameobjects with tag UI and enemys with tag enemy, is it good to verify by tag instead of verying directly by the gameobject name? I'm quite confused with i should use.
This depends on how many GameObjects you are verifying and how often you do it. If you don't this every frame or very often then don't worry about it. If you do it every frame or very often then check the GameObject by tag instead of by name but make sure to use the GameObject.CompareTag function to do so not with the GameObject.tag variable.
The reason is because GameObject.name and GameObject.tag allocates memory. GameObject.CompareTag does not.

Save object between scenes using DontDestroyOnLoad Unity C#

I'm making a 2D game where my character can go in and back out from different rooms, so since every room is a different scene I need to be able to somehow keep my character throughout every single scene, for that purpose unity offers DontDestroyOnLoad()
So I did use that function whenever I'm switching my scenes, however there is a problem with that.
Let's assume that my rooms are only 2 and they are really simple looking like this
Here in this scheme the main room is the one that you start your game in, it contains already spawned prefab of the character. Once we go to the second room my character is being saved with all his good stuff, however if we go back to the main scene/room we can now see 2 characters. Why ? Because our initial character is not being destroyed when different scene are loaded and we also have one that is being created along with the Main room/scene. Now this is really nasty and I don't know how to fix that, I also have the same problem with some scripts that I need throughout every single scene. Any help is appreciated.
You can make the character spawn in the main scene through script - instantiate it. Make sure you give the character prefab a certain tag ("Player" for example).
Then instantiate the character inside an if statement. Using FindGameObjectWithTag(<Tag>) == null you can find out if the character was already created.
public GameObject player;
if(GameObject.FindGameObjectWithTag("Player") == null){
player = Instantiate(prefab,position,rotation) as GameObject;
}
The normal solution is you don't create objects that are set to DontDestroyOnLoad in scenes that can be viewed more than once.
What most people do is create a pre-load scene that is the very first scene that loads with the game that creates all objects that survive between scenes, then that pre-load scene loads the "Main game scene".
If you don't want a pre-load scene then your game object needs to check on on Awake if another instance of the game object already exists. If it does find a instance then it needs to destroy itself. The first instance won't find any other instances so it won't be destroyed but all future instances will be.

Categories

Resources