MIF_E31230837/Assets/Script/FlashlightToggle.cs

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