My logic has worked in the past, but it is unclear why this does not work to turn my gameobjects active. This is especially puzzling as I have no errors. The fields match up correctly and I have no errors as mentioned. This is used for an inventory system.
public class addToArtMode : MonoBehaviour
{
public bool On = true;
public GameObject slotPanel;
void Start()
{
this.GetComponent<Button>().onClick.AddListener(() => AddToArtMode());
slotPanel = GameObject.Find("Slot Panel");
}
public void AddToArtMode()
{
if (On)
{
Debug.Log("ID'ing ");
slotPanel = GameObject.Find("Slot Panel");
foreach (Transform child in slotPanel.transform)
{
var parentName = this.GetComponentInParent<ArtBrowseContentInformation>().NameofArt;
var childname = child.GetComponent<InventoryContentInfo>().NameofArt;
if (childname == parentName)
{
child.gameObject.SetActive(true);
On = false;
Debug.Log("what ");
}
else
{
Off();
}
}
void Off()
{
foreach (Transform child in slotPanel.transform)
{
var parentName = this.GetComponentInParent<ArtBrowseContentInformation>().NameofArt;
var childname = child.GetComponent<InventoryContentInfo>().NameofArt;
if (childname == parentName)
{
Debug.Log("the heck");
child.gameObject.SetActive(false);
On = true;
}
}
}
}
}
}
}
try gameObject.enabled = false/true;
Related
I'm trying to make a simple script that saves a text from an input field, like a "remember me" check box. It works fine on the editor. It saves, it logs correctly, it loads fine. But when I build the scene it doesn't work, it's like PlayerPrefs never saves anything. Anyone knows why?
public Toggle rememberMe;
public InputField fieldMail;
public InputField fieldPassword;
private string mail;
private string password;
private int rememberMeChecked = 0;
private bool justChecked = false;
public EventTrigger loginButton;
private void Awake()
{
if (!PlayerPrefs.HasKey("Checked")) { PlayerPrefs.SetInt("Checked", 0); }
if (!PlayerPrefs.HasKey("Mail")) { PlayerPrefs.SetString("Mail", string.Empty); }
if (!PlayerPrefs.HasKey("Password")) { PlayerPrefs.SetString("Password", string.Empty); }
}
private void Start()
{
rememberMeChecked = PlayerPrefs.GetInt("Checked");
mail = PlayerPrefs.GetString("Mail");
password = PlayerPrefs.GetString("Password");
if (!mail.Equals(string.Empty)) { fieldMail.text = mail; }
if (!password.Equals(string.Empty)) { fieldPassword.text = password; }
if (rememberMeChecked == 0) { rememberMe.isOn = false; }
if (rememberMeChecked == 1) { rememberMe.isOn = true; }
justChecked = rememberMe.isOn;
rememberMe.onValueChanged.AddListener(delegate {
justChecked = !justChecked;
if (justChecked) { Save(1); }
else { Save(0); }
LogInfo();
});
}
private void OnEnable()
{
fieldMail.text = mail;
fieldPassword.text = password;
if (rememberMeChecked == 0) { rememberMe.isOn = false; }
if (rememberMeChecked == 1) { rememberMe.isOn = true; }
}
public void OnButtonClicked()
{
PlayerPrefs.Save();
Debug.Log("PlayerPrefs saved.");
LogInfo();
}
public void Save(int rememberMeChecked)
{
switch (rememberMeChecked)
{
case 1:
{
PlayerPrefs.SetString("Mail", fieldMail.text);
PlayerPrefs.SetString("Password", fieldPassword.text);
PlayerPrefs.SetInt("Checked", rememberMeChecked);
}
break;
case 0:
default:
{
PlayerPrefs.SetString("Mail", string.Empty);
PlayerPrefs.SetString("Password", string.Empty);
PlayerPrefs.SetInt("Checked", rememberMeChecked);
}
break;
}
PlayerPrefs.Save();
}
I have a problem seeing the name of the client-side but in my master side names of the player is showing so what I did was like this
public override void OnPlayerEnteredRoom(Player newPlayer)
{
PlayersName();
}
private void PlayersName()
{
if (playerCount == 1)
{
playerNames[0].text = "Kingdom Player 1";
playerNames[1].text = "";
}
else
{
playerNames[0].text = "Kingdom Player 1";
playerNames[1].text = "Kingdom Player 2";
}
}
public override void OnPlayerLeftRoom(Player otherPlayer)
{
PlayersName();
}
Now it displays in both sides the problem is that it is not optimize well. Can someone help me, please?
In the photon, you have to check your current room players.
You have too little change in your code. you can't use directly player count. after change, this code is working properly.
public override void OnPlayerEnteredRoom(Player newPlayer)
{
PlayersName();
}
public void PlayersName()
{
if (PhotonNetwork.CurrentRoom.PlayerCount == 1)
{
playerNames[0].text = "Kingdom Player 1";
playerNames[1].text = "";
}
else
{
playerNames[0].text = "Kingdom Player 1";
playerNames[1].text = "Kingdom Player 2";
}
}
public override void OnPlayerLeftRoom(Player otherPlayer)
{
PlayersName();
}
Now it's working fine in editor and in runtime for each door.
But I want to add a global public flag that will control all the doors at once in editor and in runtime. If I change the global flag to true all the doors will be locked and same if set to false.
The DoorsLockManager script:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[ExecuteInEditMode]
public class DoorsLockManager : MonoBehaviour
{
[HideInInspector]
public List<HoriDoorManager> Doors = new List<HoriDoorManager>();
private void Awake()
{
var doors = GameObject.FindGameObjectsWithTag("Door");
Doors = new HoriDoorManager[doors.Length].ToList();
for (int i = 0; i < doors.Length; i++)
{
Doors[i] = doors[i].GetComponent<HoriDoorManager>();
}
}
}
And the editor script:
using UnityEditor;
using UnityEngine;
[CustomEditor(typeof(DoorsLockManager))]
public class DoorsLockManagerEditor : Editor
{
private SerializedProperty _doors;
private void OnEnable()
{
_doors = serializedObject.FindProperty("Doors");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
for (int i = 0; i < _doors.arraySize; i++)
{
var door = _doors.GetArrayElementAtIndex(i);
// if door == null the script itself has an error since it can't even find the SerializedProperty
if (door == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get door property", target);
return;
}
if (door.objectReferenceValue == null) continue;
// FindPropertyRelative seems not to only work for MonoBehaviour classes
// so we have to use this hack around
var serializedDoor = new SerializedObject(door.objectReferenceValue);
// If it's public no worry anyway
// If it's private still works since we made it a SerializeField
var lockState = serializedDoor.FindProperty("doorLockState");
// Fetch current values into the serialized "copy"
serializedDoor.Update();
if (lockState == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get lockState property", target);
return;
}
// for the PropertyField there is
// no return value since it automatically uses
// the correct drawer for the according property
// and directly changes it's value
EditorGUILayout.PropertyField(lockState, new GUIContent("Door " + i + " Lockstate"));
// or alternatively
//lockState.boolValue = EditorGUILayout.Toggle("Door " + i + " Lockstate", lockState.boolValue);
// Write back changes, mark as dirty if changed
// and add a Undo history entry
serializedDoor.ApplyModifiedProperties();
}
}
}
Well, you could simply add one to the DoorsLockManager
[ExecuteInEditMode]
public class DoorsLockManager : MonoBehaviour
{
[HideInInspector]
public List<HoriDoorManager> Doors = new List<HoriDoorManager>();
// The global state
[SerializeField] private bool _globalLockState;
// During runtime use a property instead
public bool GlobalLockState
{
get { return _globalLockState; }
set
{
_globalLocakState = value;
// apply it to all doors
foreach(var door in Doors)
{
// now you would need it public again
// or use the public property you had there
Door.doorLockState = _globalLocakState;
}
}
}
private void Awake()
{
var doors = GameObject.FindGameObjectsWithTag("Door");
Doors = new HoriDoorManager[doors.Length].ToList();
for (int i = 0; i < doors.Length; i++)
{
Doors[i] = doors[i].GetComponent<HoriDoorManager>();
}
}
}
and in the editor make it "overwrite" all the other flags if changed:
[CustomEditor(typeof(DoorsLockManager))]
public class DoorsLockManagerEditor : Editor
{
private SerializedProperty _doors;
private SerializedProperty _globalLockState;
private bool shouldOverwrite;
private void OnEnable()
{
_doors = serializedObject.FindProperty("Doors");
_globalLockState = serializedObject.FindProperty("_globalLockState");
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
serializedObject.Update();
shouldOverwrite = false;
// Begin a change check here
EditorGUI.BeginChangeCheck();
EditorGUILayout.PropertyField(_globalLockState);
if(EditorGUI.EndChangeCheck())
{
// overwrite only once if changed
shouldOverwrite = true;
}
for (int i = 0; i < _doors.arraySize; i++)
{
var door = _doors.GetArrayElementAtIndex(i);
// if door == null the script itself has an error since it can't even find the SerializedProperty
if (door == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get door property", target);
return;
}
if (door.objectReferenceValue == null) continue;
var serializedDoor = new SerializedObject(door.objectReferenceValue);
var lockState = serializedDoor.FindProperty("doorLockState");
serializedDoor.Update();
if (lockState == null)
{
EditorGUILayout.HelpBox("There was an error in the editor script!\nPlease check the log", MessageType.Error);
Debug.LogError("Couldn't get lockState property", target);
return;
}
// HERE OVERWRITE
if(shouldOverwrite)
{
lockState.boolValue = _globalLockState.boolValue;
}
else
{
EditorGUILayout.PropertyField(lockState, new GUIContent("Door " + i + " Lockstate"));
}
serializedDoor.ApplyModifiedProperties();
}
serializedObject.ApplyModifiedProperties();
}
}
You could create a static class with the flag in it, and then have the door's "activated" state tied to it. Example:
public static class GlobalVariables()
{
public static bool DoorsLocked = true; //Doors would be locked dependent on logic
}
Then you just set the doors' state to the global variable in code. When you change the global bool, the doors change.
GlobalVariables.DoorsLocked = false; //unlocks all doors reading the global bool
Hope this helps!
I'm able to fix the position of the object once it's spawned. But, the object is placed onto different position on every tap on the screen. I want to avoid this problem and want my object to be fixed in a spawned position throughout the Session or Application lifetime.
This is my Deploy Stage Once script:
public class DeployStageOnce : MonoBehaviour
{
public GameObject AnchorStage;
private PositionalDeviceTracker _deviceTracker;
private GameObject _anchorGameObject;
private GameObject _previousAnchor;
public void Start()
{
if (AnchorStage == null)
{
Debug.Log("AnchorStage must be specified");
return;
}
AnchorStage.SetActive(false);
}
public void Awake()
{
VuforiaARController.Instance.RegisterVuforiaStartedCallback(OnVuforiaStarted);
}
public void OnDestroy()
{
VuforiaARController.Instance.UnregisterVuforiaStartedCallback(OnVuforiaStarted);
}
private void OnVuforiaStarted()
{
_deviceTracker = TrackerManager.Instance.GetTracker<PositionalDeviceTracker>();
}
private void AnchorGameObjectSetHitTestPosition(HitTestResult reuslt)
{
_anchorGameObject.transform.position = reuslt.Position;
_anchorGameObject.transform.rotation = reuslt.Rotation;
}
public void OnInteractiveHitTest(HitTestResult result)
{
if (result == null || AnchorStage == null)
{
Debug.LogWarning("Hit test is invalid or AnchorStage not set");
return;
}
var anchor = _deviceTracker.CreatePlaneAnchor(Guid.NewGuid().ToString(), result);
_anchorGameObject = new GameObject();
AnchorGameObjectSetHitTestPosition(result);
if (anchor != null)
{
AnchorStage.transform.parent = _anchorGameObject.transform;
AnchorStage.transform.localPosition = Vector3.zero;
AnchorStage.transform.localRotation = Quaternion.identity;
AnchorStage.SetActive(true);
}
if (_previousAnchor != null)
{
Destroy(_previousAnchor);
}
_previousAnchor = _anchorGameObject;
}
}
Well you can create an isPlaced variable in your script to check if your object is already placed like this:
private bool isPlaced = false;
public void OnInteractiveHitTest(HitTestResult result)
{
if (result == null || AnchorStage == null)
{
Debug.LogWarning("Hit test is invalid or AnchorStage not set");
return;
}
if(!isPlaced)
{
var anchor = _deviceTracker.CreatePlaneAnchor(Guid.NewGuid().ToString(), result);
_anchorGameObject = new GameObject();
AnchorGameObjectSetHitTestPosition(result);
if (anchor != null)
{
AnchorStage.transform.parent = _anchorGameObject.transform;
AnchorStage.transform.localPosition = Vector3.zero;
AnchorStage.transform.localRotation = Quaternion.identity;
AnchorStage.SetActive(true);
}
isPlaced = true;
}
}
I am making my own InputManager to remap keys during the game.
The problem is that I have assigned class to each of shortcut's parent and when the button is pressed on the debugger I can see data from another key.
And only this key keeps being changed over and over again.
Here is my example: Up is the parent of button, UpS is button being pressed which call the method from it's parent. In each parent-children it is set the same way as there.
On button press I call
public void ToggleChangeButtonPannel(Button button)
{
this.ActionText.text = Description;
this.CurrentKeyText.text = Name;
if (Panel.enabled)
{
Panel.enabled = false;
}
else
{
Panel.enabled = true;
}
}
And at update I check if panel is visible. I think the problem might be with the specification of Update() method. Does it work on every instance in parallel?
If that is the case - is it possible to use Input.anyKeyDown outside the Update() method?
private void Update()
{
if (!Panel.enabled)
{
return;
}
if (Input.anyKeyDown)
{
var currentKey = Key;
try
{
var newKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), Input.inputString.ToUpper());
if (Shortcuts.TryChangeKeyCode(currentKey, newKey))
{
RenameButtons(newKey);
}
else
{
//Error message handling
}
}
catch
{
//Error message handling
}
}
}
The problem was as I thought with Update() method. I have fixed it by using caroutine.
public void ToggleChangeButtonPannel(Button button)
{
ActionText.text = Description;
CurrentKeyText.text = Name;
if (Panel.enabled)
{
Panel.enabled = false;
}
else
{
Panel.enabled = true;
StartCoroutine(KeyRoutine());
}
EventSystem.current.SetSelectedGameObject(null);
}
IEnumerator KeyRoutine()
{
while (!Panel.enabled || !Input.anyKeyDown)
{
yield return null;
}
try
{
var newKey = (KeyCode)System.Enum.Parse(typeof(KeyCode), Input.inputString.ToUpper());
if (Shortcuts.TryChangeKeyCode(Key, newKey))
{
RenameButtons(newKey);
Key = newKey;
Panel.enabled = false;
}
else
{
StartCoroutine(RemoveAfterSeconds(3, Panel));
}
}
catch
{
StartCoroutine(RemoveAfterSeconds(3, Panel));
}
}