Inventory can close once, but fails to open again - c#

I'm creating an inventory system (using Unity 2021.3.4f1) , and want it to be able to pop up/close by pressing the same keycode. The method I've seen others using for this doesn't seem to work for me, since I'm only allowed to close the inventory once, if I start the game without unchecking the inventory. Nothing happens when I press the same key again.
Here's what I've used for the Update()
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
inventory.gameObject.SetActive(!inventory.gameObject.activeSelf);
}
}

Once you disable the game object the script becomes disabled as the game object and it will not run.
what I suggest you do I make a parent game object and attach the script to it and when you want to disable you have to disable the child

Related

Show scene once after lunching the game

Hello!
I'm making a game and I want to add a tutorial(walkthrough) at the beginning of the game.
So, I created a scene where I have all the information and now I just want to show it once after the game was launched and never show it again.
I have already search on the internet for the information. I only found some info about PlayerPrefs and I don't really know how to use it.
Thank you for your time!
You can set variable in PlayerPrefs like this:
PlayerPrefs.SetInt("IsFirstRun", 1);
and then you can check if the variable exists:
if(PleyerPrefs.HasKey("IsFirstRun")) // show the scene
This is how your script would look:
void Start()
{
if(!PleyerPrefs.HasKey("IsFirstRun"))
{
// open scene
PlayerPrefs.SetInt("IsFirstRun", 1);
}
}

Restart button doesn't work on Unity 5.6

I'm trying to make a restart button on top of a game over screen. But it seems that the button doesn't work. I've put it on the On Click() menu and it kept doing nothing when i clicked on it.
My code:
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class ButtonCodes:MonoBehaviour
{
public void RestartGame()
{
SceneManager.LoadScene(0);
}
}
Look into 4.6 UI Buttons.
Create the button in your scene, and in OnClick, drag the gameObject with your ButtonCodes into the target field (left), and choose RestartGame in the right, which will be an option under ButtonCodes.
This might be what you've already done.. if that's the case, try using some Debug.Log("Button was Clicked"); statements. If these show up, it's likely you haven't set up the Build settings to include any levels. (Unity does not add levels here just by pressing play - you must do this yourself)
Assumming there are no errors, the most likely reason it's not working is that you didn't specify any scenes in File/Build Settings (Ctrl+Shift+B)
https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.LoadScene.html
That shows that you need to order your scenes in the Build Settings if you use the sceneBuildIndex. You could also use the second LoadScene that uses sceneName which may be more reliable if you constantly reorder scenes in Build Settings.
Also, if you haven't already, try using Debug.Log to make sure that that part of the code is actually being called.
try to put the name of the scene in the scenemanager and make sure your scene you gonna load is on your build settings
public void RestartGame()
{
SceneManager.LoadScene(//name of your scene);
}
1- Sometimes when i duplicate a button and use it with other functions, it doesn't work.
2- Another reason that i faced was when i use inherited class, it doesn't work many times too.
3- Sometimes you forget to add your "0" scene in to build setting as well.
Thank you all for answering. All of the things that you said is already been done and still, the button won't work. In the end, i solved the problem myself. I realized that my Canvas doesn't have an EventSystem that was an important thing for a button to work.

Keep Links between two gameObjects when scenes change in unity

I'm Working on a game, and i want to create a mute button. So i wrote a script for that and i attach this script into a gameObject that don't destroy on load.
I link the script with a UI Button present in a main menu. This UI button is destroy when i'm changing scenes.
when i start my game, and i click on the button, the audio turns off, and when i click back, it turns on.
But when i change to another scene, and i go back to the main menu, my script doesn't have the UI Button attach to it. so when i touch the button the audio doesn't change is behavior
I would like to know if it's possible to maintain the link between the UI Button and the script (attach to a normal GameObject), even if the UI Button is destroyed?
i tried this:
ButtonGameObject = GameObject.Find("UI Button");
but it doesn't work.
How can i fix that?
Thanks a lot.
There are many ways to work around this, but here's one:
Step 1: If you haven't already done so, implement a weak singleton pattern on your mute script (let's call it MuteScript.cs for now).
private static MuteScript singleton {get; private set;}
private void Awake() {
if (singleton == null) singleton = this;
[whatever other stuff you were already doing in Awake()]
}
public static void ToggleMute(Graphic graphic)
{
singleton._ToggleMute(graphic);
}
private void _ToggleMute(Graphic graphic)
{
[whatever code you were running in your original mute method]
}
Step 2: Attach a simple script to your UI button:
public class MuteButton: MonoBehaviour
{
Graphic myGraphic;
private void Awake() {
myGraphic = GetComponent<Graphic>();
}
public void OnClick() {
MuteScript.ToggleMute(myGraphic);
//I assume you want to do something like change the colour of the button when
//the player toggles it. Passing the Graphic to the MuteScript is the easiest
//way of doing this. If you really want to keep your code clean, though,
//I recommend expanding the MuteButton class with methods to take care of
//the UI side of things.
}
}
Step 3: In Unity Editor, setup your button to call its own OnClick() method, not the MuteScript method.
-
Now when you click the button, it will call the static MuteScript.ToggleMute(), which accesses the static-cached singleton reference, which in turn points back to your original object.
Singletons and static accessors are great for efficiency in Unity because they save you from having to call expensive search functions like FindObjectsOfType(). The only gotcha is that you have to be careful about not having multiple copies of a singleton-class object lying around, especially when using DontDestroyOnLoad().
So a better approach rather than having a script search and grab the component is to use a PlayerPrefs class from Unity. Essentially, it will hold onto all important aspects of the game and auto fill information.
This is a great tool for a lot of user customization aspects of a game. When using this, have a script (sceneController would be a good name) that will run when the scene starts (create a blank object at 0,0,0) and then under void Start() have the script grab the mute/unmute button: GameObject.Find("MuteButton") or (my favorite) give it a tag called MuteButton and run: GameOject.FindWithTag("MuteButton"). Also once you get a link to the button, add a listener to it for when the button is pressed.
Also store the sound manager in a gameController that will be passed throughout the game. This would control the soundManager and have access to that. So sceneManager will also need a reference to gameManager.
Using a script that is just for player preferences (a controller if you will) is a better way to organize and contain any preferences for the users. Just better clarity and separation.
Example
SceneController Object Script
class SceneController {
GameObject muteButton;
void Start() {
muteButton = GameObject.FindWithTag("muteButton");
muteButton.AddListener(muteButtonCheck);
}
void muteButtonClick() {
if (PlayerPrefs.GetInt("playerMute")) {
// If 1 (on)
// Set sound off
PlayerPref.SetInt("playerMute", 0);
} else {
// It's 0 (off)
// Set sound on
PlayerPrefs.SetInt("playerMute", 1);
}
}
}

Add delay in C# in Unity3D projects

I currently work on Unity and using C# language.
By far, I need to do something (in smallest case, load another scene).
My question is, how to make this something happens after a few seconds I put the cursor on the area?
this is my code right now.
if (_newGameButton.Contains (Event.current.mousePosition)) {
Application.LoadLevel (1);
Destroy (this);
}
I want to add delay when _newGameButton actives. Right now, when I move my cursor over _newGameButton it'll load scene 1 immediately. I have tried many ways such as using Invoke and WaitForSeconds. None works. If the mistake is how I use it, how's the right way? Thank you so much for your help.
EDIT: This question is answered and I have another question in Activate and Deactivate Invoke function.
To make timers and delays in Unity, simply use Invoke
void Start()
{
Debug.Log("hello from Start.");
Invoke("Test", 3f);
}
private void Test()
{
Debug.Log("hello from 'Test'");
}
Also very handy is InvokeRepeating
Invoke("Test", 5f, 0.5f);
It's that easy.
In your case
if (_newGameButton.Contains (Event.current.mousePosition))
{
Invoke("YourSceneName");
}
private void ChangeScenes()
{
UnityEngine.SceneManagement.SceneManager.LoadScene("ScreenMain");
}
You MUST USE the scene name. Don't forget you MUST HAVE DRAGGED THE SCENE, TO YOUR SCENE LIST. Look at "Build Settings" "Scenes in Build".
Note
That's not really how you load scenes in Unity these days. They changed the syntax. it's more like this...
UnityEngine.SceneManagement.SceneManager.LoadScene("ScreenMain");
If you want to load asynchronously
AsyncOperation ao;
ao = UnityEngine.SceneManagement.SceneManager.LoadSceneAsync("SceneName");
while (!ao.isDone)
{
Debug.Log("loading " +ao.progress.ToString("f2"));
yield return null;
}
If you have any questions about scene loading, ask them separately as a new question. Note that you should almost certainly NOT do this "Destroy(this);".
Well ill help you understand something a bit bigger then just pausing cause it seems you are trying to create on OnClick event, nowadays its being used differently.
what you realy want to do is just create the SceneLoader script which can be a very general script such as the following,
using UnityEngine;
using UnityEngine.UI;
public class UIController : MonoBehaviour {
public int numOfSceneToLoad; // number of the scene from the build settings
public void LoadSceneNumber(numOfSceneToLoad){
UnityEngine.SceneManagement.SceneManager.LoadScene(numOfSceneToLoad);
}
}
and then you want to attach this script to your main UI Canvas/Holderplace, go to your button and at the bottom of the inspector you will see onClick(),
click on the + sign and then make the setup as follows, drag the Object you have attached this script to and put it under the "runtime" laber in that small onClick() window, then scroll and find this specific function we just created and in there you can modify the value of numOfSceneToLoad to the scene you want to load, and woilla you have a Dynamic script to load any scene you wish to.
on this note ill reffer you to some pretty amazing toturials made by unity that will teach you how to make a proper UI in unity5.
http://unity3d.com/learn/tutorials/topics/user-interface-ui/ui-button
From your description, it looks to me that your _newGameButton is set to inactive by default and you want it to active and user intractable after few delay.
For that you can create a script and keep reference of _newGameButton in it, something like this:
public GameObject _newGameButton;
and on an event say GameOver, implement like this:
void GameOver()
{
Invoke("EnableNewGameButtonAfterDelay", 5f);
}
void EnableNewGameButtonAfterDelay()
{
_newGameButton.SetActive(true);
// now this game object is active and user can click on it.
}
In this example i demonstrated that the game has been over and after 5 second delay user have new game button set to enable. [This code is not in executable form and just to give you an idea]
Hope this helps!

Load scene using canvas button

void OnMouseDown() {
SceneManager.LoadScene ("Scene2");
}
I have tried every conceivable method. The method posted has worked for me using GameObjects with colliders. Instead, this time I am using a button on a 2D canvas. It does not work in this context.
How do I load a new scene using a button in a canvas? I have tried so many different things. This should be simple.
Thanks for any advice.
Here (link: Unity page) you can find a video tutorial how to use Button on canvas in UnityGUI. It's for Unity 4.6 but its really simillar to newest (5.3.1).
It's quite simple. U can make a script with public method e.g
public void LoadScene2()
{
SceneManager.LoadScene ("Scene2");
}
Attach this script to some GameObject e.g Controller. And add event in Button inspector.
In my opinion there is a better solution for the one shown by #Paweł Marecki
I use this in my projects.
OK so you will simply create a script called ButtonManager and inside it you can make a method like this
public void ChangeToScene(string sceneName)
{
Application.LoadLevel(sceneName);
OR
SceneManager.LoadScene(sceneName);
}
Now you have your canvas button, you will select it and look for "Event Trigger"
(i got this image from google to help) add a new mouse down event.
Create an empty GameObject on your Scene, name it "ButtonManager" and drag it onto the event box.
Now you need to click that dropDown list and find your "ChangeToScene" method.
You will see that an editor field appears below, type your desired scene name and hit play :P
This way you will always use this script when you want to change scenes.
You can add other methods and add functionality, but the beautiful part is that you dont need to create a method each time the name of the scene changes.

Categories