I want the user to be able to select in the main menu if they want to start the game with VR Stereo enabled or if they want to load it in mono. Right now the GvrViewer script has a boolean checkmark in the GUI to enable/disable VR so I am trying to have the user essentially control that boolean from the main menu.
I'm not sure if I'm on the right path, but I have 2 buttons on the Main Menu that say "Enter in VR" and "Enter in Mono". Ideally, clicking on "Enter in VR" triggers a function that sets the boolean and loads the new scene with that boolean triggering the VR mode. However, I can't figure out how to pass the stored boolean into the new scene and have it override the settings already stored from the GUI inspector. I have tried "finding" the gameobject's value from my Menu script but I can't seem to have any success.
// buttons on main menu
public void LoadMono(int level) {
MonoOrStereo.VRModeEnabled = false;
Application.LoadLevel (level);
}
public void LoadStereo() {
MonoOrStereo.VRModeEnabled = true;
Application.LoadLevel (level);
}
// boolean provided by GvrViewer script for GUI inspector settings
bool VRModeEnabled {
get {
return vrModeEnabled;
}
set {
if (value != vrModeEnabled && device != null) {
device.SetVRModeEnabled(value);
}
vrModeEnabled = value;
}
}
[SerializeField]
public bool vrModeEnabled = false;
The correct approach would be to have Game manager object which is persistent across the game and has control over settings class object.
In case if you still need to get to Public boolean visible in inspector, use this approach:
SettingsObject = GameObject.FindGameObjectsWithTag("Settings");
SceneManager = SettingsObject.GetComponent<SomeSceneManagerClass>();
Scenemanager.vrModeEnabled = true;
It's hard to tell exactly what needs to be done because I need to see the structure of your project, which classes are managing your project and how they are composed in Inspector
(please note that the code above just indicates the approach and may not work as you want it to. For it to be useful in your case the data I mentioned above is required)
Related
So i got this action object witch contains a button, when i press that button the action coroutine starts, sets the cooldown of the action and enabled=false the button.
Im trying to implement a cooldown system so every time the turn ends action.currentCooldown -=1.
Im yet to implement my turn manager and i must admit im a bit clueless about it, i guess it must have a state(allyTurn, enemyTurn) and a coroutine to update all action cooldown when the turn changes.
Also what i want to do is asing a List to each unit and then display each action buttons.
here are some screenshots of the code (keep in mind its just a first draft and im still learning the basics)
Hereis the action object
here is the code for the action
I apreciate all the help i can get
So there are a couple ways to implement what you are looking for. The way that I would want to go for is using events. You could create events for each state change (i.e. AllyTurnStart and EnemyTurnStart):
public class ExampleClass : MonoBehaviour
{
bool AllyTurn = true;
UnityEvent AllyTurnStart;
UnityEvent EnemyTurnStart;
BaseAction AllyAction;
BaseAction EnemyAction;
void Start()
{
// This will setup the event listeners that get called
if (AllyTurnStart == null)
AllyTurnStart = new UnityEvent();
if (EnemyTurnStart == null)
EnemyTurnStart = new UnityEvent();
// This is for example purposes but assigning actions to the events can happen anywhere
AllyAction = new BaseAction()
EnemyAction = new BaseAction()
AllyTurnStart.AddListener(AllyAction.StartOfTurnEvents);
EnemyTurnStart.AddListener(EnemyAction.StartOfTurnEvents);
}
//This method is meant to simulate switching turns back and forth.
void NextTurn()
{
if(AllysTurn)
{
AllyTurnStart.Invoke()
}
else
{
EnemyTurnStart.Invoke()
}
//This switches whos turn it is
AllysTurn = !AllysTurn;
}
}
public class BaseAction : Monobehaviour
{
int Cooldown;
public StartOfTurnEvents()
{
// Here you can reduce the cooldown, Check if it is ready, etc.
}
}
Hope this helps.
I'm trying to make a custom unity editor and for some reason every time I close the window and open it again, my list resets to null.
I'm trying to save data from a dictionary by separating the keys and values into 2 separate lists OnDisable, and then re-creating the dictionary OnEnable by combining the lists. But every time OnEnable is called I get a null from my lists...
Here's an example of what the code looks like.
public Dictionary<string, string> myDictionary = new Dictionary<string, string>();
[SerializeField]
public List<string> listOfDictionaryKeys;
private void OnEnable()
{
// this always returns null
Debug.Log(listOfDictionaryKeys.Count);
}
private void OnDisable()
{
// this successfully saves the keys to the list
listOfDictionaryKeys = (myDictionary.Keys).ToList();
}
Does anyone have any ideas why I could be losing my list data? I'm not setting any values in an inspector, they're all being set and saved by code.
UnityEditor is a (great tool) tricky beast, that runs its own callback loop, and serialisation and deserialisation within the editor can be a bit messy.
Sometimes unity will igoner whatever constructor of an object did, and override it with default values, on the next update. I imagine that the inspector of an object initializes it when it finds null where a list is expected, but if you don't save the new serialized form with your scene, it will remain null, and will be null when OnEnable happens in the bulld (after deserialisation), unless its saved with the scene.
I do not have a full grasp of the process but that's how I imagine it.
For a quick workaround do:
private void OnEnable()
{
if (listOfDictionaryKeys==null) listOfDictionaryKeys=new List<string>();
// this always returns null
Debug.Log(listOfDictionaryKeys.Count);
}
this way you won't accidentally erase it in case it exists
I don't really understand from your question whether OnEnable and OnDisable are part of your editor script or the component itself.
If the later:
OnEnable is called when the component goes from disabled to enabled state, not when it gains focus in the inspector. The same way OnDisabled is called when the component or according GameObject is disabled, not if it loses focus.
If what you want is reacting to gaining and loosing focus in the inspector it would have to be OnEnable and OnDisable of the Inspector script itself. E.g.
[CustomEditor(typeof(XY)]
public class XYEditor : Editor
{
XY _target;
SerializedProperty list;
// Called when the class gains focus
private void OnEnable()
{
_target = (XY) target;
//Link the SerializedProperty
list = serializedObject.FindProperty("listOfDictionaryKeys");
}
public override void OnInpectorGUI()
{
//whatever your inspector does
}
// Called when the component looses focus
private void OnDisable()
{
serializedObjet.Update();
// empty list
list.ClearArray;
// Reading access to the target's fields is okey
// as long as you are sure they are set at the moment the editor is closed
foreach(var key in _target.myDoctionary.keys)
{
list.AddArrayElementAtIndex(list.arraySize);
var element = list.GetArrayElementAtIndex(list.arraySize - 1);
element.stringValue = key;
}
serialzedObject.ApplyModifiedProperties;
}
}
I also don't see where you populate the dictionary since you say it is not happening in the inspector. This might be a problem when mixonbSerializedProperty with direct access to fields.
Short explenation, of what I'm trying to do:
I'm working on a project in Unity. In the first scene I have a UI canvas with 8 Input Fields, for the user to type in up to 8 names. When the user is done typing in the amount of names he/she wants, he/she presses a 'done' button, and all of the names are added in correct order to a list and a new scene is loaded. Then the game begins, and the game goes through the list in chronic order, and gives tasks to the person whos turn it is.
The problem:
The names are added correctly to the list. But when the scene changes, the list empties itself, and all the string variables are deleted. I can't figure out why.
public string namePlayer1, namePlayer2, namePlayer3;
public bool player1IsPlaying, player2IsPlaying, player3IsPlaying = false;
List<string> playerList;
public void getInput1(string player1Name)
{
if (player1Name == "")
{
player1IsPlaying = false;
}
else
{
namePlayer1 = player1Name;
player1IsPlaying = true;
}
}
This code is executed by an 'on end edit' event, when the user has finished typing in a name in the UI Input Field. When the user has typed in the names he/she wants, he/she presses the 'done' button, and this code is executed:
public void PutNamesInList()
{
if (player1IsPlaying)
{
playerList.Add(namePlayer1);
}
if (player2IsPlaying)
{
playerList.Add(namePlayer2);
}
if (player3IsPlaying)
{
playerList.Add(namePlayer3);
}
startGame();
}
Now when a new scene is loaded, all the variables are empty.
Any help is appreciated.
When loading a scene (if not in an additive way) it will destroy everything before loading the new scene. If you don't want a GameObject (and its properties) to be destroyed automatically, use this: https://docs.unity3d.com/ScriptReference/Object.DontDestroyOnLoad.html
If you are not willing to use Object.DontDestroyOnLoad You can also use PlayerPrefs which means
Stores and accesses player preferences between game sessions.
This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 6 years ago.
EDIT
My question is different (I think..) because the last image allows me to set a GameObject to the Communication Message and Communication Message. BUT, on play, it immediately resets to None (Text) and None (Button). I don't know why this happens or how to solve this!
I am aware this question is widely covered but still I cannot solve this. I hope someone has a solution for me.
What I have
I am working with Behavior Designer, an asset for Unity. I'm making Behavior Trees and the problem occurred when using a behavior tree reference.
First, I had my Behavior Tree like this:
It searches the front door. If it is found, it will move towards it and communicate with the human playing the game.
This worked before, but now I put this behavior tree in a Behavior Tree Reference, like this:
When I double click the reference, the first image shows. BUT, where it goes wrong, is this:
Problem
This is the human instructions node in the first picture. It doesn't load the communication message and communication button. When I load the corresponding button, it immediately resets on playing the scenario. This happened when I loaded this behavior in the Behavior Tree Reference, and the problem didn't occur when I played this from the original tree self.
NullReferenceException: Object reference not set to an instance of an object
HumanInstructions.CommunicationElements (Boolean activeOrNot) (at Assets/HumanInstructions.cs:54)
HumanInstructions.OnAwake () (at Assets/HumanInstructions.cs:19)
BehaviorDesigner.Runtime.BehaviorManager.EnableBehavior (BehaviorDesigner.Runtime.Behavior behavior)
BehaviorDesigner.Runtime.Behavior.EnableBehavior ()
BehaviorDesigner.Runtime.Behavior.Start ()
Any ideas what could cause this and how to solve this?
The code from HumanInstructions
using UnityEngine;
using UnityEngine.UI;
using BehaviorDesigner.Runtime;
using BehaviorDesigner.Runtime.Tasks;
using UnityStandardAssets.Characters.FirstPerson;
public class HumanInstructions : Action
{
public string humanInstructionsText; // The string in inspector that shows up on-screen for the human operator to communicate with UGV.
public string messageToConsole; // Print this message to console when the action is performed SUCCESSFUL.
public string textOnButton; // See inspector in Behavior Designer. Is used as text on button.
public Text CommunicationMessage;
public Button CommunicationButton;
bool boolClicked; // Is false; when the button is clicked, it will turn TRUE, calling the IF function, returning Taskstatus SUCCESS.
public override void OnAwake ()
{
CommunicationElements (false);
}
public override void OnStart ()
{
boolClicked = false;
CommunicationElements (false);
CommunicationButton.onClick.AddListener (ButtonClicked);
}
public override TaskStatus OnUpdate ()
{
CommunicationMessage.text = humanInstructionsText;
CommunicationButton.GetComponentInChildren<Text> ().text = textOnButton;
CommunicationElements (true); // The communication elements are VISIBLE on screen.
TriggerStatusCameraView (false);
if (boolClicked == true) { // this IF function is active when the button is clicked. See ButtonClicked () function.
CommunicationElements (false); // Removes the communication elements from screen.
TriggerStatusCameraView (true);
return TaskStatus.Success;
} else {
return TaskStatus.Running;
}
}
// The following function is called when the CommunicationButton is clicked on screen.
void ButtonClicked ()
{
boolClicked = true; // Changes the value to true, so it will trigger the IF function in OnUpdate ();
Debug.Log (messageToConsole); // Sends this message to the console.
}
// The following function can be called upon and turn all UI elements (such as text, buttons or images) ACTIVE or not.
void CommunicationElements (bool activeOrNot)
{
CommunicationButton.gameObject.SetActive (activeOrNot);
CommunicationMessage.gameObject.SetActive (activeOrNot);
}
// The following code will DISABLE camera control if the communication screen is active for the human operator
void TriggerStatusCameraView(bool activeOrNot)
{
GameObject.Find ("FPSController").GetComponent<RigidbodyFirstPersonController_custom> ().enabled = activeOrNot;
}
}
The solution was simple. Thanks for looking into this.
Text CommunicationMessage = GameObject.Find("CrazyMsg").GetComponent<Text>();
Button CommunicationButton = GameObject.Find("MissionButton").GetComponent<Button>();
I'm writing a simple game, like tic tac toe (only mine is bigger). The game play is simple: my turn, check if won, bot's turn, check if won. I have simple UI and API that uses Domain Entites (that's not important now). So when user's moves, API will update the board, will know that next move is bot's move, so will do it and... has to notify UI. Here is my problem.
My question is:
How to notify UI about bot's move? I mean, to keep it simple but stick to the best programming practices.
My first thought was to create an event in GameAPI class. Is that good idea? Today will all new stuff, C# 6, etc.. I'm not sure:/ Right now UI is WinForms, but I would like to use this API in other UIs, like WPF or even mobile. Here is my simplified code of UI:
EDIT: Right now I'm talking about single player game. Both UI and API is a Client. There will be multiplayer through central server in next step, but right now, single player.
public partial class Form1 : Form
{
private GameAPI api;
public Form1()
{
InitializeComponent();
api = new GameAPI();
}
private void boardClick(object sender, EventArgs e)
{
Field field = GetClickedField(e);
MoveResult result = api.MakeMove(clickedColumn);
if (result != null && result.Row >= 0)
{
MessageBox.Show(result.Row + "," + clickedColumn);
if (result.IsConnected)
{
MessageBox.Show("Success!");
}
}
}
}
and API:
public class GameAPI
{
public IGame CurrentGame { get; set; }
public void CreateGame(GameType type)
{
CurrentGame = new SinglePlayerGame();
}
public Result Move(int column)
{
if (CurrentGame == null) return null;
Player player = CurrentGame.GetNextPlayer();
if (player.Type == PlayerType.Human) return CurrentGame.Move(column, player.Id);
}
public Result MoveBot()
{
// Simulate Bot's move...
}
}
My first thought was to create an event in GameAPI class. Is that good idea?
Yes, why not? Let take for example the modern UI frameworks data binding. The key point of making data binging work is providing a property change notification (read - event) when some property value of the object is modified. Usually that's implemented via IPropertyNotifyChanged interface, which is simply a polymorphic way of declaring support for PropertyChanged event. This way, if you set the object property via code, the UI updates automatically. Hope you see the similarity with your case - the API does something and raises an event, UI (being attached handler to that event as some earlier point) receives the event and updates accordingly.