199 lines
5.5 KiB
C#
199 lines
5.5 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
|
|
/// <summary>
|
|
/// Attach ke Button Senter di scene Menu AR.
|
|
/// Button otomatis muncul saat cahaya redup, hilang saat cahaya cukup.
|
|
/// User tetap klik sendiri untuk nyalain/matiin senter.
|
|
/// </summary>
|
|
public class FlashlightToggle : MonoBehaviour
|
|
{
|
|
[Header("Button")]
|
|
public GameObject buttonObject; // assign ButtonSenter object
|
|
public Image iconImage;
|
|
public Sprite iconOn;
|
|
public Sprite iconOff;
|
|
|
|
[Header("Light Sensor Setting")]
|
|
[Tooltip("Threshold cahaya (lux). Di bawah nilai ini button muncul. Agak redup = 100-200 lux")]
|
|
public float lightThreshold = 150f;
|
|
[Tooltip("Seberapa sering cek sensor cahaya (detik)")]
|
|
public float checkInterval = 0.5f;
|
|
|
|
private bool isOn = false;
|
|
private float lastCheckTime = 0f;
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
private AndroidJavaObject cameraManager;
|
|
private string cameraId;
|
|
private AndroidJavaObject sensorManager;
|
|
private AndroidJavaObject lightSensor;
|
|
private LightSensorListener sensorListener;
|
|
#endif
|
|
|
|
public float currentLux = 0f; // bisa dilihat di Inspector saat Play
|
|
|
|
void Start()
|
|
{
|
|
Button btn = GetComponent<Button>();
|
|
if (btn != null) btn.onClick.AddListener(Toggle);
|
|
|
|
// Sembunyikan button di awal
|
|
if (buttonObject != null) buttonObject.SetActive(false);
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
InitFlashlight();
|
|
InitLightSensor();
|
|
#endif
|
|
|
|
UpdateIcon();
|
|
}
|
|
|
|
void Update()
|
|
{
|
|
// Cek sensor setiap checkInterval detik
|
|
if (Time.time - lastCheckTime < checkInterval) return;
|
|
lastCheckTime = Time.time;
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
if (sensorListener != null)
|
|
{
|
|
currentLux = sensorListener.GetLux();
|
|
UpdateButtonVisibility();
|
|
}
|
|
#else
|
|
// Di Editor, simulasi cahaya redup supaya button muncul
|
|
currentLux = 50f;
|
|
UpdateButtonVisibility();
|
|
#endif
|
|
}
|
|
|
|
void UpdateButtonVisibility()
|
|
{
|
|
if (buttonObject == null) return;
|
|
|
|
bool shouldShow = currentLux < lightThreshold;
|
|
|
|
// Kalau button disembunyikan saat senter nyala, matikan dulu
|
|
if (!shouldShow && isOn)
|
|
{
|
|
isOn = false;
|
|
SetFlashlight(false);
|
|
UpdateIcon();
|
|
}
|
|
|
|
buttonObject.SetActive(shouldShow);
|
|
}
|
|
|
|
public void Toggle()
|
|
{
|
|
isOn = !isOn;
|
|
SetFlashlight(isOn);
|
|
UpdateIcon();
|
|
}
|
|
|
|
void SetFlashlight(bool on)
|
|
{
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
try
|
|
{
|
|
if (cameraManager != null && cameraId != null)
|
|
cameraManager.Call("setTorchMode", cameraId, on);
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogError("[Flashlight] Error: " + e.Message);
|
|
}
|
|
#else
|
|
Debug.Log("[Flashlight] Senter " + (on ? "ON" : "OFF") + " (Editor)");
|
|
#endif
|
|
}
|
|
|
|
void UpdateIcon()
|
|
{
|
|
if (iconImage == null) return;
|
|
if (iconOn != null && iconOff != null)
|
|
iconImage.sprite = isOn ? iconOn : iconOff;
|
|
}
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
void InitFlashlight()
|
|
{
|
|
try
|
|
{
|
|
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer")
|
|
.GetStatic<AndroidJavaObject>("currentActivity");
|
|
cameraManager = activity.Call<AndroidJavaObject>("getSystemService", "camera");
|
|
string[] ids = cameraManager.Call<string[]>("getCameraIdList");
|
|
if (ids != null && ids.Length > 0) cameraId = ids[0];
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogError("[Flashlight] Init error: " + e.Message);
|
|
}
|
|
}
|
|
|
|
void InitLightSensor()
|
|
{
|
|
try
|
|
{
|
|
AndroidJavaObject activity = new AndroidJavaClass("com.unity3d.player.UnityPlayer")
|
|
.GetStatic<AndroidJavaObject>("currentActivity");
|
|
sensorManager = activity.Call<AndroidJavaObject>("getSystemService", "sensor");
|
|
lightSensor = sensorManager.Call<AndroidJavaObject>("getDefaultSensor", 5); // TYPE_LIGHT = 5
|
|
sensorListener = new LightSensorListener();
|
|
sensorManager.Call<bool>("registerListener", sensorListener, lightSensor, 3); // SENSOR_DELAY_NORMAL = 3
|
|
}
|
|
catch (System.Exception e)
|
|
{
|
|
Debug.LogError("[LightSensor] Init error: " + e.Message);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void OnDestroy()
|
|
{
|
|
if (isOn) SetFlashlight(false);
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
try
|
|
{
|
|
if (sensorManager != null && sensorListener != null)
|
|
sensorManager.Call("unregisterListener", sensorListener);
|
|
}
|
|
catch { }
|
|
#endif
|
|
}
|
|
|
|
void OnApplicationPause(bool pause)
|
|
{
|
|
if (pause && isOn) SetFlashlight(false);
|
|
}
|
|
}
|
|
|
|
#if UNITY_ANDROID && !UNITY_EDITOR
|
|
/// <summary>
|
|
/// Listener sensor cahaya Android.
|
|
/// </summary>
|
|
public class LightSensorListener : AndroidJavaProxy
|
|
{
|
|
private float lux = 999f; // default tinggi = terang
|
|
|
|
public LightSensorListener() : base("android.hardware.SensorEventListener") { }
|
|
|
|
public void onSensorChanged(AndroidJavaObject sensorEvent)
|
|
{
|
|
try
|
|
{
|
|
float[] values = sensorEvent.Get<float[]>("values");
|
|
if (values != null && values.Length > 0)
|
|
lux = values[0];
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
public void onAccuracyChanged(AndroidJavaObject sensor, int accuracy) { }
|
|
|
|
public float GetLux() => lux;
|
|
}
|
|
#endif |