How can I check internet connection inside Update Function in unity? I want to know whether the user is connected or not, and based on that just disable some functionality of my game.
Seems like there is no question like this been asked here before or if it is, it just checking the connection in Start function. Here is the code I have so far:
void Update () {
if (Application.internetReachability == NetworkReachability.NotReachable) {
Debug.Log ("No internet access");
} else {
Debug.Log ("internet connection");
}
}
#mjwills solution is right and it works OK, but nobody forces you to check connection every single frame of your game. You don't have to do that.
A better solution is to check connection when a button is clicked or when an event happens in your scene.
You need to run your Update function periodically.
http://unitylore.com/articles/timers-in-unity/ could be used for this:
using UnityEngine;
public class Timer : MonoBehaviour
{
public float waitTime = 1f;
float timer;
void Update ()
{
timer += Time.deltaTime;
if (timer > waitTime) {
if (Application.internetReachability == NetworkReachability.NotReachable) {
Debug.Log ("No internet access");
} else {
Debug.Log ("internet connection");
}
timer = 0f;
}
}
}
Unity's Application.internetReachability is not the best solution for internet detection as it was not designed for that purpose (as stated in the docs).
The proper way is to implement a technique called Captive Portal Detection, which is what all the major OS's use for their internet status detection. If implemented correctly, it can even detect when the network is restricted (hotels or airports) as it relies on HTTP requests of known content. Therefore it is far more reliable.
It is not that hard to implement. You need to make an HTTP request to a known "check page", and check whether the right content were returned.
However, if you want a complete, ready-to-use solution, you can check the asset Eazy NetChecker which I created for this purpose. It also has events and a custom editor. It is not free, but it is super cheap!
Related
I'm making a small game for android and currently use a pooling system e.g. for enemies, projectiles etc.
As for now I'm Async loading in levels as you play the game which means no loading scene when venturing into a new zone.
Pool is created when new game is started or old save is loaded. It works fine but leaves one issue! With no loading scenes while playing, there's no time to populate pool other than at the beginning. As player could potentially play all the way though in one sitting, that means all pooled objects needs to be loaded and instantiated.
I realize "Dynamically" filling a pool kinda miss the whole idea of pooling in the first place, but I'm curious what solutions people have come up with. Instantiating enemies at level 1 that won't see use until level 10 seem wasteful.
Cheers :)
To extend on my comments, I made an example which you could implement into your code. The enable, disable and OnLevelFinishedLoading should go somewhere into your Level/SceneManager class.
This should stream in the pooled objects whenever you load a new scene.
void OnEnable()
{
SceneManager.sceneLoaded += OnLevelFinishedLoading;
}
void OnDisable()
{
SceneManager.sceneLoaded -= OnLevelFinishedLoading;
}
void OnLevelFinishedLoading(Scene scene, LoadSceneMode mode)
{
StartCoroutine(StartPoolingNextLevel(yourObjectPooler));
}
private IEnumerator StartPoolingNextLevel(YourObjectPoolerClass yourObjectPooler)
{
for (int i = 0; i < yourObjectPooler.AmountToPool; i++)
{
yourObjectPooler.PoolItem(); // psuedo code
yield return new WaitForEndOfFrame();
}
}
Edit
Okay, so I partially solved the problem by adding a rigid body component to the capsule. I read somewhere that apparently you have to have one in order to move on the server.
Problem 2
The next problem I have is that I can now move a capsule that is spawned by the client fine and the host can move it as well as many times as they like. The problem I am getting now is that when the host spawns a capsule the client cannot move it at all and I get a sort of glitch effect on the client side and the capsule still doesn't move on the host side. Is there a reason why it would only work one way and not the other way around? I thought at first it might have to do with Spawn vs SpawnWithClientAuthority but that doesn't seem to make a difference.
Project Summary
I have a pretty simple multiplayer project, all I want to do is have one player host and the other join as a client. Once they are joined together the two players can spawn a capsule and then when the user clicks on a capsule. They should be able to pick it up and move it around the scene and the other player should be able to see this action. I can get both players to connect to the server and spawn their own capsule and both players can see this. The movement script is done as well. However, it is only transmitted on the host side. When the client picks up the object it does not update on the server.
Problem
I have done a bit of debugging and have found that when I call the command on the client it is not being executed at all through line breaks and simple debug statements.
Code
public void OnInputClicked(InputClickedEventData eventData)
{
Debug.Log("clicked");
if (isLocalPlayer)
{
if (Physics.Raycast(transform.position, direction: transform.forward, hitInfo: out hit, maxDistance: range))
{
Debug.Log("Hit capsule");
objectID = GameObject.Find(hit.transform.name);
objNetId = objectID.GetComponent<NetworkIdentity>();
CmdAssignAuthority(objNetId);
Debug.Log("Cmd done");
}
else
{
//else if the player is releasing the object we want to release authority
if (objNetId != null)
{
CmdAssignAuthority(objNetId);
}
}
}
[Command]
void CmdAssignAuthority(NetworkIdentity target)
{
Debug.Log("inside cmd");
NetworkConnection current = target.clientAuthorityOwner;
if (current != null && current != connectionToClient)
{
target.RemoveClientAuthority(current);
target.AssignClientAuthority(connectionToClient);
}
else
{
if (current != null)
{
target.RemoveClientAuthority(current);
}
if (current == null)
{
target.AssignClientAuthority(connectionToClient);
}
}
}
Question
Am I calling this command correctly? The script is attached to a player prefab and the capsule prefab contains a network id and a network transform. I am pretty new to Unet and this feels like a noob mistake.
I've made a dice app as a project to learn to work with unity (it was so good in my eyes that I put it on the google play store) but when I downloaded it from there, the Start function of at least 2 scripts isn't called and I have no idea whether the other Start functions are being called.
Here you can see 2 of the Start functions that aren't called
void Start()
{
light = light.GetComponent<Light>();
GetComponent<Button>().onClick.AddListener(TaskOnClick);
rawImage = GetComponent<RawImage>();
isLockMode = false;
rawImage.texture = getIconLock(isLockMode);
}
void Start()
{
Screen.fullScreen = false;
Dice.AddDie();
Input.gyro.enabled = true;
GlobalConfig.onShowShadowsChanged += onShadowsEnabledChange;
}
They work when I use Unity Remote on my smartphone and they also work when I just use unity without the remote...
the first script is attached to a UI element and the second script is attached to an empty GameObject called 'App'
It's also even more weird because they used to work but then I switched pc's (but used the same code).
I think something is wrong with the building itself
Found out the problem, the build was generating two files, an .apk and an other .odb or somethingl ike that (might be another extension). I had to untick 'split application binary' in the player settings
I have to convert my pong game from keyboard usage to touch based mechanics. However I am completely stuck trying to figure out Unity's touch mechanics. I have searched through the internet and everyone somehow keeps resolving the issue in ways that are still failing for me. Here is, from everything I have gathered, what I believe should work. This is in my update method so it is constantly checking this.
Touch t;
void Update() {
if (Input.touchCount > 0) {
print("touch seen");
t = Input.GetTouch(0);
}
}
The if statement condition is never met no matter how many times I touch the screen. I am using a lenovo laptop that has a touch screen, maybe it is reading my touches as clicks? I just can't seem to figure it out. If I take away the if statement I get an ArrayIndexOutOfBounds Exception. Any help is extremely appreciated!
Update It is registering as a mouse click, and I can't just allow this because I need multiple touch inputs.
You can use Input.touchSupported to check if touch is supported on your computer. If it returns true, then read from touch with Input.GetTouch(0). If it returns false, then use Input.GetMouseButtonDown to read from the mouse instead. Touch won't work if your computer does not support touch screen. Below is complete code on how to do this:
void Update()
{
if (Input.touchSupported)
{
Debug.Log("TOUCH IS SUPPORTED");
if ((Input.touchCount > 0) && (Input.GetTouch(0).phase == TouchPhase.Began))
{
print("touched screen");
}
}
else
{
Debug.Log("TOUCH IS NOT SUPPORTED");
if (Input.GetMouseButtonDown(0))
{
print("clicked screen");
}
}
}
public Transform OculusPlayerPrefab;
public Transform DefaultPlayerPrefab;
void Start() {
Transform player = OVRDevice.IsHMDPresent() ?
(Transform)Instantiate(OculusPlayerPrefab) :
(Transform)Instantiate(DefaultPlayerPrefab);
player.position = transform.position;
}
This should detect if the oculus rift HMD is connected and instantiate the oculus player prefab, otherwise the default. However, IsHMDPresent() returns false whether the Oculus Rift is connected or not. In the unity/oculus integration package however, OVRMainMenu uses the IsHMDPresent() method with the expected results.
As of (at least) Unity 2018.2, using the Oculus Utilities, the following works:
if (OVRManager.isHMDPresent) {
// headset connected
}
I'll add that you can subscribe to HMDMounted and HMDUnmounted events as well which is somewhat related:
OVRManager.HMDMounted += MyOnHMDMountedFunction();
OVRManager.HMDUnmounted += MyOnHMDUnmountedFunction();
Those will fire when you put on (HMDMounted) and/or take off (HMDUnmounted) your headset.
Unity now has a built-in way to detect this.
http://forum.unity3d.com/threads/simply-detecting-the-oculus-rifts-presence-solved.294089/#post-2368233
Docs: http://docs.unity3d.com/ScriptReference/VR.VRDevice-isPresent.html
Edit: this answer is from 2014 and based on Unity 4. You probably want
to use the other answers.
I found this method to be working best:
Ovr.Hmd.Detect() > 0
Also remember of the the HMDLost/HMDAcquired events, so you don't have to poll this every frame:
bool oculusPresent=false;
void CheckOculusPresence() {
oculusPresent=Ovr.Hmd.Detect() > 0;
}
void Start() {
CheckOculusPresence();
OVRManager.HMDAcquired+=CheckOculusPresence;
OVRManager.HMDLost+=CheckOculusPresence;
}
(oculus SDK 0.4.3/unity3d 4.5.5, OSX/Windows)