How to use JNI in Unity - unity3d

I have a JAR library that i need to use in a Unity project but i have never used JAR before,
i couldn't get JNI to work correctly
here is a simple code which outputs 0 but probably should return the correct hashcode of the java string??
public class test : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
AndroidJNIHelper.debug = true;
using (AndroidJavaObject jc = new
AndroidJavaObject("java.lang.String","test"))
{
int a = jc.CallStatic<int>("hashCode");
Debug.Log(a);
}
}
}

Problem was that i was using the editor after moving to android it worked perfectly .

Related

Unity fungus got red line

I got a problem Having the fungus plugin red line
But in unity editor it works normal.
It is a little problem but i want to fix it.
Can someone help?
I try to check visual studio install for VS 2019 has already got unity plugin.
And I try to use open c# project from unity editor
but it still got the problem
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Fungus;
public class TestVariablefungus : MonoBehaviour
{
public Flowchart flowchart;
public int missioncount = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void setFungusmission(int count)
{
//flowchart.SetBooleanVariable("missioncomplete", true);
missioncount= count;
flowchart.SetIntegerVariable("mission", missioncount);
}
public void setGrabMission(bool IsGrab)
{
flowchart.SetBooleanVariable("grabOnhand", IsGrab);
}
}
I found the problem myself.
That is because I put the project folder under a lot of level of folder.
Make the fungus package cannot catch the function.

Is there a way to automatically disable normal maps for mobile builds in Unity?

I'm trying to build a Unity game for mobile, and I want to know if there is a way to remove normal maps from all materials (Standard shader, built in pipeline) when building for mobile platforms without removing them from other platforms. Using Unity 2021 LTS. I already looked through the Project Settings, and it doesn't seem like there is an easy way to do this.
I ended up finding a solution to my own problem, so I'll post it here just in case anyone else needs it.
Create a file called NormalMapPreprocess.cs with this code, and put it in the Assets/Editor folder, and it will remove the normal maps at build time.
using System.Collections.Generic;
using UnityEditor.Build;
using UnityEditor.Rendering;
using UnityEngine;
using UnityEngine.Rendering;
#if UNITY_ANDROID
public class NormalMapPreprocess : IPreprocessShaders
{
ShaderKeyword m_KeywordNormal;
public NormalMapPreprocess()
{
m_KeywordNormal = new ShaderKeyword("_NORMALMAP");
}
public int callbackOrder { get { return 0; } }
public void OnProcessShader(Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data)
{
for (int i = data.Count - 1; i >= 0; --i)
{
if (data[i].shaderKeywordSet.IsEnabled(m_KeywordNormal))
{
data.RemoveAt(i);
}
}
}
}
#else
public class NormalMapPreprocess {}
#endif
Not sure if this is the best solution, but at least it works.

LocatableCamera (PhotoCapture) on the Hololens 2

I have 2 issues when using PhotoCapture on the Hololens 2, which are probably connected. They did not occur on the Hololens 1.
The only obtainable resolution is 3904x2196
Getting the CameraToWorldMatrix always fails
As can be seen in the docs, this resolution has no framerate associated with it.
My presumption is that the CameraToWorldMatrix is only obtainable for camera profiles with a lower resolution.
How can i change the resolution and get the matrix within Unity?
Minimal Reproducible Example
I am using Unity 2019.2.19f1 and Visual Studio 2019 Community (16.4.5)
Create a new Unity Project following the steps here, except using IL2CPP as the scripting backend instead of .NET
In Player Settings: Capabilities enable InternetClient, InternetClientServer, PrivateNetworkClientServer, Webcam, Microphone and SpatialPerception, in Player Settings: Supported Device Families select Holographic
Create a new empty gameobject and add the following script:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.WebCam;
public class PhotoCaptureController : MonoBehaviour
{
PhotoCapture photoCaptureObject = null;
bool isRunning = false;
void Start()
{
StartCoroutine(StartCameraCapture());
}
private IEnumerator StartCameraCapture()
{
if (!Application.HasUserAuthorization(UserAuthorization.WebCam))
{
yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);
}
if (Application.HasUserAuthorization(UserAuthorization.WebCam))
{
Debug.Log("Creating PhotoCapture");
PhotoCapture.CreateAsync(false, OnPhotoCaptureCreated);
}
else
{
Debug.Log("Webcam Permission not granted");
}
}
private void Update()
{
if (isRunning)
{
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
}
void OnPhotoCaptureCreated(PhotoCapture captureObject)
{
photoCaptureObject = captureObject;
IEnumerable<Resolution> availableResolutions = PhotoCapture.SupportedResolutions;
foreach (var res in availableResolutions)
{
Debug.Log("PhotoCapture Resolution: " + res.width + "x" + res.height);
}
Resolution cameraResolution = availableResolutions.OrderByDescending((res) => res.width * res.height).First();
CameraParameters c = new CameraParameters();
c.hologramOpacity = 0.0f;
c.cameraResolutionWidth = cameraResolution.width;
c.cameraResolutionHeight = cameraResolution.height;
c.pixelFormat = CapturePixelFormat.BGRA32;
captureObject.StartPhotoModeAsync(c, OnPhotoModeStarted);
}
private void OnPhotoModeStarted(PhotoCapture.PhotoCaptureResult result)
{
if (result.success)
{
isRunning = true;
photoCaptureObject.TakePhotoAsync(OnCapturedPhotoToMemory);
}
}
void OnCapturedPhotoToMemory(PhotoCapture.PhotoCaptureResult result, PhotoCaptureFrame frame)
{
if (result.success)
{
if (frame.TryGetCameraToWorldMatrix(out Matrix4x4 cameraToWorldMatrix))
{
Debug.Log("Successfully obtained CameraToWorldMatrix: " + cameraToWorldMatrix.ToString());
}
else
{
Debug.Log("Failed to obtain CameraToWorldMatrix");
}
}
frame.Dispose();
}
}
Change Build Settings:
Build, open VS solution, set build target to ARM64, Debug and deploy to Device
This CameraCapture plugin may work for you. It's a native plugin for Unity. The readme.txt contains information on building it. Basically, you need to build the native plugin variants before trying to open up the Unity sample. If you haven’t built C++/WinRT components, you may need to go through the setup steps here. The SpatialCameraTracker.cs file shows how to receive the camera matrices.
There is minimal support on this but all the code is in the repo

How to debug why Unity freezes?

I am doing a collaboration with my school mates for a school project, but recently when I run Unity it freezes and I can't get it to unfreeze. I have uninstalled and reimported all the assets and my group mates also said that their Unity does not have this problem. I can't find a solution.
The project is being done in 2d. I was testing some logic while this happened to me. I was making a health bar test where it automatically goes down and there's a text box while follows it containing the actual number. Then suddenly the next day Unity decided to quit on me and not run at all.
Update
Code:
public static float fillamount = 1f;
public float period = 1f;
public Image image;
private float time;
public float DoesItDecreaseOverTime = -0.1f;
private float tempnum;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
time += Time.deltaTime;
while (fillamount <100 || fillamount > 0)
{
if (time >= period)
{
fillamount += DoesItDecreaseOverTime;
time = 0;
}
}
tempnum = (fillamount * 100);
image.fillAmount = fillamount;
}
}
After long days of frustration myself, I have found how to debug while unity freezes. I was doing stuff with trees (not the vegetation, the data structure) and for me it was very hard to determine where and what causes stack overflow. The stack overflow freezes unity so I can't see any debug that would have helped me to solve the problem. But now, I found the solution.
SOLUTION
So, I tried using System.Diagnostics.Debug.WriteLine which you should see in the output window of Visual Studio. But that doesn't seem to work with a unity project. Anyways, I started to think a little bit and came up with this class:
using System;
using System.IO;
public class Logger
{
public Logger(string logFilePath)
{
if(!logFilePath.EndsWith(".log"))
logFilePath += ".log";
LogFilePath = logFilePath;
if(!File.Exists(LogFilePath))
File.Create(LogFilePath).Close();
WriteLine("New Session Started");
}
public string LogFilePath { get; private set; }
public void WriteLine(object message)
{
using(StreamWriter writer = new StreamWriter(LogFilePath, true))
writer.WriteLine(DateTime.Now.ToString() + ": " + message.ToString());
}
}
Usage is like this:
Logger logger = new Logger(#"C:\Users\Soogbad\Desktop\MyLog.log");
logger.WriteLine("Hello World");
This creates a log file in which you can see all the logs you made. It works perfect! Even while unity is freezing.
Try to avoid Loops in the update function (unless you fully control the loop), this function is called everyframe so if you perform long tasks in here you might experience framedrop and freezes.
In your case replace the while by a If and revert the conditions.
If you have unity pro you have the Profiler that will tell you what script/function is taking the most cpu time.

Unity trying to load wrong namespace when building for WSA

I have two DLLs with their PDB files loaded into my Unity project. One targets the editor in the "Select platforms for plugin" inspector and is in the folder Assets/Plugins. The other targets WSAPlayer, has UWP selected for the SDK and DotNet for the scripting backend. It is in the folder Assets/Plugins/WSA.
When I attempt to build for Windows Store (SDK: Universal 10, Target device: PC, UWP Build Type: XAML, UWP SDK: Latest installed, and Build and run on: Local Machine) I get the following errors:
Assets\CubeScript.cs(16,48): error CS0246: The type or namespace name 'Win32HidDevice' could not be found (are you missing a using directive or an assembly reference?)
Error building Player because scripts had compiler errors
I would not expect UWP to be able to load Win32HidDevice, nor does my UWP DLL use it, so it must be coming from the other DLL. The app works fine debugging in the editor, and if I also check "Standalone" on the first DLL then I can build and run a standalone app.
What settings do I need to get Unity to ignore the Win32 DLL and use the UWP one when building for WSA?
I do not think it is the script itself, but for completeness here it is:
using UnityEngine;
using Zanzibar;
public class OrbScript : MonoBehaviour
{
public Mat mat;
void Start ()
{
MatManager.Instance.MatConnected += MatConnected;
MatManager.Instance.MatDisconnected += MatDisconnected;
MatManager.Instance.Initialize(Communication.AllSupported);
}
private void MatConnected(Mat mat)
{
Debug.LogFormat("Mat {0}", mat.UniqueName);
this.mat = mat;
}
private void MatDisconnected(Mat mat)
{
this.mat = null;
}
void Update ()
{
if (mat == null)
{
GetComponent<Renderer>().material.color = Color.black;
}
else if (mat.TaggedObjects.Count > 0)
{
GetComponent<Renderer>().material.color = Color.green;
}
else if (mat.Touches.Count > 0)
{
GetComponent<Renderer>().material.color = Color.magenta;
}
else
{
GetComponent<Renderer>().material.color = Color.white;
}
}
}
#Tautvydas-Zilys spotted my problem over on the Unity forums here. I'd been looking in the wrong script, doh! CubeScript.cs contained this line:
var currentMat = orb.mat.Device as Win32HidDevice;
which I needed to replace with these lines:
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
var currentMat = orb.mat.Device as Win32HidDevice;
#elif UNITY_WSA_10_0
var currentMat = orb.mat.Device as UwpDevice;
#endif