I have a problem here with Photon's PUN 2. Sometimes It works, but other times it doesn't. Since the last 2 weeks it isn't working that fine. Before it were better, I joined to the master, and then, to the lobby and It allowed me to list the rooms and join them without any problem. Now, I haven't changed that code that much, I only changed it after the errors started. Now, sometimes it joins a match, but another it doesn't, showing the following error:
JoinRandomRoom failed. Client is not on Master Server or not yet ready to call operations. Wait for callback: OnJoinedLobby or OnConnectedToMaster.
I only have 2 devices to test my online with PUN, but, even if I created a room is not working anymore, it just seems like works randomly. Here's my code if you want to check it:
void Start()
{
PhotonNetwork.ConnectUsingSettings();
}
// Update is called once per frame
void Update()
{
}
public override void OnJoinedLobby()
{
// /* print("Connected to lobby")*/;
}
public override void OnConnectedToMaster()
{
//This shows a popup to let know the player that is connected
//PhotonNetwork.JoinLobby();
base.OnJoinedLobby();
GameObject.Find("IWifi").SetActive(false);
print("Puga");
StatePScript.IsShow = true;
Connected = true;
GameObject.Find("IOk").GetComponent<Image>().color = Color.white;
print("IOKS Value is " + IOKS.Show);
GameObject.Find("StatusText").GetComponent<Text>().text = "Connected!";
GameObject.Find("StatusText").GetComponent<Text>().color = Color.green;
A.Play();
GameObject.Find("StatePanel").GetComponent<Animator>().SetBool("Show", false);
IOKS.Show = false;
GameObject.Find("IOk").GetComponent<Image>().color = new Color(0, 0, 0, 0);
Connected = false;
StatePScript.IsShow = false;
}
I have other photon scripts like this that is the random room code:
using UnityEngine.UI;
using Photon.Pun;
public class RandomBScript : MonoBehaviourPunCallbacks
{
// Use this for initialization
private Button B;
void Start ()
{
B = GetComponent<Button>();
B.onClick.AddListener(Clicker);
}
void Clicker()
{
PhotonNetwork.JoinRandomRoom();
print("Random");
}
public override void OnJoinRandomFailed(short returnCode, string message)
{
base.OnJoinRandomFailed(returnCode, message);
print(message);
}
}
The create room code:
using Photon.Pun;
using Photon.Realtime;
public class CreateRoomS : MonoBehaviourPunCallbacks
{
// Use this for initialization
private Button B;
private InputField IF;
private InputField PlayerField;
public AudioSource A;
void Start ()
{
B = GetComponent<Button>();
PlayerField = GameObject.Find("PlayerInput").GetComponent<InputField>();
IF = GameObject.Find("NameInput").GetComponent<InputField>();
B.onClick.AddListener(Clicker);
}
private void Awake()
{
}
void Clicker()
{
print("Trying To create a room...");
if (IF.text.Length > 0 && IF.text.Length <= 20)
{
int PlayerAmount = Int32.Parse(PlayerField.text);
RoomOptions roompos = new RoomOptions()
{
IsVisible = true, IsOpen = true, MaxPlayers = (byte)PlayerAmount
};
PhotonNetwork.CreateRoom(IF.text, roompos);
print("RoomCreated!");
}
else
{
A.Play();
}
}
public override void OnJoinedRoom()
{
print("We are in a room");
PhotonNetwork.LoadLevel("WaitScene");
}
public override void OnCreateRoomFailed(short returnCode, string message)
{
base.OnCreateRoomFailed(returnCode, message);
}
public override void OnCreatedRoom()
{
base.OnCreatedRoom();
print("We created the room");
}
// Update is called once per frame
public override void OnConnectedToMaster()
{
base.OnConnectedToMaster();
print("Connected to the master");
}
And finally, the list rooms code:
using Photon.Pun;
using Photon.Realtime;
using System.Reflection;
using System;
public class RooManager : MonoBehaviourPunCallbacks
{
// Use this for initialization
public GameObject roomPrefab;
public Sprite Four, Two, Three;
private string RoomName;
private int PlayerAmount;
private int MaxPlayers;
private Image I;
private Vector2 RoomVector;
private bool Lock = false;
public GameObject Content;
private List<RoomInfo> RoomList;
private bool IsntNull = false;
private Dictionary<string, RoomInfo> cachedRoomList;
private Dictionary<string, GameObject> roomListEntries;
private void Awake()
{
GameObject.Find("StatePanel").GetComponent<Animator>().SetBool("Show", true);
cachedRoomList = new Dictionary<string, RoomInfo>();
roomListEntries = new Dictionary<string, GameObject>();
}
void Start ()
{
Content = GameObject.Find("Content").GetComponent<GameObject>();
RoomVector = new Vector2(370, this.transform.position.y);
}
void Rooming()
{
PhotonNetwork.JoinLobby();
}
private void ClearRoomListView()
{
foreach (GameObject entry in roomListEntries.Values)
{
Destroy(entry.gameObject);
}
roomListEntries.Clear();
}
private void UpdateRoomListView()
{
foreach (RoomInfo Item in cachedRoomList.Values)
{
RoomName = Item.Name;
PlayerAmount = Item.PlayerCount;
MaxPlayers = Item.MaxPlayers;
RoomVector.y -= 100;
GameObject RoomPrefab = Instantiate(roomPrefab, RoomVector, transform.rotation) as GameObject;
if (Item.PlayerCount == 0)
{
Destroy(RoomPrefab);
}
print(PhotonNetwork.CurrentLobby.Name);
RoomPrefab.transform.Find("RoomName").GetComponent<Text>().text = RoomName;
RoomPrefab.transform.Find("PlayerInt").GetComponent<Text>().text = PlayerAmount.ToString();
if (Item.PlayerCount == 0)
{
}
if (Item.MaxPlayers == 4)
{
GameObject.Find("IPlayerA").GetComponent<Image>().sprite = Four;
}
else if (Item.MaxPlayers == 2)
{
GameObject.Find("IPlayerA").GetComponent<Image>().sprite = Two;
}
else if (Item.MaxPlayers == 3)
{
GameObject.Find("IPlayerA").GetComponent<Image>().sprite = Three;
}
RoomPrefab.transform.SetParent(Content.transform);
}
}
public override void OnRoomListUpdate(List<RoomInfo> roomList)
{
ClearRoomListView();
UpdateCachedRoomList(roomList);
UpdateRoomListView();
print("Updated");
}
private void UpdateCachedRoomList(List<RoomInfo> roomList)
{
foreach (RoomInfo info in roomList)
{
// Remove room from cached room list if it got closed, became invisible or was marked as removed
if (!info.IsOpen || !info.IsVisible || info.RemovedFromList)
{
if (cachedRoomList.ContainsKey(info.Name))
{
cachedRoomList.Remove(info.Name);
}
continue;
}
// Update cached room info
if (cachedRoomList.ContainsKey(info.Name))
{
cachedRoomList[info.Name] = info;
}
// Add new room info to cache
else
{
cachedRoomList.Add(info.Name, info);
}
}
}
This script instantiates a button for every room in photon's server. If you click one button, you join that room. As I said, sometimes it work and sometimes it doesn't, sometimes it helped to comment the line PhotonNetwork.JoinLobby(), but that means that you wont see the romos. Actually, even with or without the JoinLobby() line, it isn't working that well.
Related
I'm having this problem using Unity's Advertisment. Specifically after watching the video and clicking the X button to close the video, I should give the prize to the player (go to the next level). The problem is that the OnUnityAdsDidFinish function calls if (showResult == ShowResult.Finished) multiple times. What am I doing wrong? how do I call the FindObjectOfType () .LoadNextLevel () function once; ? Thank you in advance
public class UnityAdsInterstitial : MonoBehaviour, IUnityAdsListener
{
private string gameID = "******";
//nome scelto nella DashBoard di Unity
private string interstitialID = "interstitial";
private string myPlacementId = "rewardedVideo";
public int randomHighValue = 30;
private bool TestMode = true;
private bool adsClosed = false;
public Button _button;
private void Awake()
{
_button = GetComponent<Button>();
}
void Start()
{
Debug.Log("Ads start");
_button = GameObject.Find("StartAds").GetComponent<Button>();
_button.interactable = Advertisement.IsReady(myPlacementId);
if (_button) _button.onClick.AddListener(ShowRewardedVideo);
Advertisement.Initialize(gameID, TestMode);
Advertisement.AddListener(this);
if (adsClosed)
{
adsClosed = false;
}
}
public void ShowInterstitial()
{
if (Advertisement.IsReady(interstitialID) )
{
Advertisement.Show(interstitialID);
}
}
public void ShowRewardedVideo()
{
if (Advertisement.IsReady(myPlacementId))
{
Debug.Log("Rewarded video is Ready");
Advertisement.Show(myPlacementId);
}
else
{
Debug.Log("Rewarded video is not ready at the moment! Please try again later!");
}
}
public void HideBanner()
{
Advertisement.Banner.Hide();
}
public void OnUnityAdsReady(string placementdID)
{
if (placementdID == interstitialID)
{
Debug.Log("InterstitialIsReady");
}
if (placementdID == myPlacementId)
{
Debug.Log("RewardedIsReady");
_button.interactable = true;
}
}
public void OnUnityAdsDidFinish(string placementdID, ShowResult showResult)
{
if (showResult == ShowResult.Finished)
{
// Reward the user for watching the ad to completion.
if (!adsClosed)
{
adsClosed = true;
FindObjectOfType<LevelLoader>().LoadNextLevel();
}
}
else if (showResult == ShowResult.Skipped)
{
// Do not reward the user for skipping the ad.
}
else if (showResult == ShowResult.Failed)
{
Debug.LogWarning("The ad did not finish due to an error.");
}
}
public void OnUnityAdsDidError(string message)
{
Debug.Log("OnUnityAdsDidError");
}
public void OnUnityAdsDidStart(string message)
{
Debug.Log("OnUnityAdsDidStart");
}
I would start my investigation by checking the placement id (in case there are more placements)
Checking that the callback is for the proper placement id
if (showResult == ShowResult.Finished && placementId == myPlacementId)
{
// Reward the user for watching the ad to completion.
if (!adsClosed)
{
adsClosed = true;
FindObjectOfType<LevelLoader>().LoadNextLevel();
}
}
The second would be that I only have one active instance of UnityAdsInterstitial. You can check this in debug mode by the reference of the object. If more than one instance starts from somewhere else in your code, then you should just limit to one.
This is the script.. in the starting lines you can see the usage of keycodes. I want to add UI buttons for android. When the user tap on that button it acts as Keycode.A or any Keycode which I want and I don't want to change the script. Any solution ? I am totally beginner I don't understand much of this code so don't want to change it. I got it with the free asset 2D Game Kit in which character ellen moves with pc controls. All I want is to change character controls from pc to ui buttons. Please help if I have to change the script I will get a lot of errors which I can't handle so please help.
using UnityEngine;
using UnityEngine.UIElements;
namespace Gamekit2D
{
public class PlayerInput : InputComponent, IDataPersister
{
public static PlayerInput Instance
{
get { return s_Instance; }
}
protected static PlayerInput s_Instance;
public bool HaveControl { get { return m_HaveControl; } }
public InputButton Pause = new InputButton(KeyCode.Escape, XboxControllerButtons.Menu);
public InputButton Interact = new InputButton(KeyCode.E, XboxControllerButtons.Y);
public InputButton MeleeAttack = new InputButton(KeyCode.K, XboxControllerButtons.X);
public InputButton RangedAttack = new InputButton(KeyCode.O, XboxControllerButtons.B);
public InputButton Jump = new InputButton(KeyCode.Space, XboxControllerButtons.A);
public InputAxis Horizontal = new InputAxis(KeyCode.D, KeyCode.A, XboxControllerAxes.LeftstickHorizontal);
public InputAxis Vertical = new InputAxis(KeyCode.W, KeyCode.S, XboxControllerAxes.LeftstickVertical);
[HideInInspector]
public DataSettings dataSettings;
protected bool m_HaveControl = true;
protected bool m_DebugMenuIsOpen = false;
void Awake ()
{
if (s_Instance == null)
s_Instance = this;
else
throw new UnityException("There cannot be more than one PlayerInput script. The instances are " + s_Instance.name + " and " + name + ".");
}
void OnEnable()
{
if (s_Instance == null)
s_Instance = this;
else if(s_Instance != this)
throw new UnityException("There cannot be more than one PlayerInput script. The instances are " + s_Instance.name + " and " + name + ".");
PersistentDataManager.RegisterPersister(this);
}
void OnDisable()
{
PersistentDataManager.UnregisterPersister(this);
s_Instance = null;
}
protected override void GetInputs(bool fixedUpdateHappened)
{
Pause.Get(fixedUpdateHappened, inputType);
Interact.Get(fixedUpdateHappened, inputType);
MeleeAttack.Get(fixedUpdateHappened, inputType);
RangedAttack.Get(fixedUpdateHappened, inputType);
Jump.Get(fixedUpdateHappened, inputType);
Horizontal.Get(inputType);
Vertical.Get(inputType);
if (Input.GetKeyDown(KeyCode.F12))
{
m_DebugMenuIsOpen = !m_DebugMenuIsOpen;
}
}
public override void GainControl()
{
m_HaveControl = true;
GainControl(Pause);
GainControl(Interact);
GainControl(MeleeAttack);
GainControl(RangedAttack);
GainControl(Jump);
GainControl(Horizontal);
GainControl(Vertical);
}
public override void ReleaseControl(bool resetValues = true)
{
m_HaveControl = false;
ReleaseControl(Pause, resetValues);
ReleaseControl(Interact, resetValues);
ReleaseControl(MeleeAttack, resetValues);
ReleaseControl(RangedAttack, resetValues);
ReleaseControl(Jump, resetValues);
ReleaseControl(Horizontal, resetValues);
ReleaseControl(Vertical, resetValues);
}
public void DisableMeleeAttacking()
{
MeleeAttack.Disable();
}
public void EnableMeleeAttacking()
{
MeleeAttack.Enable();
}
public void DisableRangedAttacking()
{
RangedAttack.Disable();
}
public void EnableRangedAttacking()
{
RangedAttack.Enable();
}
public DataSettings GetDataSettings()
{
return dataSettings;
}
public void SetDataSettings(string dataTag, DataSettings.PersistenceType persistenceType)
{
dataSettings.dataTag = dataTag;
dataSettings.persistenceType = persistenceType;
}
public Data SaveData()
{
return new Data<bool, bool>(MeleeAttack.Enabled, RangedAttack.Enabled);
}
public void LoadData(Data data)
{
Data<bool, bool> playerInputData = (Data<bool, bool>)data;
if (playerInputData.value0)
MeleeAttack.Enable();
else
MeleeAttack.Disable();
if (playerInputData.value1)
RangedAttack.Enable();
else
RangedAttack.Disable();
}
void OnGUI()
{
if (m_DebugMenuIsOpen)
{
const float height = 100;
GUILayout.BeginArea(new Rect(30, Screen.height - height, 200, height));
GUILayout.BeginVertical("box");
GUILayout.Label("Press F12 to close");
bool meleeAttackEnabled = GUILayout.Toggle(MeleeAttack.Enabled, "Enable Melee Attack");
bool rangeAttackEnabled = GUILayout.Toggle(RangedAttack.Enabled, "Enable Range Attack");
if (meleeAttackEnabled != MeleeAttack.Enabled)
{
if (meleeAttackEnabled)
MeleeAttack.Enable();
else
MeleeAttack.Disable();
}
if (rangeAttackEnabled != RangedAttack.Enabled)
{
if (rangeAttackEnabled)
RangedAttack.Enable();
else
RangedAttack.Disable();
}
GUILayout.EndVertical();
GUILayout.EndArea();
}
}
}
}
It's not possible. I rather advice you to directly call the functions you want when the button is pressed.
I have a GameScreenManger that will show or hide a panel based on the game status. I have a AdManager gameObject that holds a script that handles ads. I am able to show the ad, but on onAdclosed if i tried to make a reference of GameScreenManager that holds a script in Admanager Script and call a function when onAdclosed event listeners function, the call is triggering, but the actions are not working. Could some one help me in this?
using UnityEngine;
using GoogleMobileAds.Api;
using System;
public class AdManager : MonoBehaviour
{
public static AdManager instance;
private string appId = "";
private InterstitialAd InterstitialAd;
private string InterstitialAdId = "interstitial_Ad_Id";
private RewardedAd RewardedVideoAd;
private string RewardedVideoAdId = "rewarded_video_ad_Id ";
public GameObject RewardPanel;
public GameScreenManager gameManager;
public bool isRewardedVideo;
private bool RewardedVideoLoaded = false;
public void Awake()
{
if(instance == null)
{
instance = this;
} else
{
Destroy(this);
}
MobileAds.Initialize(initStatus => { });
}
private void Start()
{
RequestInterstitial();
RewardedVideoAd = new RewardedAd(RewardedVideoAdId);
RequestRewardedVideo();
// Called when an ad request has successfully loaded.
this.RewardedVideoAd.OnAdLoaded += HandleRewardedAdLoaded;
// Called when an ad request failed to load.
this.RewardedVideoAd.OnAdFailedToLoad += HandleRewardedAdFailedToLoad;
// Called when an ad is shown.
this.RewardedVideoAd.OnAdOpening += HandleRewardedAdOpening;
// Called when an ad request failed to show.
this.RewardedVideoAd.OnAdFailedToShow += HandleRewardedAdFailedToShow;
// Called when the user should be rewarded for interacting with the ad.
this.RewardedVideoAd.OnUserEarnedReward += HandleUserEarnedReward;
// Called when the ad is closed.
this.RewardedVideoAd.OnAdClosed += HandleRewardedAdClosed;
}
private void Update()
{
if (RewardedVideoLoaded == false)
{
RequestRewardedVideo();
}
}
private void RequestInterstitial()
{
string adUnitId = InterstitialAdId;
// Initialize an InterstitialAd.
this.InterstitialAd = new InterstitialAd(adUnitId);
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
this.InterstitialAd.LoadAd(request);
}
public void ShowInterstitial()
{
if (this.InterstitialAd.IsLoaded())
{
this.InterstitialAd.Show();
}
}
public void RequestRewardedVideo()
{
// Create an empty ad request.
AdRequest request = new AdRequest.Builder().Build();
// Load the interstitial with the request.
this.RewardedVideoAd.LoadAd(request);
if (this.RewardedVideoAd.IsLoaded())
{
isRewardedVideo = true;
RewardedVideoLoaded = true;
} else
{
isRewardedVideo = false;
RewardedVideoLoaded = false;
}
}
public void ShowRewardedVideo()
{
if (this.RewardedVideoAd.IsLoaded())
{
this.RewardedVideoAd.Show();
}
}
public void HandleRewardedAdLoaded(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardedAdLoaded event received");
}
public void HandleRewardedAdFailedToLoad(object sender, AdErrorEventArgs args)
{
MonoBehaviour.print(
"HandleRewardedAdFailedToLoad event received with message: "
+ args.Message);
}
public void HandleRewardedAdOpening(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardedAdOpening event received");
}
public void HandleRewardedAdFailedToShow(object sender, AdErrorEventArgs args)
{
MonoBehaviour.print(
"HandleRewardedAdFailedToShow event received with message: "
+ args.Message);
}
public void HandleRewardedAdClosed(object sender, EventArgs args)
{
MonoBehaviour.print("HandleRewardedAdClosed event received");
Debug.Log("{lo} OnClosed called sender = " + sender);
RequestRewardedVideo();
gameManager.CheckForLives(); //This is not working.
this.RewardPanel.SetActive(true);
}
public void HandleUserEarnedReward(object sender, Reward args)
{
Debug.Log("{lo} Earned a Reward HandleUserEarnedReward called!");
string type = args.Type;
double amount = args.Amount;
this.RewardPanel.SetActive(true);
}
}
GameScreen Script
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class GameScreenManager : MonoBehaviour
{
public GameObject PauseScreen;
public GameObject OutOfLifeScreen;
public GameObject PauseButton;
public GameObject Scoretext;
public GameObject Livesbutton;
public Text MusicText;
public void LoadPause()
{
PauseScreen.SetActive(true);
bool audioPlaying = FindObjectOfType<AudioManager>().audioPlaying;
MusicText.text = audioPlaying ? "MUSIC ON" : "MUSIC OFF";
Time.timeScale = 0f;
}
public void ShowResume()
{
PauseScreen.SetActive(false);
Time.timeScale = 1f;
}
public void ShowMainMenu()
{
Time.timeScale = 1f;
SceneManager.LoadScene("Menu");
}
public void ShowOutOfLives()
{
OutOfLifeScreen.SetActive(true);
PauseButton.SetActive(false);
Time.timeScale = 0f;
}
public void CloseOutOfLives()
{
Debug.Log(" {lo} Entered CloseOutOfLives");
OutOfLifeScreen.SetActive(false);
PauseButton.SetActive(true);
Time.timeScale = 1f;
}
public void TogggleSound()
{
FindObjectOfType<AudioManager>().ToggleMute();
bool audioPlaying = FindObjectOfType<AudioManager>().audioPlaying;
MusicText.text = audioPlaying ? "MUSIC ON" : "MUSIC OFF";
PlayerPrefs.SetInt("audioNeeded", audioPlaying ? 1 : 0);
}
public void Quit()
{
Application.Quit();
}
}
Because the callbacks are coming from a non-main thread, and unity is a single threaded environment, so some unity APIs are inaccessible from non-main threads, for example you can't use GameObject.SetActive or many more component functions except from the main thread, so what you need to do is dispatch the callback to the main thread first, then all statements in your function will execute.
Here's how.
1) A simple dispatcher that executes methods on unity's main thread.
create an empty game object in your scene, and attach this to it.
using System;
using System.Collections.Generic;
/// <summary>
/// Helps dispatch task results to the main thread to be able to operate on unity's API like SetActive, enabled etc...
/// </summary>
public class MainThreadDispatcher : MonoBehaviour
{
Queue<Action> jobs = new Queue<Action>();
static MainThreadDispatcher Instance = null;
private void Awake()
{
Instance = this;
}
private void Update()
{
while (jobs.Count > 0)
{
var next = jobs.Dequeue();
if(next != null)
{
next.Invoke();
}
}
}
/// <summary>
/// Dispatches a function to be executed on unity's main thread to be able to use unity's API.
/// </summary>
/// <param name="newJob"></param>
public static void Dispatch(Action newJob)
{
if (newJob == null)
return;
Instance.jobs.Enqueue(newJob);
}
}
2) Edit your on ad closed callback to dispatch to the main thread.
public void HandleRewardedAdClosed(object sender, EventArgs args)
{
// simply give unity control back.
// you can pick and choose to execute what on main thread,
// but I'm just gonna dispatch the whole block.
MainThreadDispatcher.Dispatch(() =>
{
MonoBehaviour.print("HandleRewardedAdClosed event received");
Debug.Log("{lo} OnClosed called sender = " + sender);
RequestRewardedVideo();
gameManager.CheckForLives();
this.RewardPanel.SetActive(true);
});
}
It seems like you don't have a reference to your object in the second script:
Ad Script
public GameScreenManager gsmanagerRef; //drag and drop on the editor or find it on initialization
then you should be able to call
gsmanagerRef.ShowResume(); //or any other function
Hope this helps!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[ExecuteInEditMode]
public class GameObjectInfo : MonoBehaviour
{
[System.Serializable]
public class GameObjectstInfo
{
public GameObject parent;
public int childrenCount;
public List<Transform> children = new List<Transform>();
}
public string gameObjectsInfo = "";
public string results = "";
public bool addChildren = false;
public GameObjectstInfo[] objectsInfo;
private string previousGameObjectsInfo = "";
// Start is called before the first frame update
void Start()
{
Search();
}
private void Update()
{
if (gameObjectsInfo != "" && gameObjectsInfo != previousGameObjectsInfo)
{
Search();
}
previousGameObjectsInfo = gameObjectsInfo;
Reset();
}
public void Search()
{
if (gameObjectsInfo != "")
{
var foundObjects = FindGameObjectsWithName(gameObjectsInfo);
objectsInfo = new GameObjectstInfo[foundObjects.Length];
if (foundObjects.Length > 0)
{
results = "Found Results";
for (int i = 0; i < foundObjects.Length; i++)
{
objectsInfo[i] = new GameObjectstInfo();
objectsInfo[i].parent = foundObjects[i];
if (addChildren == true)
{
foreach (Transform t in foundObjects[i].GetComponentsInChildren<Transform>(true))
{
objectsInfo[i].childrenCount += 1;
objectsInfo[i].children.Add(t);
}
}
else
{
}
}
}
else
{
results = "No Results";
}
}
}
private void Reset()
{
if (gameObjectsInfo == "")
{
results = "No Results";
objectsInfo = new GameObjectstInfo[0];
}
}
GameObject[] FindGameObjectsWithName(string nameIt)
{
int it = 0;
GameObject[] objArr;
bool b = false;
while (!b)
{
if (GameObject.Find(nameIt))
{
GameObject.Find(nameIt).name = nameIt + it;
it++;
}
else
{
b = true;
}
}
objArr = new GameObject[it];
while (it > 0)
{
it--;
objArr[it] = GameObject.Find(nameIt + it);
objArr[it].name = nameIt;
}
return objArr;
}
}
This is the part where I'm adding or not the children:
if (addChildren == true)
{
foreach (Transform t in foundObjects[i].GetComponentsInChildren<Transform>(true))
{
objectsInfo[i].childrenCount += 1;
objectsInfo[i].children.Add(t);
}
}
else
{
}
But I want to do it also in the Update if the flag addChildren is true and changed to false or false to true make the change and add/remove the children in real time.
Now I need to delete the text in the variable gameObjectsInfo and re type again to make the children changes. But I want that the effect will happen without typing over again. Only when changing the state of the flag addChildren.
If I'm changing the addChildren state re search again with or without the children.
There are ways you can do this by writing your own editor for the class so it'll respond to clicking on the checkbox for that bool, if you are only setting the value of addChildren through code, you can use a property set function, or, the most straight-forward way (if you don't mind waiting until the next frame after changing the value) is to just have an extra bool tracking the previous value:
private bool _lastAddChildren;
public bool addChildren = false;
...
void Start()
{
_lastAddChildren = addChildren;
...
}
private void Update()
{
if ((gameObjectsInfo != "" && gameObjectsInfo != previousGameObjectsInfo)
|| (_lastAddChildren != addChildren))
{
Search();
}
previousGameObjectsInfo = gameObjectsInfo;
_lastAddChildren = addChildren;
Reset();
}
I've looked through this over and over again, I can't seem to figure out what the issue is. After looking it up some common issue where just people added extra braces or just forgetting one but I've looked through it and cant seem to find where I messed up. What is causing this error and why is it happening? It's showing the errors on lines 120 and 105.
using UnityEngine;
using Rocket.Core.Plugins;
using Rocket.Core.Logging;
using Rocket.Unturned.Events;
using Rocket.Unturned.Player;
using System.Collections.Generic;
using Rocket.Unturned;
using System;
using System.Timers;
namespace VipTeleport
{
public class VipTeleport : RocketPlugin
{
public static VipTeleport Instance;
public Vector3 DeathPos;
public UnturnedPlayer movePlayer;
public bool canTeleport = false;
public int timerT = 0;
public List<string> players = new List<string>();
public List<PlayerFinder> playerVars = new List<PlayerFinder>();
public PlayerFinder playerInfo;
public string steamId;
public int[] playerTimer = new int[24];
public int[] playerSteamID = new int[24];
public bool[] playersCanTeleport = new bool[24];
public int index;
protected override void Load()
{
VipTeleport.Instance = this;
//Just console logs for the plugin in RocketApi on unturneds server console
Logger.LogWarning("##################################");
Logger.LogWarning("#Vip Teleport Loaded Sucessfully!#");
Logger.LogWarning("##################################");
Logger.LogWarning("# Version V.1.0 #");
Logger.LogWarning("##################################");
}
protected override void Unload()
{
}
private void FixedUpdate()
{
U.Events.OnPlayerConnected += (UnturnedPlayer player) =>
{
int addTo = Convert.ToInt32(player.CSteamID);
foreach (int f in playerSteamID)
{
if (f == 0)
{
playerSteamID[f] = addTo;
foreach (int i in playerTimer)
{
playerTimer[f] = 0;
break;
}
foreach (bool t in playersCanTeleport)
{
playersCanTeleport[f] = false;
}
break;
}
}
};
//Listener for player Death
UnturnedPlayerEvents.OnPlayerDead += (UnturnedPlayer player, Vector3 Vector3) =>
{
int localSteamID = Convert.ToInt32(player.CSteamID);
foreach (int i in playerSteamID)
{
if (i == localSteamID)
{
index = i;
playerTimer[index] = 120;
break;
}
}
System.Timers.Timer aTimer = new System.Timers.Timer();
aTimer.Elapsed += new ElapsedEventHandler(playerTimeVars);
aTimer.Interval = playerTimer[index];
aTimer.Enabled = true;
if ((playerTimer[index] <= 120) && (playerInfo.timerT > 0))
{
playerInfo.canTeleport = true;
}
else
{
playerInfo.canTeleport = false;
playerInfo.timerT = 0;
}
};
U.Events.OnPlayerDisconnected += (UnturnedPlayer player) =>
{
};
public int indexHolder(int i)
{
return i;
}
public void playerTimeVars(object source, ElapsedEventArgs e)
{
int localIndex = indexHolder(index);
playerTimer[localIndex] = 0;
}
}
}
}
Your last two methods need to be below a curly brace, currently they are inside the FixedUpdate() method.
private void FixedUpdate()
{
...
U.Events.OnPlayerDisconnected += (UnturnedPlayer player) =>
{
};
}
public int indexHolder(int i)
{
return i;
}
public void playerTimeVars(object source, ElapsedEventArgs e)
{
int localIndex = indexHolder(index);
playerTimer[localIndex] = 0;
}
Your FixedUpdate() method hasn't got enough brackets.
The methods public int indexHolder(int i), public void playerTimeVars(object source, ElapsedEventArgs e) are placed inside private void FixedUpdate() method which is the source of this error. Place them outside FixedUpdate and it should fix the error