UNITY’de Bir Webcam’e Erişerek Onun Görüntüsünü Objeye Texture Olarak Atamak

Yayınlandı: 01 Temmuz 2013 yasirkula tarafından Oyun Tasarımı, UNITY 3D içinde

Merhaba,

Bu derste, Unity’de bir webcam’e (ya da bir kameraya) erişip onun görüntüsünü oyun motoru içinde kullanmayı göstermeye çalıştım. Kodları comment’leyerek neyin ne olduğunu kısaca açıkladım. Zaten tek bir script yeterli; o da oldukça kısa bir script.

NOT: Bu webcam olayı tüm cihazlarda (cep telefonları dahil) çalışıyor ancak eğer webcam kullanan bir Android uygulaması yaparsanız uygulama kurulmadan önce uygulamanın istediği izinler arasında “Hardware controls : take pictures and videos” da gözüküyor.

Kodu görmek için yazının devamını okuyabilirsiniz…

WebcamTest adında yeni bir C# script oluşturup içeriğini aşağıdaki gibi değiştirmeniz ve bu objeyi webcam görüntüsünü hangi objede göstermek istiyorsanız ona component olarak vermeniz yeterli. Bu objede Mesh Renderer gibi bir component olmalı ve objenin z ekseni (mavi eksen), webcam görüntüsünün görünmesini istediğiniz yöne doğru bakmalı.

using System.Collections;
using UnityEngine;

public class WebcamTest : MonoBehaviour
{
	private WebCamTexture webcam;
	private int mevcutWebcam; // Cihazda birden çok webcam varsa aralarında geçiş yapmak için kullanacağımız bir kod
	private WebCamDevice[] webcamCihazlari; // Aygıttaki tüm webcam'leri depolayan bir değişken
	private Quaternion anaRotasyon; // Kameranın ekrana yamuk yumuk açılarla yansımasını engellemek için bir değişken

	IEnumerator Start()
	{
		// Webcam'e erişmek için kullanıcıdan izin istememiz gerekiyor mu kontrol et
		if( !Application.HasUserAuthorization( UserAuthorization.WebCam ) )
		{
			// Kullanıcının izni gerekiyor, izin iste ve bekle
			yield return Application.RequestUserAuthorization( UserAuthorization.WebCam );

			// Kullanıcı izin vermezse script'i objeden kaldır
			if( !Application.HasUserAuthorization( UserAuthorization.WebCam ) )
				Destroy( this );
		}

		webcamCihazlari = WebCamTexture.devices;

		// Eğer cihazda en az 1 tane webcam varsa, 0. indexteki webcam cihazını "webcam" değişkenine ata; eğer webcam yoksa hata mesajı ver
		if( webcamCihazlari.Length != 0 )
		{
			webcam = new WebCamTexture( webcamCihazlari[0].name );
			mevcutWebcam = 0;
		}
		else
		{
			Debug.LogError( "Hata! Cihazda webcam bulunamadı." );

			// Hata mesajının ardından bu scripti objeden kaldır
			Destroy( this );
		}

		// Objeye texture olarak webcam görüntüsünü ata
		GetComponent<Renderer>().material.mainTexture = webcam;

		// Webcam'den veri almaya başla (webcam'i çalıştır)
		webcam.Play();

		anaRotasyon = transform.rotation;
	}

	void Update()
	{
		// Her kameranın kendine has bir çekim açısı olabilir. Bu kod, objeyi kameranın çekim açısına göre otomatik olarak döndürüyor (benim de tam anlamadığım bir şekilde)
		transform.rotation = anaRotasyon * Quaternion.AngleAxis( webcam.videoRotationAngle, Vector3.forward );
	}

	void OnGUI()
	{
		// Webcam'i duraklatmak/devam ettirmek ya da durdurmak için ekranın sol üstüne butonlar ekle
		if( webcam.isPlaying )
		{
			if( GUI.Button( new Rect( 10, 10, 100, 50 ), "DURAKLAT" ) )
				webcam.Pause();

			if( GUI.Button( new Rect( 10, 70, 100, 50 ), "DURDUR" ) )
				webcam.Stop();
		}
		else
		{
			if( GUI.Button( new Rect( 10, 10, 100, 50 ), "OYNAT" ) )
				webcam.Play();
		}

		// Görüntüyü ters çevirmek için butonlar ekle
		if( GUI.Button( new Rect( 10, 150, 100, 50 ), "DİKEY ÇEVİR" ) )
		{
			Vector3 scale = transform.localScale;
			scale.y = -scale.y;
			transform.localScale = scale;
		}

		if( GUI.Button( new Rect( 10, 210, 100, 50 ), "YATAY ÇEVİR" ) )
		{
			Vector3 scale = transform.localScale;
			scale.x = -scale.x;
			transform.localScale = scale;
		}

		// Eğer varsa başka kameralara geçmek için buton ekle
		if( webcamCihazlari.Length > 1 )
		{
			if( GUI.Button( new Rect( 120, 10, 100, 50 ), "KAMERA DEĞİŞ" ) )
				WebcamDegistir( ( mevcutWebcam + 1 ) % webcamCihazlari.Length );
		}

		// Eğer cihazda ön kamera varsa ilk ön kameraya geçiş yapmayı sağlar
		if( GUI.Button( new Rect( 230, 10, 120, 50 ), "ÖN KAMERA" ) )
		{
			for( int i = 0; i < webcamCihazlari.Length; i++ )
			{
				// Eğer bu webcam öne bakıyorsa mevcut kamerayı buna ayarla
				if( webcamCihazlari[i].isFrontFacing )
				{
					WebcamDegistir( i );
					return;
				}
			}
		}

		// Eğer cihazda arka kamera varsa ilk arka kameraya geçiş yapmayı sağlar
		if( GUI.Button( new Rect( 360, 10, 120, 50 ), "ARKA KAMERA" ) )
		{
			for( var i = 0; i < webcamCihazlari.Length; i++ )
			{
				// Eğer bu webcam arkaya bakıyorsa mevcut kamerayı buna ayarla
				if( !webcamCihazlari[i].isFrontFacing )
				{
					WebcamDegistir( i );
					return;
				}
			}
		}
	}

	private void WebcamDegistir( int yeniWebcam )
	{
		// Mevcut webcam'den görüntü almayı bırak
		webcam.Stop();

		// Artık kullanmayacağımız webcam görüntüsünü yok ederek hafızayı boşalt
		Destroy( webcam );

		// Yeni webcam'e geçiş yap
		mevcutWebcam = yeniWebcam;
		webcam = new WebCamTexture( webcamCihazlari[mevcutWebcam].name );
		GetComponent<Renderer>().material.mainTexture = webcam;

		// Yeni webcam'i çalıştır
		webcam.Play();
	}
}
yorum
  1. Mehmet ŞENGÜL dedi ki:

    Merhaba hocam. Kodları bir plane bağladım görüntü alıyorum fakat ön kamerada sağa yatırınca sola sola yatırınca sağa dönüyor. Rotation ayarlarıyla oynadım ama bi sonuç alamadım. Yardımcı olabilir misin?

    • yasirkula dedi ki:

      Derste webcam.videoRotationAngle’dan faydalanıyorum. Eğer bu sizde bir işe yaramadıysa, plane’i elle 90 derece döndürmekten başka bir seçenek olmayabilir.

  2. bunyaminyakut dedi ki:

    hocam hayırlı akşamlar,
    ben bir objenin üzerindeki dokuyu slider ile nasıl kontrol ederek döndürebilirim?
    daha anlaşılır olsun diye şu şekilde örnek vereyim; Duvara tuğla dokusunu ekledim ve duvara tıkladığımda tuğla dokusunu duvar oynamadan istediğim gibi nasıl döndürebilirim.

      • UV Rotation değerini nasıl değiştirebilirim? Ve bunu bir slidere nasıl bağlayabilirim.

      • yasirkula dedi ki:

        Kendi shader’ınızı yazmadan bunu yapmanız mümkün değil diye biliyorum, örnek shader’lar için: https://forum.unity.com/threads/rotation-of-texture-uvs-directly-from-a-shader.150482/

      • çok teşekkür ederim halletmeye çalışırım

      • Properties
        {
        _MainTex(“Texture”, 2D) = “white” {}
        _UvRotation(“UV Rotation”, float) = 0
        }

        SubShader
        {
        Tags { “Queue” = “Transparent” “RenderType” = “Transparent” }
        Blend SrcAlpha OneMinusSrcAlpha
        ZTest on
        ZWrite off

        Pass
        {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag

        #include “UnityCG.cginc”

        struct appdata
        {
        float4 vertex : POSITION;
        float2 uv : TEXCOORD0;
        fixed4 color : COLOR;
        };

        struct v2f
        {
        float4 vertex : SV_POSITION;
        float2 uv : TEXCOORD0;
        fixed4 color : COLOR;
        };

        sampler2D _MainTex;
        float4 _MainTex_ST;
        fixed _UvRotation;

        v2f vert(appdata v)
        {
        v2f o;
        o.vertex = UnityObjectToClipPos(v.vertex);

        fixed cosr = cos(_UvRotation);
        fixed sinr = sin(_UvRotation);
        fixed2x2 uvrotation = fixed2x2(cosr, -sinr, sinr, cosr);

        float2 uv = mul(UNITY_MATRIX_M, v.vertex).xz * _MainTex_ST.xy;
        o.uv = mul(uvrotation, uv);
        o.color = v.color;
        return o;
        }

        fixed4 frag(v2f i) : SV_Target
        {
        fixed4 col = tex2D(_MainTex, i.uv);
        return fixed4(col.rgb, i.color.a);
        }
        ENDCG
        }
        }

        //Bu şekilde shader kullandıktan sonra bunun UV Rotation değerine bir slider ile değişken nasıl yaratabilirim,?

      • yasirkula dedi ki:

        Slider’ın On Value Changed’inde materyal.SetFloat(“_UvRotation”, sliderDegeri); kodunu çağırabilirsiniz.

  3. Furkan emre dedi ki:

    (mevcutWebcam + 1 ) % webcamCihazlari.Length );

    Hocam ben bunu tam anlamadım

    • yasirkula dedi ki:

      mevcutWebcam değişkeni, webcamCihazlari array’inde kaçıncı sıradaki webcam cihazının şu anda aktif olduğunu belirtmekte. Bir sonraki webcam’i çalıştırırken mevcutWebcam’in değerinin, webcamCihazlari’nın sınırları dışına taşmadığından emin olmamız lazım. Koddaki % işareti “bölümden kalan” anlamına geliyor, yani “4 % 3” yazarsak bu 4’ün 3’e bölümünden kalanı döndürür. 4 yerine ne yazarsak yazalım sonuç [0,2] aralığında olur. Yazdığım kodda ise, %’un döndürdüğü değer daima [0,webcamCihazlari.Length-1] aralığında oluyor, yani webcamCihazlari’nın sınırları dahilinde oluyor.

Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Google fotoğrafı

Google hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap /  Değiştir )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.