Anybody knows how to turn On/Off android flashlight using C# only in Unity?
I don't like plugins, and I don't want to make one of my own. Is there a why to make my device switch the flashlight On or Off using pure C#?
I tried to add this script to the main camera, but it just didn't do the trick :(
private bool Active;
private AndroidJavaObject camera1;
void FL_Start()
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
WebCamDevice[] devices = WebCamTexture.devices;
int camID = 0;
camera1 = cameraClass.CallStatic<AndroidJavaObject>("open", camID);
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
Active = true;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnDestroy()
{
FL_Stop();
}
void FL_Stop()
{
if (camera1 != null)
{
camera1.Call("stopPreview");
camera1.Call("release");
Active = false;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnGUI()
{
GUILayout.BeginArea(new Rect(Screen.width * 0.1f, Screen.height * 0.1f, Screen.width * 0.3f, Screen.height * 0.1f));
if (!Active)
{
if (GUILayout.Button("ENABLE FLASHLIGHT"))
FL_Start();
}
else
{
if (GUILayout.Button("DISABLE FLASHLIGHT"))
FL_Stop();
}
GUILayout.EndArea();
}
Newer Samsung phones are very picky about code.
You need to use camera1.Call("startPreview");
as shown below;
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
///FIX/////
camera1.Call("startPreview");
Active = true;
}
You could have a look at the Android plugin source for Camera Capture Kit (https://www.assetstore.unity3d.com/en/#!/content/56673) - I know you said you don't like plugins however with this one the source is availble and lets you see what goes on for you to tweak. With regards to your problem, Not all phones have the Torch functionality so that might be what you should check for for that ? Maybe you sohuld use the referance that unity itself is using ?
AndroidJavaObject camera=null;
AndroidJavaObject cameraParameters=null;
void ToggleAndroidFlashlight()
{
if (camera == null)
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
camera = cameraClass.CallStatic<AndroidJavaObject>("open", 0);
if (camera != null)
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode","torch");
camera.Call("setParameters",cameraParameters);
}
}
else
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
string flashmode = cameraParameters.Call<string>("getFlashMode");
if(flashmode!="torch")
cameraParameters.Call("setFlashMode","torch");
else
cameraParameters.Call("setFlashMode","off");
camera.Call("setParameters",cameraParameters);
}
}
void ReleaseAndroidJavaObjects()
{
if (camera != null)
{
camera.Call("release");
camera = null;
}
}
Related
So I am trying to create this script which changes the color of the sprite when I execute the method OnMouseDown().
The color change should execute every 2 seconds. In this code provided below the colors only change once for some reason.
I have already tried coroutines. But they didn't work for some reason.
Please help thanks,
public bool startstop = false;
SpriteRenderer m_SpriteRenderer;
IEnumerator Changecolor() {
yield return new WaitForSeconds(3);
int random = Random.Range(1, 4);
if (random == 1) {
this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
this.m_SpriteRenderer.color = Color.blue;
} else if (random == 2) {
this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
this.m_SpriteRenderer.color = Color.red;
} else if (random == 3) {
this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
this.m_SpriteRenderer.color = Color.green;
} else {
this.m_SpriteRenderer = this.GetComponent<SpriteRenderer>();
this.m_SpriteRenderer.color = Color.yellow;
}
this.StartCoroutine("Changecolor", 3f);
}
private void OnMouseDown() {
if (this.startstop) {
this.StartCoroutine("Changecolor", 3f);
this.startstop = !this.startstop;
} else {
this.StopCoroutine("Changecolor");
this.startstop = !this.startstop;
}
}
No errors just doesn't work.
Do you have a Collider on the object? A Collider is needed to have the OnMouseDown event fired.
The code principally works, but is far from quality.
- Only call GetComponent() once, then cache the result. This call is very expensive.
- Initially you have to click two times, as the Coroutine will be stopped at the first click.
Here is the code with some improvements:
public bool m_isRunning = false;
public SpriteRenderer m_spriteRenderer;
private void Start() {
m_spriteRenderer = this.GetComponent<SpriteRenderer>();
}
private IEnumerator Changecolor() {
yield return new WaitForSeconds(3);
int random = Random.Range(1, 4);
if (random == 1) {
m_spriteRenderer.color = Color.blue;
} else if (random == 2) {
m_spriteRenderer.color = Color.red;
} else if (random == 3) {
m_spriteRenderer.color = Color.green;
} else {
m_spriteRenderer.color = Color.yellow;
}
this.StartCoroutine("Changecolor", 3f);
}
private void OnMouseDown() {
m_isRunning = !m_isRunning;
if (m_isRunning) {
StartCoroutine("Changecolor", 3f);
} else {
StopCoroutine("Changecolor");
}
}
Note that the second parameter you pass in (3f)
StartCoroutine ("Changecolor", 3f);
does nothing since your Changecolor does not take any arguments ...
I would actually suggest to not use Coroutine here at all but rather InvokeRepeating and CancelInvoke
void Changecolor()
{
// Either in Awake or as lazy initialization
if(!m_SpriteRenderer) m_SpriteRenderer = GetComponent<SpriteRenderer>();
int random = Random.Range(1, 4);
switch(random)
{
case 1:
m_spriteRenderer.color = Color.blue;
break;
case 2:
m_spriteRenderer.color = Color.red;
break;
case 3:
m_spriteRenderer.color = Color.green;
break;
default:
m_spriteRenderer.color = Color.yellow;
break;
}
}
private void OnMouseDown()
{
startstop = !startstop;
if (this.startstop)
{
InvokeRepeating(nameof(Changecolor), 0f, 2f);
}
else
{
CancelInvoke(nameof(Changecolor));
}
}
The code you provided works just fine, and sins you say the color changes only once, I assume you have a collider on the object that has the script attached, the only thing you should change is the continues call to GetComponent<SpriteRenderer> because it is pretty costly and should only be called in either Start or Awake another thing, which isn't major, and there is nothing wrong with it, but it kind of rubs me the wrong way, is the creation of a new coroutine at the end of the old, why not do something like this:
private Coroutine _colorChanger;
private SpriteRenderer _renderer;
void Start() //Can be Awake, whichever you choose
{
_renderer = GetComponent<SpriteRenderer>();
if (_renderer == null)
{
Debug.Log("No sprite found.");
return;
}
//This is performed if OnMouseDown is implemented, if you implement the Update with Input.GetKeyDown, then this can be removed
var collider = GetComponent<Collider>();
if (collider == null)
{
collider = gameObject.AddComponent<BoxCollider>(); //or BoxCollider2D if you are applying the script to the sprite itself.
}
collider.isTrigger = true;
}
private void OnMouseDown() //this can be swapped out for what Saif wrote, a Update method which checks if the button is down, should be GetKeyDown instead of GetKey, having it that way will eliminate the need for a collider/UI element
{
if (_colorChanger == null)
{
_colorChanger = StartCoroutine(ChangeColor(2f));
}
else
{
StopCoroutine(_colorChanger);
_colorChanger = null;
}
}
IEnumerator ChangeColor(float timeoutSec)
{
while (true)
{
yield return new WaitForSeconds(timeoutSec);
int random = Random.Range(1, 5); //Change max from 4 to 5
if (random == 1)
{
_renderer.color = Color.blue;
}
else if (random == 2)
{
_renderer.color = Color.red;
}
else if (random == 3)
{
_renderer.color = Color.green;
}
else
{
_renderer.color = Color.yellow;
}
}
}
Update: just noticed something that others missed, you should change the Random.Range(1, 4) to Random.Range(1, 5) or else the yellow color will never come into effect.
Your code is right, no issues in it except that the OnMouseDown() function will not be called since you are not clicking on any box triggers or any UI elements. Hence try to use update function as given below:
void Update()
{
if (Input.GetKey(KeyCode.Mouse0))
{
if (startstop == false)
{
StartCoroutine("Changecolor", 3f);
this.startstop = !this.startstop;
}
else
{
StopCoroutine("Changecolor");
this.startstop = !this.startstop;
}
}
}
So I'm trying to mute a specific audio source once my death menu pops up ingame. I tried with:
public void toggleEndMenu(float score)
{
GameObject jumpGameObject = GameObject.Find("Jump");
if (jumpGameObject != null)
{
AudioSource jumpAudio = jumpGameObject.GetComponent<AudioSource>();
if (jumpAudio != null)
{
jumpAudio.mute = true;
}
}
gameObject.SetActive(true);
scoreText.text = ((int)score).ToString();
isShown = true;
This did not work the audiosource does not get muted, maybe it cannot find the gameobject or something?
I am trying to draw a line from camera to a instantiated object.I am using the scene UnityARHitTest Example.When I touch on a vertical plane the object gets instantiated and i want to draw a line from camera to the object.When I move my device the line should show from the centre of my camera.For some reason line renderer is not showing when I call it in the Late update.
LineRenderer lins;
public GameObject Lineprefab;
bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes)
{
List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);
if (hitResults.Count > 0 && check==true)
{
foreach (var hitResult in hitResults)
{
Debug.Log ("Got hit!");
if (Select == 0)
{
Debug.Log("hit-zero!");
Instantiate(Instaobj[0], ForSelect);
check = false;
}
if (Select == 1)
{
Debug.Log("hit-one!");
Instantiate(Instaobj[1], ForSelect);
check = false;
}
if (Select == 2)
{
Debug.Log("hit-two!");
Instantiate(Instaobj[2], ForSelect);
check = false;
}
if (Select == 3)
{
Debug.Log("hit-three!");
Instantiate(Instaobj[3], ForSelect);
check = false;
}
if (Select == 4)
{
Debug.Log("hit-four!");
Instantiate(Instaobj[4], ForSelect);
check = false;
}
if (Select == 5)
{
Debug.Log("hit-five!");
Instantiate(Instaobj[5], ForSelect);
check = false;
}
m_HitTransform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
m_HitTransform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));
obj.StopPlaneTracking();
if (GameObject.Find("debugPlanePrefab(Clone)"))
GameObject.Find("debugPlanePrefab(Clone)").SetActive(false);
else
Debug.Log("no prefab");
//lins.SetPosition(0, m_HitTransform.position);
//lins.SetPosition(1, obj.m_camera.transform.position);
return true;
}
}
return false;
}
When I use lins.setposition() in the above method(which is commented) a line is shown in the output.When I use lins.setposition() in the below LateUpdate() the output is not shown nothing comes.
private void Start()
{
spawngenerator();
}
void spawngenerator()
{
GameObject newline = Instantiate(Lineprefab);
lins = newline.GetComponent<LineRenderer>();
//lins.SetPosition(0, m_HitTransform.position);
//lins.SetPosition(1, obj.m_camera.transform.position);
}
private void LateUpdate()
{
lins.SetPosition(0,obj.m_camera.transform.position );
lins.SetPosition(1,m_HitTransform.position );
}
I want to make a Xamarin.iOS app where I can capture pictures like the camera... My app supports only portrait.
I want to turn the captured picture to portrait if the camera was landscape when i capture the picture.
Does someone know how I can do this?
Code
public async void CapturePhoto()
{
var videoConnection = stillImageOutput.ConnectionFromMediaType(AVMediaType.Video);
var sampleBuffer = await stillImageOutput.CaptureStillImageTaskAsync(videoConnection);
var jpegImageAsBytes = AVCaptureStillImageOutput.JpegStillToNSData(sampleBuffer).ToArray();
string base64StringImage = Convert.ToBase64String(jpegImageAsBytes);
FaceRecognition faceRecognition = new FaceRecognition();
int result = faceRecognition.SendPhoto(base64StringImage);
}
Try this :
var currentOrientation = UIApplication.SharedApplication.StatusBarOrientation;
if (currentOrientation == UIInterfaceOrientation.Portrait)
{
videoConnection.VideoOrientation = AVCaptureVideoOrientation.Portrait;
}
else if (currentOrientation == UIInterfaceOrientation.LandscapeRight)
{
videoConnection.VideoOrientation = AVCaptureVideoOrientation.LandscapeRight;
}
//xxx
Update:
If the app only supports an orientation or you lock the screen , there is another old way to detect device orientation. Core Motion
public void LockOrientation()
{
CMMotionManager CMManager = new CMMotionManager();
CMManager.DeviceMotionUpdateInterval = 0.2f;
CMManager.StartDeviceMotionUpdates(NSOperationQueue.MainQueue, (motion, error) => {
if (Math.Abs(motion.Gravity.X) > Math.Abs(motion.Gravity.Y))
{
Console.WriteLine("Lan");
if (motion.Gravity.X > 0)
{
UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.LandscapeLeft), new NSString("orientation"));
Console.WriteLine("Left");
}
else
{
UIDevice.CurrentDevice.SetValueForKey(new NSNumber((int)UIInterfaceOrientation.LandscapeRight), new NSString("orientation"));
Console.WriteLine("Right");
}
}
else
{
if (motion.Gravity.Y >= 0)
{
Console.WriteLine("Down");
}
else
{
Console.WriteLine("UP");
}
}
CMManager.StopDeviceMotionUpdates();
});
}
Refer to here
Anybody knows how to turn On/Off android flashlight using C# only in Unity?
I don't like plugins, and I don't want to make one of my own. Is there a why to make my device switch the flashlight On or Off using pure C#?
I tried to add this script to the main camera, but it just didn't do the trick :(
private bool Active;
private AndroidJavaObject camera1;
void FL_Start()
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
WebCamDevice[] devices = WebCamTexture.devices;
int camID = 0;
camera1 = cameraClass.CallStatic<AndroidJavaObject>("open", camID);
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
Active = true;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnDestroy()
{
FL_Stop();
}
void FL_Stop()
{
if (camera1 != null)
{
camera1.Call("stopPreview");
camera1.Call("release");
Active = false;
}
else
{
Debug.LogError("[CameraParametersAndroid] Camera not available");
}
}
void OnGUI()
{
GUILayout.BeginArea(new Rect(Screen.width * 0.1f, Screen.height * 0.1f, Screen.width * 0.3f, Screen.height * 0.1f));
if (!Active)
{
if (GUILayout.Button("ENABLE FLASHLIGHT"))
FL_Start();
}
else
{
if (GUILayout.Button("DISABLE FLASHLIGHT"))
FL_Stop();
}
GUILayout.EndArea();
}
Newer Samsung phones are very picky about code.
You need to use camera1.Call("startPreview");
as shown below;
if (camera1 != null)
{
AndroidJavaObject cameraParameters = camera1.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode", "torch");
camera1.Call("setParameters", cameraParameters);
///FIX/////
camera1.Call("startPreview");
Active = true;
}
You could have a look at the Android plugin source for Camera Capture Kit (https://www.assetstore.unity3d.com/en/#!/content/56673) - I know you said you don't like plugins however with this one the source is availble and lets you see what goes on for you to tweak. With regards to your problem, Not all phones have the Torch functionality so that might be what you should check for for that ? Maybe you sohuld use the referance that unity itself is using ?
AndroidJavaObject camera=null;
AndroidJavaObject cameraParameters=null;
void ToggleAndroidFlashlight()
{
if (camera == null)
{
AndroidJavaClass cameraClass = new AndroidJavaClass("android.hardware.Camera");
camera = cameraClass.CallStatic<AndroidJavaObject>("open", 0);
if (camera != null)
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
cameraParameters.Call("setFlashMode","torch");
camera.Call("setParameters",cameraParameters);
}
}
else
{
cameraParameters = camera.Call<AndroidJavaObject>("getParameters");
string flashmode = cameraParameters.Call<string>("getFlashMode");
if(flashmode!="torch")
cameraParameters.Call("setFlashMode","torch");
else
cameraParameters.Call("setFlashMode","off");
camera.Call("setParameters",cameraParameters);
}
}
void ReleaseAndroidJavaObjects()
{
if (camera != null)
{
camera.Call("release");
camera = null;
}
}