I have looked at other answers, but it hasnt helped because I did add the object and not the script in the OnClick() box, but it still won't let me access the variable. What's going on?
The object in the box, not the script
The Method I want to access
public void IncreaseStat(string stat, float val)
{
switch (stat)
{
case "Hunger":
gm.juice.hunger += val;
break;
case "Energy":
gm.juice.energy += val;
break;
case "Happiness":
gm.juice.happiness += val;
break;
case "Health":
gm.juice.health += val;
break;
default:
Debug.LogError("INVALID STAT: " + stat);
break;
}
}
Look like Unity not allow you to put function with more than one parameter into the OnClick() event
using UnityEngine;
using UnityEngine.UI;
public class ButtonEventDemo : MonoBehaviour
{
public void FunctionWithNoParams()
{
// This is working fine
}
public void FunctionWithStringParam(string text)
{
// This is working fine
}
public void FunctionWithIntParam(int number)
{
// This is working fine
}
public void FunctionWithButtonParam(Button button)
{
// This is working fine
}
public void FunctionWithTwoParams(int first, int second)
{
// Cannot put this function into OnClick() event
}
}
OnClick() demo
Related
Hello? I'm studying the MIRROR Network Now.
enter image description here
However, I have a problem about getting other player's value. This image explain what I want to do.
enter image description here
I create 3 projects. One is server(local host) and other is Client A , the other is Client B.
Firstly, I wrote code like this :
public class PlayerManager : NetworkBehaviour
{
[SyncVar(hook = nameof(onValueChanged))]
int value = 0;
private void Update()
{
if(isServer && Input.GetKeyDown("x"))
{
Message();
}
}
public override void OnStartServer()
{
Debug.Log("Here is Game Room Scene, Player add Successfully");
}
[Command]
private void Hola()
{
value++;
Debug.Log("Received Hola from the client!");
Debug.Log("Server Value : " + value);
ReplyHola();
}
[TargetRpc]
private void ReplyHola()
{
Debug.Log("Received Hola from Client!");
}
[ClientRpc]
private void Message()
{
Debug.Log("Ping...");
}
[ClientRpc]
private void UpdateValue(int value)
{
this.value = value;
}
private void onValueChanged(int oldValue, int newValue)
{
Debug.Log("New Value Detective :");
Debug.Log("Old Value : " + oldValue);
Debug.Log("New Value : " + newValue);
Debug.Log("Sum Value : " + PlayerStat.Value);
}
}
3 Projects have all same code. I referenced code from this video(https://www.youtube.com/watch?v=8tKFF0RP9Jw).
And, I wrote code about sum client A and B's code like this:
private void SumDatas()
{
foreach(var playerObj in FindObjectsOfType(typeof(GameObject)) as GameObject[])
{
if(gameObject.name == "Player(Clone)")
{
PlayerStat.Value += GameObject.Find("Player(Clone)").transform.GetComponent<PlayerManager>().GetValue();
}
}
}
PlayerStat is a static class and Code is like this:
public static class PlayerStat
{
public static int Value { get; set; }
}
Is there anybody help me?
I solved this problem. I will not delete this question for other people who will have same problem with me.
I add this code at my server project, Client A and B project:
[SyncVar(hook = nameof(onValueChanged))]
int value = 0;
int myValue = 0;
private void Update()
{
myValue = PlayerStat.Value;
}
I'm new to Unity and AR app development, i am trying to create a small app to constantly get current location of the device, but the location is never getting updated no matter how much i try
This is my code
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class GPS1 : MonoBehaviour
{
public static GPS1 Instance { set; get; }
public double lat,lon;
private void Start()
{
Instance=this;
DontDestroyOnLoad(gameObject);
StartCoroutine(StartLocationService());
}
private IEnumerator StartLocationService()
{
if(!Input.location.isEnabledByUser)
{
Debug.Log("User has not enabled the GPS");
yield break;
}
Input.location.Start();
Input.compass.enabled=true;
int maxWait=20;
while(Input.location.status==LocationServiceStatus.Initializing && maxWait > 0)
{
yield return new WaitForSeconds(1);
maxWait--;
}
if (maxWait<=0)
{
Debug.Log("Timed Out");
yield break;
}
if(Input.location.status==LocationServiceStatus.Failed)
{
Debug.Log("Unable to determine");
yield break;
}
lat=Input.location.lastData.latitude;
lon=Input.location.lastData.longitude;
yield break;
}
}
[on play][1]
[1]: https://i.stack.imgur.com/KPqSf.png
Please help me with this if possible i tried everything and it isn't working yet.
Im new in developing so need some help for my game!
On my game I have 2 buttons one is "Play" and other "Level Select"
I stuck at the "Play" button, need to make a script that is always loading the highest level that is unlocked, not current but highest.
Here is the code that im using for level manager
public List<Button> levelButton;
public Sprite lockimage;
public bool delete;
private void Start()
{
int saveIndex = PlayerPrefs.GetInt("SaveIndex");
for (int i = 0; i < levelButton.Count; i++)
{
if (i <= saveIndex)
{
levelButton[i].interactable = true;
}
else
{
levelButton[i].interactable = false;
levelButton[i].GetComponent<Image>().sprite = lockimage;
}
}
}
public void LevelSelect()
{
int level = int.Parse(EventSystem.current.currentSelectedGameObject.name);
SceneManager.LoadScene(level);
}
public void PlayGame()
{
//code here
}
public void ResetGame()
{
PlayerPrefs.SetInt("SaveIndex", 0);
SceneManager.LoadScene(0);
}
public void DontResetGame()
{
SceneManager.LoadScene(0);
}
}
SceneManager.LoadScene(PlayerPrefs.GetInt("SaveIndex"));
edit: adding some info/context.
I realized that you set level buttons interactivity on the start functions based on the int save_index value you get from PlayerPrefs.
From there, I assumed that you could load the level directly using that same value on the PlayGame function.
Do note that the code I wrote will throw an error, if the "SaveIndex" key is not yet on PlayerPrefs
I really need help, when I put Invoke in C#, I have this error:
The local function 'RestartGame' is declared but never used Assembly-CSharp
I really don't know why it is happening, but here is the code:
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
public void EndGame()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
Invoke("RestartGame", restartDelay);
}
void RestartGame ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}
unity manual: For better performance and maintability, use Coroutines instead.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html
Try someting like this:
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
private IEnumerator coroutine;
public void EndGame()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
coroutine = RestartDelayed(restartDelay);
StartCoroutine(coroutine);
}
void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
IEnumerator RestartDelayed(float delay)
{
yield return new WaitForSeconds(delay);
RestartGame();
}
}
}
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
I upvoted flyingchris answer but just to explain your error message, I'm assuming its a yellow warning message, is that you are never calling the method RestartGame() directly anywhere in your code, you are invoking it however. Invoking is typically used for UnityEvents and coroutines are typically used for delaying a method.
I've been having trouble figuring out this error I've been getting. The code works for my other projects, but for some reason it isn't working in this project.
This is the error
NullReferenceException: Object reference not set to an instance of an object LevelManager.AdsLoadlevel (System.String name) (at Assets/Scripts/LevelManager.cs:21) LevelManager.ScoreLevelLoad () (at Assets/Scripts/LevelManager.cs:46) UnityEngine.Events.InvokableCall.Invoke (System.Object[] args) (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:153) UnityEngine.Events.InvokableCallList.Invoke (System.Object[] parameters) (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:634) UnityEngine.Events.UnityEventBase.Invoke (System.Object[] parameters) (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent.cs:769) UnityEngine.Events.UnityEvent.Invoke () (at /Users/builduser/buildslave/unity/build/Runtime/Export/UnityEvent_0.cs:53) UnityEngine.UI.Button.Press () (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:35) UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/UI/Core/Button.cs:44) UnityEngine.EventSystems.ExecuteEvents.Execute (IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:52) UnityEngine.EventSystems.ExecuteEvents.Execute[IPointerClickHandler] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.EventFunction`1 functor) (at /Users/builduser/buildslave/unity/build/Extensions/guisystem/UnityEngine.UI/EventSystem/ExecuteEvents.cs:269) UnityEngine.EventSystems.EventSystem:Update()
this is the code from the LevelManager class
using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class LevelManager : MonoBehaviour {
private AdsManager ads;
// Use this for initialization
void Start () {
ads = GameObject.FindObjectOfType<AdsManager> ();
}
//LEVELMANAGEMENT
public void AdsLoadlevel(string name){
ads.ShowRewardedAd ();
SceneManager.LoadScene(name);
}
public void LoadLevel(string name){
SceneManager.LoadScene(name);
}
//For death
private void LoadLevelDeath(){
SceneManager.LoadScene ("LoseScreen");
}
public void DeathLevel(){
Invoke ("LoadLevelDeath", 2.5f);
}
//Score level management
public void ScoreLevelLoad(){
if (Score.score < 200) {
AdsLoadlevel ("Level1");
}
if (Score.score >= 200 && Score.score < 400) {
AdsLoadlevel ("Level2");
}
if (Score.score >= 400 && Score.score < 600) {
AdsLoadlevel ("Level3");
}
if (Score.score >= 600 && Score.score < 800) {
AdsLoadlevel ("Level4");
}
if (Score.score >= 800 && Score.score < 1000) {
AdsLoadlevel ("Level5");
}
}
}
and this is the code for the AdsManager class
using UnityEngine;
using System.Collections;
using UnityEngine.Advertisements;
public class AdsManager : MonoBehaviour {
public void ShowAd()
{
if (Advertisement.IsReady())
{
Advertisement.Show();
}
}
public void ShowRewardedAd()
{
if (Advertisement.IsReady("rewardedVideo"))
{
var options = new ShowOptions { resultCallback = HandleShowResult };
Advertisement.Show("rewardedVideo", options);
}
}
private void HandleShowResult(ShowResult result)
{
switch (result)
{
case ShowResult.Finished:
Debug.Log("The ad was successfully shown.");
//
// YOUR CODE TO REWARD THE GAMER
// Give coins etc.
break;
case ShowResult.Skipped:
Debug.Log("The ad was skipped before reaching the end.");
break;
case ShowResult.Failed:
Debug.LogError("The ad failed to be shown.");
break;
}
}
}
The error occurs when I press a button to call the ScoreLevelLoad function, and the line it highlights is "ads.ShowRewardedAd()". Also, SOMETIMES a warning pops up saying I'm missing a reference and when I click on that it shows "Unity ads coroutine host". I've been struggling with this for a few days and can't seem to figure it out.
I figured it out, although I do not fully understand why, I assume it has to do with global variable or something, but basically all I needed to do was move what was in the Start function, into the AdsLoadlevel function so it reads like
public void AdsLoadlevel(string name){
ads = GameObject.FindObjectOfType<AdsManager> ();
ads.ShowRewardedAd ();
SceneManager.LoadScene(name);
}
if any one has a more detailed reason for why this is, please comment!