如何在Unity中使用Android光感传感器

3

我希望在Unity中使用Android上的光传感器。然而,Unity本身并不支持此功能,并且商店中也没有相应的资源或插件可供使用。同时,谷歌对于此问题的解决也不是很友好。


因为我花了一些时间来处理这个问题,而且在网上没有看到任何解决方案。所以我想分享一下,以防止其他人像我一样苦苦挣扎。我选择使用 Stack Overflow 来提高可见性。当我在谷歌上搜索时,我更喜欢 SO 的链接而不是博客的链接。(顺便说一句,我没有博客) - Ice-Blaze
如果这是一个非常具体的问题,我应该加以说明。但事实上,我的问题字面上是“我想在Unity中获取光传感器的值”,除了一个售价45美元的插件外,就没有答案了。所以我给出了我的解决方案。当人们在他们的代码中遇到问题时,他们必须提供尽可能多的信息,但这里并非如此。 - Ice-Blaze
1
我认为这是一个非常有帮助的问题和答案。我以前做过类似的事情,也知道很多人想要做这个,并且这应该能帮到他们。唯一的区别是当传感器值改变时,我使用UnityPlayer.UnitySendMessage来调用一个C#函数。 - Programmer
2个回答

10

简易版

这部分说明如何使用我的代码。

  1. .jar 文件放入 Assets/Plugins/Android 文件夹中。

  2. 然后只需在您想要的 GameObject 上添加脚本 LightSensorPluginScript.cs

  3. 如果您想获取传感器值:

    TextMesh tm;
    LightSensorPluginScript test;
    void Start() {
        tm = transform.GetComponent<TextMesh>();
        test = GetComponent<LightSensorPluginScript> ();
    }
    void Update() { 
        tm.text = test.getLux().ToString();
    }
    
  4. 这个zip归档文件包含所有的文件。

详细版本

这一部分讲解如何创建插件。

首先你需要创建一个Android库。如果你正在使用Android Studio,它们会被转换成.aar文件。像解压缩文件一样解压缩它们,你会发现一个正确的.jar文件classes.jar。你可以按照自己的想法重命名它,Unity不在意。

Android Java 代码

public class LightSensorLib{

    private SensorManager mSensorManager;
    private Sensor mSensorRot;
    private float lux = -1000;

    public void init(Context context) {
        mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
        mSensorRot = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);

        SensorEventListener mySensorEventListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent event) {
                float sensorData[];

                if(event.sensor.getType()== Sensor.TYPE_LIGHT) {
                    sensorData = event.values.clone();
                    lux = sensorData[0];
                }
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {}
        };
        mSensorManager.registerListener(mySensorEventListener, mSensorRot, 500);
    }

    public float getLux () {
        return lux;
    }
}

然后我有一个C#脚本,它在Android Java和Unity之间建立桥梁。

C#桥接代码

public class LightSensorPluginScript : MonoBehaviour {
    private AndroidJavaObject activityContext = null;
    private AndroidJavaObject jo = null;
    AndroidJavaClass activityClass = null;

    void Start () {
        #if UNITY_ANDROID
        activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");

        jo = new AndroidJavaObject("com.etiennefrank.lightsensorlib.LightSensorLib");
        jo.Call("init", activityContext);
        #endif
    }

    public float getLux() {
        #if UNITY_ANDROID
        return jo.Call<float>("getLux");
        #endif
    }
}

现在您可以按照本帖子“简易版”部分所述的操作来使用该传感器。

如果您需要更高精度,我很乐意回答并更新帖子。

对于IOs版本,很抱歉我没有Mac进行开发...所以如果您可以借给我一台,我会很高兴地去做。

我可以将其作为插件添加到资产商店中,但这感觉有点麻烦。因此,我更喜欢将其发布在StackOverflow上,那里的帖子编辑工具非常好用。

最后,希望它能对一些开发人员有所帮助。


-2
using UnityEngine;
using System;
using System.Collections;

public class LightSensorPluginScript : MonoBehaviour {
private AndroidJavaObject activityContext = null;
private AndroidJavaObject jo = null;
AndroidJavaClass activityClass = null;
public TextMesh tm;
LightSensorPluginScript test;


void Start () {
    #if UNITY_ANDROID
    activityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    activityContext = activityClass.GetStatic<AndroidJavaObject>("currentActivity");

    tm = transform.GetComponent<TextMesh>();
    test = GetComponent<LightSensorPluginScript>();




jo = new AndroidJavaObject("com.etiennefrank.lightsensorlib.LightSensorLib");
    jo.Call("init", activityContext);
    #endif
}

public float getLux() {
    #if UNITY_ANDROID
    return jo.Call<float>("getLux");
    #endif
}

void Update()
{

    tm.text = test.getLux().ToString();
}

}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接