How can I reset a prefab in Unity to it's initial state when I click a button?
Absolute beginner, not sure where to start. Any help would be appreciated. Thanks!
As TEEQNE said, you'll have to cache (save) the values when you start the game (on the void Start(){} method probably), then whenever you press the button (on the button's.onClick method) you'll want to reset those values.
Another strategy which could save you from the potentially tedious work of caching each value you want reset, would be to simply destroy the gameobject and reinstantiate it using the prefab.
void OnReset(){
var resetGameobject = Gameobject.Instantiate(myPrefab);
Destroy(this);
}
If you're resetting a lot then you might run into some performance issues with the second approach, but it probably won't be a concern in your case.
Let me know if you need a more detailed walkthrough/code examples.
Probably the simplest way would be to destroy this object and instantiate a new one from this prefab.
You could create some sort of ButtonManager script which holds the reference to the currently active object and when the button is clicked, it destroys it and creates a new one in its place, like this:
class ButtonManager: MonoBehaviour
{
// you can drag the prefab in the inspector to this field
public GameObject prefab;
GameObject actObject;
// you set this method to be launched in the button's menu
void OnClick()
{
Destroy(actObject);
actObject = Instantiate(prefab);
}
}
Another way (better optimized and preferable in production and bigger games) would be to just write some sort of Reset function that reverts all the changes made to this object.
Related
Basically, In my scene, underneath a GameObject called 'GameOverUI' I have some buttons and a Panel that covers the screen. I have made a simple animation where the panel's opacity (The alpha channel) increases. Do any of you know how to make it so that when the player dies, it enables GameOverUI and plays the animation for the panel once?
Edit: Forgot to mention, I know how to make it so that 'GameOverUI' is enabled, I just don't know how to make the animation play
If you are looking for a solution with animations, then here you go:
Create a script for your GameOverUI gameObject. Really simple:
public class UIHandler : MonoBehaviour
{
private void OnEnable()
{
//play "dead screen" animation
}
}
Method OnEnable() is a MonoBehavior function, and will be called when you enable a GameObject by calling myGameObject.SetActive(true);.
However, I would recommend thinking about another solution. I usually leave GameOverUI always active and use it to manage its children via script. So I think it would be more elegant to write something like this:
public class UIHandler : MonoBehaviour
{
public void PlayerDied()
{
//play "dead screen" animation
}
}
The difference is, that instead of enabling and disabling the GameObject, you call a method. This way, you will be able to pass data (as function parameters) if you need to do so. For example, you can write to the screen, what caused the death. And further on, the GameObject will be able to manage its UI components for other purposes.
I hope it makes sense and I could be of your help!
I am trying to add same components to different game objects in a scene in Unity. To make it faster I am trying to write a script that will do this for a list of game objects like (enemy1, enemy2, enemy3...).
I know that adding a script named Enemy I will do:
gameObject.AddComponent<Enemy>();
But the problem is once I stop the play mode the component is gone. Is there a way to achieve this?
You can directly select all the game objects (the list of enemies you mentioned) from the Hierarchy by holding ctrl and then add in the inspector the script Enemy to all of them.
However, if you want to use a script to do it, which can be executed outisde of the Play Mode you need to add ExecuteInEditMode before the script, like this:
[ExecuteInEditMode]
public class TriggerEdit : MonoBehaviour
{
// List of GameObjects
String[] enemyList = {"enemy1", "enemy2", "enemy3"};
void OnEnable()
{
foreach(String enemy in enemyList){
go = GameObject.Find(enemy);
go.AddComponent<Enemy>();
}
}
}
Then you need to add that script to any game object in your scene. Everytime you want to trigger the script you just need to disable and enable the script TriggerEdit in the editor:
One problem with this approach is that everytime you enable the script, it will add a new component, independently if there is already a compoment of type Enemy in the game object, so you may end up with a lot of Enemy components. Something you can try then is to clean all Enemy components in the scene before adding anything else new. For example:
object[] enemiesToDelete = GameObject.FindObjectsOfType<Enemy>();
foreach(UnityEngine.Object enemyComponent in enemiesToDelete)
{
DestroyImmediate(enemyComponent);
}
So I have an animation that fades into the menu screen but after the animation ends none of my buttons work. I have figured out that it is because the GameObject that holds the black image that fades to clear is always in the front, blocking me from using any of the buttons. I tried to write a script, that's attached to the game object, that disables the GameObject after it completes the animation, but it isn't working.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class LevelChanger : MonoBehaviour
{
public Animation anim;
public void SetTrigger()
{
this.StartCoroutine(this.PerformAnimRoutine());
}
private IEnumerator PerformAnimRoutine()
{
var state = anim.PlayQueued("Fade_In", QueueMode.PlayNow, PlayMode.StopSameLayer);
yield return new WaitForSeconds(state.length);
this.gameObject.SetActive(false);
}
}
Is there anything wrong with the code or is there an easier way to accomplish this? I am extremely new to unity so I am very stuck.
If all you are doing is fading a sprite to clear and you seem to know about coroutines, I might start by suggesting you do the fade within a coroutine instead.
Have that decrease the alpha by some fraction each frame and when it's 0 disable the object.
That's just if that sounds more fluid, nothing wrong with the animation way.
Doing it with animations though :
I'm not confident that you can disable the object the animation is on in that animation. If it is available on the dope sheet try that. Otherwise we can use state behaviours or animation events.
Animation Events
These can be used to trigger a function at a certain point of an animation. You can create them similar to keyframes. Here is a link to Unity's guide on this topic.
All you'd need to do is create an event and place it at the end of the animation. Then you need to in a script of that object make a public function that simply disables the object. Call that with the event.
State Behaviours
State Machine Behaviours allow you to define a script to run on a given animation state. It has many functions to hook onto such as OnStateEnter and OnStateExit.
You'd want to click on the state that fades in the animator. In the inspector you should be able to click "Add Behaviour". This will create a script that you can open and edit. Here is the reference for that class.
From there is should be very simple to disable the object through OnStateExit.
I'm still a bit lost on this. Basically I want to have a persistent gameobject throughout multiple scenes. This gameobject will represent the players avatar. It is displayed using a prefab.
I tried adding the singleton script to my login scene controller. I have a public GameObject class parameter but it isn't showing up in the inspector so I can drop the prefab in. Maybe I'm getting this wrong.
Also, let's say I'm testing a scene. Since the singleton is initialized in the login scene, How would I get this global gameobject prefab into that new scene I'm testing considering I won't even be loading the login scene during testing?
I think I'm just super confused. All I want is to be able to use 1 script which represents the players "avatar", including the prefab used to display it, and have it persist throughout the entire game. Is this possible? Also, how do I get it when I'm testing scenes and haven't called the scene containing the singleton?
Thanks for anyone who can help me.
Basically I want to have a persistent gameobject throughout multiple scenes. This gameobject will represent the players avatar.
Use DontDestroyOnLoad on the object that should persist throughout multiple scenes.
Take caution if you are loading back the same scene that set the Object to DontDestroyOnLoad, as it will create another same object that has a DontDestroyOnLoad. This post talks about it.
Edit (Thanks to yes), check the comments in this answer.
(There are also a few more options that you have depending on your needs, Hugo's answer from this post has it.)
I tried adding the singleton script to my login scene controller. I have a public GameObject class parameter but it isn't showing up in the inspector so I can drop the prefab in. Maybe I'm getting this wrong.
Show some codes? It is hard to exactly tell what is wrong.
It might be the fact that you forgot to drag in your script to a game-object, or the class is static, etc.
is there anyway to draw stuff on scene view without calling OnSceneGUI?
or is there a way to get OnSceneGUI to get called even if the object with the script attached is not selected?
Edit: Looks like I wasn't explicit enough on what I was asking for so here's a little update:
I have a whole bunch of controls shown as GUI objects on my Game Scene that are used by the game designers to more easily test the game. Since these tools are for development use rather than deployment, I wanted to move these to the scene window instead.
Unfortunately I am only able to display these GUI tools if the object that contains the script with the "OnSceneGUI" method is selected. Instead I want them to be displayed whenever the game is running and regardless of the selected object.
I have found the solution to my issue.
If you want your GUI stuff to always be displayed on the scene window you can do the following:
public class MyClass{
static MyStaticConstructor() {
SceneView.onSceneGUIDelegate += OnScene;
}
static void OnScene(SceneView sceneView) {
// Draw GUI stuff here for Scene window display
}
}
This code will run as soon as you press play and will draw whatever you wish on your scene window.
Hope it will help others!
There are many ways to use GUI,
The easiest but least efficient way is using the GUI class on OnGUI()
GUI.Label(new Rect(10,10,10,10), "This is a label");
GUI.Label(new Rect(10,10,10,10), "Your Texture2D here");
Any active monobehaviour will run OnGUI() if its defined. So it can be attached to any gameObject. You can create an empty gameObject in the scene and call it "GuiGameObject" for example and attach the script there. That way it wont be mixed in with your gameplay script.
There are also GUI textures --> More Info on GUITexture
Also I recommend checking out nGUI
Edit:
For OnSceneGUI You can try Editor.Repaint, you can use it to make sure that the inspector updates changes made inside of OnSceneGUI