Unity Gelişmiş Input Sistemi (Mobil Destekli)

Yayınlandı: 19 Temmuz 2017 yasirkula tarafından Oyun Tasarımı, UNITY 3D içinde
Etiketler:, , , , , , , , , , , , , , , ,

GÜNCELLEME (20.03.2018): Asset Store linki eklendi.

Hepinize yeniden merhabalar,

Son zamanlarda Input.GetAxis, Input.GetButton veya Input.GetKey kullanan kodların Android cihazlarda nasıl çalıştırılabileceği ile ilgili çeşitli sorular alıyordum. Ben de bu konuda basit bir çözüm üretmeye çalıştım ve ortaya SimpleInput adını verdiğim sistem çıktı.

SimpleInput sistemi ile UI butonlarına dokunarak, dokunmatik ekranda parmağınızı sürükleyerek, joystick kullanarak, direksiyon çevirerek, belirlediğiniz klavye tuşlarına dokunarak vb. Input fonksiyonlarını simüle edebiliyorsunuz.

Asset Store: https://www.assetstore.unity3d.com/en/#!/content/113033

Alternatif Link: https://github.com/yasirkula/UnitySimpleInput/raw/master/SimpleInput.unitypackage

Detaylar için yazının devamını okuyabilirsiniz…

Sistemin işleyişi çok basit: öncelikle üstteki unitypackage‘ı projenize import ediyorsunuz. Ardından kodlarınızdaki multi-platform olmasını istediğiniz Input fonksiyonlarını aşağıdaki gibi SimpleInput versiyonu ile değiştiriyorsunuz:

  • Input.GetAxis -> SimpleInput.GetAxis
  • Input.GetAxisRaw -> SimpleInput.GetAxisRaw
  • Input.GetButtonDown -> SimpleInput.GetButtonDown
  • Input.GetButton -> SimpleInput.GetButton
  • Input.GetButtonUp -> SimpleInput.GetButtonUp
  • Input.GetMouseButtonDown -> SimpleInput.GetMouseButtonDown
  • Input.GetMouseButton -> SimpleInput.GetMouseButton
  • Input.GetMouseButtonUp -> SimpleInput.GetMouseButtonUp
  • Input.GetKeyDown -> SimpleInput.GetKeyDown
  • Input.GetKey -> SimpleInput.GetKey
  • Input.GetKeyUp -> SimpleInput.GetKeyUp

SimpleInput’ta karşılığı olmayan tek Input fonksiyonu Input.GetKey(string) fonksiyonu. Kodlarınızda bu fonksiyonu kullanıyorsanız o zaman fonksiyonun aldığı string parametreyi, KeyCode türündeki karşılığı ile değiştirmeniz lazım.

Artık geriye, bu input’lara değerlerini verecek olan component’leri/objeleri oyuna eklemek kalıyor. Mesela SimpleInput.GetAxis(“Horizontal”) ve SimpleInput.GetAxis(“Vertical”) fonksiyonlarına değerlerini vermesi için oyuna bir joystick veya d-pad ekleyebilirsiniz.

Paketle birlikte gelen Prefabs klasörünün içerisinde bazı hazır input objeleri bulunmakta: joystick, direksiyon (SteeringWheel), d-pad, yatay yön tuşları (ArrowsHorizontal), dikey yön tuşları (ArrowsVertical) ve 4 yöne yön tuşları (ArrowsAllDirections). Bu objeleri rahatça kişiselleştirebilmeniz için de Sprites klasöründe bir takım hazır görseller bulunmakta. Tabi eğer dilerseniz kendi görsellerinizi de kullanabilirsiniz. Paketle gelen hazır görsellerin hepsinin lisansı CC0 Creative Commons, yani istediğiniz sprite’ları herhangi bir credit vermeden istediğiniz gibi kullanabilirsiniz.

Diyelim ki oyuna joystick eklemek istiyorsunuz. Bu durumda yapmanız gereken şey, Prefabs klasöründeki Joystick prefab’ını sahnenizdeki canvas‘ın içerisine sürükleyip (canvas yoksa oluşturun) ardından joystick’i istediğiniz gibi konumlandırmak. Bundan sonra tek yapmanız gereken, joystick hareket ettikçe hangi axis’lerin değerlerinin değişeceğini belirlemek:

X Axis“e atanmış axis, joystick’i yatayda hareket ettirdikçe değer alırken “Y Axis“e atanmış axis ise joystick’i dikeyde hareket ettirdikçe değerini alır. “Movement Axes” değişkeni joystick’in hangi eksenlerde hareket edebileceğini belirtirken “Movement Area Radius” değişkeni ise joystick’in hareket alanı yarıçapını belirler. “Is Dynamic Joystick” seçeneği seçilirse joystick normalde ekranda gözükmez ancak sadece ekrana bir parmak dokununca, parmağın olduğu noktada belirir; yani konumu dinamik olur. “Dynamic Joystick Movement Area” ise, joystick eğer ki dinamik ise bu joystick’in nerelerde oluşabileceğini belirler. Bu alanın dışına dokunulursa orada joystick oluşmaz. Eğer değeri verilmezse joystick ekranın herhangi bir yerine dokununca oluşabilir.

2 boyutlu bir oyun yapıyorsunuz ve karakterinizin ekrandaki sol ve sağ ok tuşlarına dokundukça hareket etmesini istiyorsunuz diyelim. Bu durumda Prefabs klasöründeki ArrowsHorizontal prefab’ını canvas’ınıza sürükleyebilirsiniz. Bu objenin içerisinde Left (sol) ve Right (sağ) adında iki obje, bu objelerde de “Axis Input UI” isminde bir component bulunmakta. Bu component’i bir UI elemanına atarsanız, o UI elemanına basılı tutulduğu sürece “Axis” değişkeninde belirlenen axis input’unun değeri “Value” olur:

Eğer anlattıklarım birazcık kafanızı karıştırdıysa Example klasöründeki örnek sahneyi açıp oradaki sistemi inceleyebilirsiniz:

Bu örnekte hareket edebilen ve zıplayabilen 2 player var ve ilk player hareket etmek için Horizontal ve Vertical axis’lerini kullanırken ikinci player ise Horizontal2 ve Vertical2 axis’lerini kullanıyor. Zıplamak için ise Jump ve Jump2 button’larını kullanıyorlar. Yani SimpleInput ile, normalde Unity’de var olmayan axis’leri ve button’ları da kullanabiliyorsunuz.

Üstte bahsettiğim component’ler de dahil olmak üzere, plugin ile beraber gelen tüm component’lerden kısaca bahsedecek olursam:

SimpleInput.GetAxis İçin Component’ler

  • AxisInputKeyboard: klavyedeki bir tuşa basılı tuttuğunuz sürece axis’in değerini değiştirir
  • AxisInputMouse: “Mouse X” ve “Mouse Y” input’larını başka axis’lere taşımaya yarar (bkz. neden?)
  • AxisInputUI: bir UI elemanına (mesela Button, Image, Text vs.) basılı tuttuğunuz sürece axis’in değerini değiştirir
  • Dpad: genellikle joystick’lerin solunda gördüğümüz d-pad’leri simüle eder. D-pad’lerde input ya tamamen vardır (-1 veya 1 değerini alır) ya da hiç yoktur (0 değerini alır). Yani 0.5 gibi bir ara değer döndürülmez
  • Joystick: alışageldiğimiz joystick input’u
  • SteeringWheel: ekrandaki bir direksiyonu simüle eder. Direksiyonu sola veya sağa çevirdikçe axis’in değeri değişir
  • Touchpad: atandığı RectTransform‘un üzerinde parmak sürüklenirse, bu sürükleme miktarı kadar axis’in değerini değiştirir; yani ekranda parmağı sürükledikçe axis’e değer verir. Eğer tüm ekranda parmağı sürükleyebilmek istiyorsanız Canvas objesinin kendisine bu component’i verebilirsiniz. Component’teki “Allow Touch Input” değişkeni, touchpad’in dokunmatik ekran desteklemesini sağlarken  “Allowed Mouse Buttons” ise, hangi mouse butonlarının touchpad’de işe yarayacağını belirler.

SimpleInput.GetButton İçin Component’ler

  • ButtonInputKeyboard: klavyedeki bir tuşa basılı tuttuğunuz sürece button’un değerini değiştirir
  • ButtonInputUI: bir UI elemanına basılı tuttuğunuz sürece button’un değerini değiştirir

SimpleInput.GetMouseButton İçin Component’ler

  • MouseButtonInputKeyboard: klavyedeki bir tuşa basılı tuttuğunuz sürece mouse button’un değerini değiştirir
  • MouseButtonInputUI: bir UI elemanına basılı tuttuğunuz sürece mouse button’un değerini değiştirir

SimpleInput.GetKey İçin Component’ler

  • KeyInputKeyboard: klavyedeki bir tuşa basılı tuttuğunuz sürece key’in değerini değiştirir
  • KeyInputUI: bir UI elemanına basılı tuttuğunuz sürece key’in değerini değiştirir

Bu component’ler arasından ButtonInputKeyboard gibilerini oyununuzdaki herhangi bir objeye component olarak verebilirken KeyInputUI gibilerini ise sadece UI objelerine component olarak verebilirsiniz. Joystick, SteeringWheel veya Dpad için ise Prefabs’taki hazır prefab’ları kullanmanızı öneririm.

Eğer ki SimpleInput ile bir klavye tuşuna tıklayınca değil de bir mouse tuşuna tıklayınca bir axis’i simüle etmek gibi bir niyetiniz olursa da o zaman sahnedeki bir objeye AxisInputKeyboard component’i verebilir ve “Key” olarak sol mouse tuşu için Mouse0, sağ mouse tuşu için Mouse1 ve orta mouse tuşu için de Mouse2 değerini verebilirsiniz.

Umarım faydalı olur. Daha sonra görüşmek dileğiyle!

yorum
  1. urhoba dedi ki:

    Hocam merhaba oyunumda parmak yukarı kayınca zıplanmasını aşağı kaydırılınca aşağı doğru hızlanmasını istiyorum. Acaba bunu nasıl yapabilirim. c#i için basit bir örnek yapabilirmisiniz.

    • yasirkula dedi ki:

      Bunun için UI sistemini kullanmanızı öneririm çünkü bu şekilde yazdığınız kod otomatik olarak multi-platform ve multi-touch destekliyor olacak. Örneğin sahnede bir Image objesi oluşturup ona şu kodu atarsanız, parmağınızı veya mouse’u bu objenin üzerinde sürükleyince Debug.Log komutları çalışacak:

      using UnityEngine;
      using UnityEngine.EventSystems;
      
      public class ParmakSwipeKontrol : MonoBehaviour, IDragHandler
      {
      	public float kaydirmaMiktari = 15f;
      
      	public void OnDrag( PointerEventData eventData )
      	{
      		float delta = eventData.position.y - eventData.pressPosition.y;
      		if( delta > kaydirmaMiktari )
      		{
      			eventData.pointerDrag = null;
      			Debug.Log( "yukarı kaydırıldı" );
      		}
      		else if( delta < -kaydirmaMiktari )
      		{
      			eventData.pointerDrag = null;
      			Debug.Log( "aşağı kaydırıldı" );
      		}
      	}
      }
      

      Image objesinin görünmez olmasını isterseniz Color değerinin ‘A’sını 0 yapabilirsiniz. Ayrıca bu fikir vasıtasıyla, Gelişmiş Input Sistemi’me parmak sürükleme tespit eden bir modül eklemeyi düşünüyorum. Fikir için teşekkürler.

  2. müçtehit dedi ki:

    Hocam dediklerinizi yaptım ancak topu hareket bir türlü ettiremedim normal yön tuşları ile hareket ettirebiliyorum fakat touchpad ile olmuyor joystick örnekleriniz direksiyon packleri vs hepsi var bi touchpad yok 🙂 keşke oda hazır örneklerde olsaydı bakıp rahatça anlardım şimdi yaptıklarım şunlar Touchpad scriptini topun içine atıyorum sensivity 1 yapıyorum Allow Mouse Input seçenegini işaretliyorum fakat value deger çevirmiyor bir Türlü kafama göre scripte oynamalar yaptım bir sizce bakarsanız sevinirim saygılar 🙂

    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;

    namespace SimpleInputNamespace

    {

    public class Touchpad : MonoBehaviour
    {

    public enum MouseButton { Left = 0, Right = 1, Middle = 2 }
    public float speed=10;
    private Rigidbody rb;

    public Touch touch;

    public SimpleInput.AxisInput xAxis = new SimpleInput.AxisInput( “Horizontal” );
    public SimpleInput.AxisInput yAxis = new SimpleInput.AxisInput( “Vertical” );

    private RectTransform rectTransform;

    public float sensitivity = 1f;

    [Tooltip( “Should touchpad allow touch inputs on touchscreens, or mouse input only” )]
    public bool allowTouchInput = true;

    [Tooltip( “Valid mouse buttons that can register input through this touchpad” )]
    public MouseButton[] allowedMouseButtons;

    [Tooltip( “Should a touch on a UI element be considered valid” )]
    public bool ignoreUIElements = false;

    private float resolutionMultiplier;
    private int fingerId = -1;

    private Vector2 prevMouseInputPos;
    private bool trackMouseInput = false;

    private Vector2 m_value = Vector2.zero;
    public Vector2 Value { get { return m_value; } }

    void Start()
    {

    rb = GetComponent();
    }
    void FixedUpdate()
    {

    float xAxis = SimpleInput.GetAxis(“Horizontal”);
    float yAxis = SimpleInput.GetAxis(“Vertical”);
    Vector3 movement = new Vector3(xAxis, 0.0f, -yAxis);
    rb.AddForce(movement * speed);
    }
    void Awake()
    {
    rectTransform = transform as RectTransform;
    resolutionMultiplier = 100f / ( Screen.width + Screen.height );

    Graphic graphic = GetComponent();
    if( graphic != null )
    graphic.raycastTarget = false;
    }

    void OnEnable()
    {
    xAxis.StartTracking();
    yAxis.StartTracking();

    SimpleInput.OnUpdate += OnUpdate;
    }

    void OnDisable()
    {
    xAxis.StopTracking();
    yAxis.StopTracking();

    SimpleInput.OnUpdate -= OnUpdate;
    }

    void OnUpdate()
    {
    EventSystem eventSystem = EventSystem.current;

    m_value.Set( 0f, 0f );

    if( allowTouchInput && Input.touchCount > 0 )
    {
    for( int i = 0; i < Input.touchCount; i++ )
    {
    Touch touch = Input.GetTouch( i );
    if( fingerId == -1 )
    {
    if( touch.phase == TouchPhase.Began &&
    ( rectTransform == null || RectTransformUtility.RectangleContainsScreenPoint( rectTransform, touch.position ) ) &&
    ( ignoreUIElements || eventSystem == null || !eventSystem.IsPointerOverGameObject( touch.fingerId ) ) )
    {
    fingerId = touch.fingerId;
    break;
    }
    }
    else if( touch.fingerId == fingerId )
    {
    m_value = touch.deltaPosition * resolutionMultiplier * sensitivity;

    if( touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled )
    fingerId = -1;

    break;
    }
    }
    }
    else
    {
    if( GetMouseButtonDown() )
    {
    Vector2 mousePos = Input.mousePosition;

    if( ( rectTransform == null || RectTransformUtility.RectangleContainsScreenPoint( rectTransform, mousePos ) ) &&
    ( ignoreUIElements || eventSystem == null || !eventSystem.IsPointerOverGameObject() ) )
    {
    trackMouseInput = true;
    prevMouseInputPos = Input.mousePosition;
    }
    else
    trackMouseInput = false;
    }
    else if( trackMouseInput && GetMouseButton() )
    {
    Vector2 mousePos = Input.mousePosition;
    m_value = ( mousePos – prevMouseInputPos ) * resolutionMultiplier * sensitivity;
    prevMouseInputPos = mousePos;
    }
    }

    xAxis.value = m_value.x;
    yAxis.value = m_value.y;
    }

    private bool GetMouseButtonDown()
    {
    for( int i = 0; i < allowedMouseButtons.Length; i++ )
    {
    if( Input.GetMouseButtonDown( (int) allowedMouseButtons[i] ) )
    return true;
    }

    return false;
    }

    private bool GetMouseButton()
    {
    for( int i = 0; i < allowedMouseButtons.Length; i++ )
    {
    if( Input.GetMouseButtonDown( (int) allowedMouseButtons[i] ) )
    return true;
    }

    return false;
    }
    }
    }

    • yasirkula dedi ki:

      Touchpad’in kaynak kodunu değiştirmenize gerek yok, siz sadece touchpad olmasını istediğiniz RectTransform objesine Touchpad component’i verin. Inspector’dan “X Axis”i “Horizontal”, “Y Axis”i “Vertical” yapın ve touchpad’in mouse ile de kontrol edilebilmesini istiyorsanız, “Allowed Mouse Inputs” array’ine, hangi mouse tuşları basılı iken bu touchpad ile etkileşime girilebileceğini girin (mesela sol mouse tuşu için listeye Left’i ekleyebilirsiniz):

      Artık kendi yazdığınız herhangi bir scriptteki SimpleInput.GetAxis(“Horizontal”) ve SimpleInput.GetAxis(“Vertical”) komutları touchpad’den input almalı.

      • müçtehit dedi ki:

        Dediklerinizi bir bir yapıyorum ama olmuyor hocam touchpad olmasını istedigim objenin içine atıyorum ve o objenin içinde hareket kodlarıda var ama touch pad hiçbir işe yaramıyor yinede saolun .

      • yasirkula dedi ki:

        Bugün kontrol ettiğimde touchpad’in mouse kodunda “masumane” bir hata olduğunu gördüm 🙂 137. satırı Input.GetMouseButton olarak değiştirince hatanın düzelmesi lazım. Tespitiniz için teşekkürler.

  3. Murat Aksoy dedi ki:

    Hocam bunu görmeden önce biraz kurcaladım ve düzelttim hatamı buldum Edit>Input sekmesinde mouse X ve Y yerlerinde ki movement ayarı mouseda kalmış onu joysticke çektim düzeldi. Çok çok çok çok teşekkür ederim. Allah razı olsun sizden 🙂

  4. Murat Aksoy dedi ki:

    public Transform playerBody;
    public float mouseSensitivity;

    float xAxisClamp = 0.0f;

    void Awake()
    {
    Cursor.lockState = CursorLockMode.Locked;
    }

    void Update()
    {
    RotateCamera();
    }

    void RotateCamera()
    {
    float mouseX = SimpleInput.GetAxis(“Mouse X”);
    float mouseY = SimpleInput.GetAxis(“Mouse Y”);

    float rotAmountX = mouseX * mouseSensitivity;
    float rotAmountY = mouseY * mouseSensitivity;

    xAxisClamp -= rotAmountY;

    Vector3 targetRotCam = transform.rotation.eulerAngles;
    Vector3 targetRotBody = playerBody.rotation.eulerAngles;

    targetRotCam.x -= rotAmountY;
    targetRotCam.z = 0;
    targetRotBody.y += rotAmountX;

    if (xAxisClamp > 90)
    {
    xAxisClamp = 90;
    targetRotCam.x = 90;
    }
    else if (xAxisClamp < -90)
    {
    xAxisClamp = -90;
    targetRotCam.x = 270;
    }

    print(mouseY);

    transform.rotation = Quaternion.Euler(targetRotCam);
    playerBody.rotation = Quaternion.Euler(targetRotBody);

    }
    }

    Merhaba hocam benim internet yardımı ile yazdığım bir kod örneği bu karakterin kamerasının sağa sola dönmesi için mouse ile fakat ben joystick için yapmak istedim sizin bu yazınızı buldum sonrasın da joystick tuttum canvas oluşturup bir joystick oluşturup thomp ile falan yerleştirdim çok güzel oldu fakat şöyle bir sorun var ben mobile build aldığım da joystick dışında ekranın neresine dokunursam dokunayım kamera oraya dönüyor direk ve joystick neredeyse işlevsiz hale geliyor bu neden olabilir ? Yardımcı olabilir misiniz lütfen rica ediyorum

    • yasirkula dedi ki:

      Hmm evet bu gözümden kaçan bir nokta olmuş. “Mouse X” ve “Mouse Y” axis’lerini Unity Android’de direkt Input.GetAxis olarak da destekliyor sanırım (parmağı ekranda sürükledikçe). SimpleInput da Input’u desteklediği için böyle bir sıkıntı oluyor. Bunun için şöyle bir component yazdım:

      using UnityEngine;
      
      namespace SimpleInputNamespace
      {
      	public class AxisInputMouse : MonoBehaviour
      	{
      		public SimpleInput.AxisInput xAxis = new SimpleInput.AxisInput();
      		public SimpleInput.AxisInput yAxis = new SimpleInput.AxisInput();
      
      #if UNITY_EDITOR || UNITY_STANDALONE || UNITY_WEBGL || UNITY_FACEBOOK || UNITY_WSA || UNITY_WSA_10_0
      		void OnEnable()
      		{
      			xAxis.StartTracking();
      			yAxis.StartTracking();
      
      			SimpleInput.OnUpdate += OnUpdate;
      		}
      
      		void OnDisable()
      		{
      			xAxis.StopTracking();
      			yAxis.StopTracking();
      
      			SimpleInput.OnUpdate -= OnUpdate;
      		}
      
      		void OnUpdate()
      		{
      			xAxis.value = Input.GetAxisRaw( "Mouse X" );
      			yAxis.value = Input.GetAxisRaw( "Mouse Y" );
      		}
      #endif
      	}
      }
      

      Bu component, mouse’tan alınan Mouse X ve Mouse Y input’larını düzgün bir şekilde başka 2 axis’e aktarıyor. Bu component’i sahnenizdeki bir objenize verip X Axis’ine değer olarak diyelim ki “Imlec X”, Y Axis’ine değer olarak da “Imlec Y” verip kodunuzu da SimpleInput.GetAxis( “Imlec X” ) ve SimpleInput.GetAxis( “Imlec Y” ) olarak değiştirin. Son olarak, joystick’in axis’lerini de “Imlec X” ve “Imlec Y” olarak güncelleyince sorunun ortadan kalkması lazım.

      • Murat Aksoy dedi ki:

        Denicem hocam şimdi gördüm umarım başarılı olur. Deneyip hemen dönücem tekrardan buraya hocam çok çok teşekkür ederim şimdiden

      • Murat Aksoy dedi ki:

        ArgumentNullException: Argument cannot be null.
        Parameter name: key
        System.Collections.Generic.Dictionary`2[System.String,SimpleInput+Axis].TryGetValue (System.String key, .Axis& value) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:588)
        SimpleInput.UnregisterAxis (.AxisInput input) (at Assets/Plugins/SimpleInput/Scripts/SimpleInput.cs:356)
        SimpleInput+AxisInput.StopTracking () (at Assets/Plugins/SimpleInput/Scripts/SimpleInput.cs:93)
        SimpleInputNamespace.AxisInputMouse.OnDisable () (at Assets/Script/AxisInputMouse.cs:23)

        Böyle bir hata aldım hocam ve öncesinde de
        public SimpleInput.AxisInput xAxis = new SimpleInput.AxisInput();
        public SimpleInput.AxisInput yAxis = new SimpleInput.AxisInput();

        sonda ki new SimpleInput.AxisInput();

        satıları hata verdi visual studio ile düzeltme yaptım hatayı anlamadığım için hata kalktı sonra ınput girdilerini Imlec X ve Imlec Y ile değiştirdim kodu bir gameobjecte attım joystick teki ve kendi kodum da ki Mouse X/Y satırlarını Imlec ile değiştirdim. Neyi yanlış yapmış olabilirim.

      • yasirkula dedi ki:

        Henüz birkaç gün önce asset’i güncellemiştim, o yüzden size verdiğim kod eski sürümde çalışmıyor sanırım. Eski sürüm için, koddaki xAxis ve yAxis değişkenlerini silip yerine şunları ekleyin:

        [SerializeField]
        private string xAxis;
        [SerializeField]
        private string yAxis;
        
        private SimpleInput.AxisInput xInput = null;
        private SimpleInput.AxisInput yInput = null;
        

        Ardından koda şu fonksiyonu ekleyin:

        void Awake()
        {
        	if( xAxis != null && xAxis.Length > 0 )
        		xInput = new SimpleInput.AxisInput( xAxis );
        
        	if( yAxis != null && yAxis.Length > 0 )
        		yInput = new SimpleInput.AxisInput( yAxis );
        }
        

        Bir de OnUpdate’i şöyle güncellediniz mi tamamdır:

        void OnUpdate()
        {
        	if( xInput != null )
        		xInput.value = Input.GetAxisRaw( "Mouse X" );
        	
        	if( yInput != null )
        		yInput.value = Input.GetAxisRaw( "Mouse Y" );
        }
        
  5. Ahmet Akel dedi ki:

    Yasir abi, butona tıklayınca örneğin “w” tuşuna basmış gibi yapmasını nasıl yaparım. Teşekkürler

    • yasirkula dedi ki:

      Öncelikle Input.GetKey fonksiyonu kullanıyorsanız onu SimpleInput.GetKey ile değiştirmeniz lazım. Ardından buton objesine KeyInputUI component’i verip Key değişkenine değer olarak W tuşunu vermeniz lazım.

  6. Murat Aksoy dedi ki:

    Merhaba hocam joystickler de yerleştirdim editor için de bir sıkıntı çıkarmıyor fakat androide build run yapıp açtıgım da joysticlere dokunduğum da sürekli kamerayı bir noktaya sabitliyor sonra hareket ettirebiliyorum kısaca joysticke dokkundugum da kamera yukarıya kayıyor sonra hareket ediyor bunu nasıl çözebilirim

    • asdf dedi ki:

      kamerayı direk hareket ettirdiğiniz objenin child objesi olarak ayarladıysanız hareket ettirdiğiniz objenin her hareketi kameraya yansıyacaktır
      onun yerine kameraya şöyle bi kod yazabilirsiniz diyelimki objeniz hem yukarı hem sag sol gidiyor

      public transform hedefobje;
      void Update(){
      gameobject.transform.position=new vector3(hedefobje.position.z,hedefobje.position.y,transform.position.z)
      }

      eger oyununuz üç boyutlu ise en sondaki transform position z yerine hedefobje.position.z diyebilirsiniz onemli olan hareket ettirdiğiniz objenin hareket yönlerini kameraya vermek

    • yasirkula dedi ki:

      Editörde de yine joystick kullanmanıza rağmen bu hatayı almadığınızı düşünüyorum. Kullandığınız joystick dinamik miydi? “Is Dynamic Joystick” değerini tersine çevirince de aynı sorun devam ediyor mu? Unity versiyonunuz kaç?

      • Murat Aksoy dedi ki:

        Merhaba evet editorde böyle bir sorun olmuyor. UNİTY sürümüm 2017.3.03f son sürüm diye biliyorum. Çevirip tekrar bakıcam is dinamik tikini kaldırıp.

  7. Hüseyin dedi ki:

    Yasir Hocam bir soru sormak istiyorum.
    Ben mouse ile ekrana tıklamak istiyorum.
    Input.getMouseDown(0) u kullanıyorum

    Şöyle birşey var
    Ekranda mesela 5 tane küp var
    Ben ekrana tıkladığımda eğer tıkladığım yerde küp varsa o küpü yok etmek istiyorum nasıl yapabilirim.
    Yardımcı olursanız ve kodlarını paylaşırsanız çok sevinirim
    Sevgilerle..

    • yasirkula dedi ki:

      Öncelikle küpte bir collider olduğundan emin olun. Ardından küpe bir script atıp içine şu fonksiyonu yazın:

      void OnMouseDown()
      {
      Destroy(gameObject);
      }

  8. ahmet dedi ki:

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    [RequireComponent(typeof(CharacterController))]

    public class Rotateone : MonoBehaviour {

    public float turnSpeed = 4.0f;
    private Vector3 mouseOrigin;
    private bool isRotating;
    private bool isZooming;
    private CharacterController controller;
    private CollisionFlags flags;

    public float minY = -45.0f;
    public float maxY = 45.0f;
    float rotationY = 0.0f;

    void Update()
    {
    controller = GetComponent();
    if (Input.GetMouseButtonDown(0))
    {
    // Get mouse origin
    mouseOrigin = Input.mousePosition;

    isRotating = true;
    }

    if (!Input.GetMouseButton(0)) isRotating = false;

    if (isRotating)
    {
    Vector3 pos = Camera.main.ScreenToViewportPoint(Input.mousePosition – mouseOrigin);

    transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed);
    transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed);

    }

    }
    }

    Hocam ben burda x’in min,max ve y’nin min ve max aralarında dönmesi için nasıl yazabilirim.
    (y mesela -45 ile + 45 arasında kalsın).Yardım edebilirmisiniz.Teşekürler.

    • yasirkula dedi ki:

      Şöyle bir şey deneyebilirsiniz:

      transform.RotateAround(transform.position, transform.right, -pos.y * turnSpeed);
      transform.RotateAround(transform.position, Vector3.up, pos.x * turnSpeed);

      Vector3 rot = transform.localEulerAngles;

      while( rot.x > 180f ) rot.x -= 360f;
      while( rot.y > 180f ) rot.y -= 360f;
      while( rot.x < -180f ) rot.x += 360f;
      while( rot.y < -180f ) rot.y += 360f;

      rot.x = Mathf.Clamp( rot.x, minX, maxX );
      rot.y = Mathf.Clamp( rot.y, minY, maxY );

      transform.localEulerAngles = rot;

      • hicmedyaa dedi ki:

        iyi günler unity3d oyundan apk dosyası alırken bu hatayı alıyorum yardım edermisiniz?

        UnityEditor.BuildPlayerWindow + BuildMethodException: Komut dosyalarının düzenleyicide derleme hataları olması nedeniyle Player’ı oluşturma hatası
        UnityEditor.BuildPlayerWindow + DefaultBuildMethods.BuildPlayer’da (BuildPlayerOptions seçenekleri) [0x0020e] C: \ buildslave \ birlik \ yapı \ Düzenleyici \ Mono \ BuildPlayerWindowBuildMethods.cs’de: 
        UnityEditor.BuildPlayerWindow.CallBuildMethods adresinde (Boolean askForBuildLocation, BuildOptions defaultBuildOptions) [0x00065] C: \ buildslave \ birlik \ yapı \ Düzenleyici \ Mono \ BuildPlayerWindowBuildMethods.cs’de: 88 
        UnityEngine.GUIUtility: ProcessEvent (Int32, IntPtr) 

      • yasirkula dedi ki:

        Size mail ile de cevap vermiştim ama başkalarının da faydalanabilmesi için; şurada yazan çözüm metotları şöyle: https://answers.unity.com/questions/1380921/build-failed-with-errors-at-unityeditorbuildplayer.html

        1- Assets-Reimport All yapmayı deneyin
        2- APK’yı farklı bir isimle masaüstündeki farklı bir klasöre kaydetmeyi deneyin
        3- Build System’ı Gradle yapmayı deneyin
        4- SDK Manager’da Build Tools’un en güncel sürüm olduğundan emin olun
        5- JDK sürümünüz 1.7 ise JDK 1.8 kurup öyle build almayı deneyin (öncesinde yeni JDK’yı Edit-Preferences-External Tools’a tanıtmanız gerekebilir)
        6- Build&Run yapıyorsanız sadece Build etmeyi deneyin

  9. Hüseyin dedi ki:

    Yasir Hocam Videolu Olarak Anlatsanız Çok Memnun Oluruz.
    Gerçi Zaten Memnunuz Ama…

  10. enceweb dedi ki:

    Hocam Merhabalar,
    Üst üste 2 tane buton var. Alttaki butonda seçilecek player ın sprite’ı üstteki butonda ise player’ın değerinin yazılı olduğu sprite var(Üstteki buton alttaki butonun child’ı).Alttaki butona tıklayınca player seçiliyor. Üstteki butonu setactive false ile kaldırıyorum ama sorun şu ki onu kaldırmadan da alttaki buton çalışıyor 🙂 Alttaki butonu setactive false yapmadan(çünkü playerin sprite’ının gözükmesi gerekiyor) nasıl pasif hale getirebilirim hocam?
    Saygılarımla…

  11. WE dedi ki:

    Ben Android için bir oyun hazırladım paketledim. Editördeyken sorunsuzca butonlara tıklayabiliyorum fakat paketledikten sonra telefondan açınca butonlar tepki vermiyor. Mesela var olan butona bastığım zaman basıldığı anlaşılıyor hovered var fakat event tepki vermiyor.

  12. Y4kup dedi ki:

    TouchPad scriptini entegre edemedim hocam.Basitçe anlatırmısınız.

    • yasirkula dedi ki:

      Bir UI objesine (mesela Image) Touchpad scriptini verip “X Axis” ve “Y Axis”e değerlerini vermeniz lazım. Diyelim ki değerlerini “Horizontal” ve “Vertical” yaparsanız kodlarınızda SimpleInput.GetAxis(“Horizontal”) ve SimpleInput.GetAxis(“Vertical”) fonksiyonlarını kullanarak touchpad’in döndürdüğü x ve y değerlerinden faydalanabilirsiniz. Eğer touchpad’i mouse ile de kullanabilmek istiyorsanız “Allow Mouse Input” seçeneğini işaretlemeyi unutmayın.

      • Y4kup dedi ki:

        Teşekkür ederim oldu.Android FPS controller yapmak için sormuştum.Güzel oldu sayenizde.Kod için ayrıca teşekkürler.

      • yasirkula dedi ki:

        Rica ederim 🙂

      • müçtehit dedi ki:

        Hocam ben yapamadım biraz daha adım adım açıklıyabilirmisiniz Touchpad”i örnegin bir objeyi hareket ettiricez ama nasıl ?

      • yasirkula dedi ki:

        Touchpad olmasını istediğiniz RectTransform objesine Touchpad component’i verin ve “X Axis” ile “Y Axis” değişkenlerine değer olarak, yatay ve dikey eksen için kullanmak istediğiniz axis’lerin isimlerini girin (“Horizontal” ve “Vertical” gibi halihazırda var olan axis’ler girebileceğiniz gibi, “YatayHareket” ve “DikeyHareket” gibi yeni axis’ler de girebilirsiniz). Eğer touchpad’in mouse ile de kontrol edilebilmesini istiyorsanız “Allowed Mouse Buttons” değişkenine, hangi mouse butonları ile touchpad’i kontrol edebileceğinizi girin.

        Artık script’lerinizden touchpad’in değerlerine SimpleInput.GetAxis(“YatayHareket”) ve SimpleInput.GetAxis(“DikeyHareket”) vasıtasıyla erişebilirsiniz.

  13. enceweb dedi ki:

    Merhabalar hocam,

    Player Pref kullanımı ile alakalı bir sorum olacaktı. Oyun içi toplanılan skorla menüde kilidi açılmamış bir objenin(oyuncu,araba vs) kilidini açıp oyuna o obje ile devam etmek için nasıl bir script yazmalıyız? Bu konu ile alakalı forumlarda bir sürü soru var ama hiç cevap yok yabancı kaynak da bulamadım yardımcı olabilirseniz çok sevinirim hocam.
    Saygılarımla…

    • yasirkula dedi ki:

      Oyun bitiminde elimizdeki skoru “score” isminde bir değişken tutuyor diyelim. Bu durumda şöyle bir kod ile toplam skoru artırabilirsiniz:

      PlayerPrefs.SetInt( “ToplamSkor”, PlayerPrefs.GetInt( “ToplamSkor”, 0 ) + score );
      PlayerPrefs.Save();

      Oyun esnasında herhangi bir anda da bu skora PlayerPrefs.GetInt( “ToplamSkor” ); şeklinde erişebilir ve bu değeri kontrol ederek kilitleri açabilirsiniz.

  14. Muhammed dedi ki:

    S.a yasir abi konuyla alakalı değil fakat 2 şey kafama takıldı bulamadım 1.si ben androide bir uygulama yapıp açtığımda telefonun bildirim çubuğu kapanıyor ben bunu nasıl önlerim yani uygulama açıldığında telefonun bildirim çubuğuda gözüksün. 2.si de mesela bir canvas icine panel olusturdum ben bir butona tıkladığım zaman panelin yandan sürülerek açılmasını istiyorum aynı google play de soldan açılan pencere gibi butonu ben hallederim sadece birden değil yavaş yavaş açılmasını istiyorum bunları nasıl yapabilirim cevaplarsan sevinirim iyi geceler abicim.

    • yasirkula dedi ki:

      1- Android’deki Immersive Mode’u kodunuzun Start fonksiyonuna “Screen.fullScreen = false;” yazarak çözebildiğiniz söyleniyor.
      EDIT: fullScreen kodu bildirim çubuğunu açmıyor olabilir. Bunun için o koda ilaveten projenizin Plugins/Android klasörüne şu 2 dosyayı kopyalamanız gerekebilir: https://github.com/Over17/UnityShowAndroidStatusBar/tree/master/Assets/Plugins/Android
      2- Panelinizin Anchor X değerlerini ve Pos X değerini 0 yapın. Pivot X değerini ise 1 yapın. Ardından şu fonksiyonlar vasıtasıyla paneli açıp kapatabilirsiniz (kodun panelde olması lazım ve fonksiyonları StartCoroutine ile çalıştırmalısınız):

      IEnumerator PaneliAc( float sure )
      {
      	RectTransform tr = (RectTransform) transform;
      	Vector2 pivot = tr.pivot;
      
      	if( sure <= 0f )
      		sure = 0.0001f;
      
      	float delta = pivot.x / sure;
      	while( pivot.x > 0f )
      	{
      		pivot.x -= delta * Time.deltaTime;
      
      		if( pivot.x <= 0f )
      		{
      			pivot.x = 0f;
      			tr.pivot = pivot;
      		}
      		else
      		{
      			tr.pivot = pivot;
      			yield return null;
      		}
      	}
      }
      
      IEnumerator PaneliKapat( float sure )
      {
      	RectTransform tr = (RectTransform) transform;
      	Vector2 pivot = tr.pivot;
      
      	if( sure <= 0f )
      		sure = 0.0001f;
      
      	float delta = ( 1f - pivot.x ) / sure;
      	while( pivot.x < 1f )
      	{
      		pivot.x += delta * Time.deltaTime;
      
      		if( pivot.x >= 1f )
      		{
      			pivot.x = 1f;
      			tr.pivot = pivot;
      		}
      		else
      		{
      			tr.pivot = pivot;
      			yield return null;
      		}
      	}
      }
      
  15. Hocam ben unity ile android’de kullanıcıdan isim gibi bir şey almak istiyorum butona tılayınca klavye gelicek ve oraya ismini yazıcak ve onu kaydedicem klavye için tek kaynak bunu bulabildim:
    https://docs.unity3d.com/Manual/MobileKeyboard.html
    bunu da yapamadım

    Bildiğiniz başka bir kaynak var mıdır

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;

    public class klavyeaçma : MonoBehaviour {

    public string stringToEdit = “Hello World”;
    private TouchScreenKeyboard keyboard;

    // Opens native keyboard
    void OnGUI ()
    {
    stringToEdit = GUI.TextField (new Rect (10, 10, 200, 30), stringToEdit, 30);

    if (GUI.Button (new Rect (10, 50, 200, 100), “Default”)) {
    keyboard = TouchScreenKeyboard.Open (“”, TouchScreenKeyboardType.NumberPad);
    }

    }
    }

    kodum bu ekranda yazı yazılabilen bi ekran çıkıyor (pc için klavye ile yazılabiliyor) altında bir de klavye olması gerek fakat onun yerine default yazan bir buton var

    kodu açıklayabilir misiniz ?

    hata nerde ?

    • yasirkula dedi ki:

      Bu kod, artık performansından dolayı tavsiye edilmeyen OnGUI fonksiyonunu kullanıyor ve de benim hiç kullanmadığım TouchScreenKeyboard sınıfından faydalanıyor. Onun yerine UI sistemini kullanarak bir Input Field objesi oluşturmak isteyebilirsiniz. Input Field’a kullanıcı mobil cihazda tıklayınca ekranda otomatik olarak bir sanal klavye belirmekte.

      UI dersim için bkz: https://yasirkula.com/2015/01/21/unity-ui-arayuz-sistemi/

  16. enceweb dedi ki:

    tamamdır hocam bu kısmı hallettim bi noktayı atlamışım 🙂 teşekkürler…

  17. enceweb dedi ki:

    hocam tekrar merhaba, sonsuz yolda değişiklikleri uyguladım normal oyunda sorun yok ama ileri yol objelerine oyundakinden farklı kendi yaptığım zemin prefablarını kullanınca 2 sorunla karşılaşıyorum 1.si yol sonsuz oluşmuyor, 2.si puan objeleri gözükmüyor nerede hata yapıyor olabilirim hocam yardımlarınızı rica ediyorum, saygılarımla…

  18. Muhammed dedi ki:

    S.a yasir abi nasılsın ben sana 3 tane bir şey soracağım yardım edersen sevinirim ilk olarak ben oyunda atiyorum bir ayarlar bolumu ekledim ve ben butona basinca grafik kodunun acilip kapanmasini istiyorum kisacasi butona tiklayinca yada OnMouseDown ile bir objeye tiklayinca scriptin kapanip acilmasini istiyorum birde ben zombi yapay zekasi olusturdum mesela ben mesafe 2 den az olursa zombinin saldirma animasyonu devreye giriyor uzaklasirsam pesimden kosuyor evet onu normal olarak yaptim fakat zombi duvarin arkasina gecince dolasmiyor navigasyonu haritaya ekledim objelere bunu karaktere nasil vericem ki etrafini dolasip beni bulsun ama yine mesafe azalinca animasyonlar devreye girsin kısacası benim yaptığım yapay zekada zombi modelinin beni navigationdan bulmasını istiyorum son olarak benim oyunum çok kasmaya başladı farkettim 3d model ekleyince kasmaya başlıyor bahçenin etrafını demirlerle kapattım yaklaşık 30 tane nesne kopyaladım kasmaya başladi oyunun grafiklerini düşürtmeden kasmasını nasıl önleyebilirimyardim edersen sevinirim abicim (:

    • Muhammed dedi ki:

      Son bir şey daha sormak istiyorum abi ben şimdi unity deki hazir joysickleri kullaniyorum fakat pc uzerinden joystickler işlemiyor bende hep build edip telefondan bakmak zorunda kaliyorum ve zaman kaybi oluyor hem pc uzerinden hemde telefondan işleyen joystickleri nasil yapabilirim

      • yasirkula dedi ki:

        Açıkçası şu dersimdeki joystick’in her platformda düzgün çalışıyor olması lazım: https://yasirkula.com/2016/06/17/unity-ui-dokunmatik-ekran-joystick-kullanimi-multi-touch-destekli/

        Ekrandaki butonu UI-Button ile yaparsanız On Click event’i vasıtasıyla, butona basınca çalışacak fonksiyonlar belirleyebilirsiniz. Bu fonksiyonların birinin içerisinde ise grafik scripti component’ine GameObject.Find ve GetComponent fonksiyonları yardımıyla erişip component’in enabled’ını değiştirebilirsiniz.

        Zombilere NavMeshAgent vermeniz lazım. Zombiler player’ı kovalarken pathfinding yapması için NavMeshAgent’ta SetDestination( player.transform.position ); gibi bir kod çalıştırmalısınız. NavMeshAgent zombiyi kendi başına hareket ettireceği için başka Translate veya AddForce gibi kodlarınız varsa onları silin veya comment’leyin. Zombi ile player arasındaki gerçek mesafeyi bulmak için de NavMeshAgent’ın remainingDistance değişkeninden faydalanabilirsiniz.

  19. enceweb dedi ki:

    emekleriniz için çok teşekkür ederim hocam, karşılık beklemeden yaptığınız çalışmalarla bizleri mahçup ediyorsunuz başarılarınızın devamını dilerim, saygılarımla….

  20. enceweb dedi ki:

    merhabalar hocam, emek ve gayretleriniz için çok teşekkür ederim bu alanda bildiğimiz herşeyi sizden öğrendik desem abartmış sayılmam sanırım 🙂 . hocam daha önce yayınlamış olduğunuz temple run tarzı oyun yapımı ile alakalı scriptte bir yerde takıldım yardımlarınızı rica ediyorum. yolu sağa veya sola döndürmeden subway surf tarzı düz ilerlemek istiyorum ama pooling sistemini uygulayamıyorum. düz ilerleyen infinete bir yol ve puan objelerini koyabilmek için scriptte nasıl değişiklik yapmam gerekiyor yardımcı olabilirseniz çok sevinirim… saygılarımla….

    • yasirkula dedi ki:

      Temple Run örneğini yazdığım zamanlarda henüz şimdikinden daha acemiydim ve dürüst olmak gerekirse o örneğin kodu çok da iyi olmadı. Temel çok iyi olmayınca da onun üzerine kat çıkmak zor oluyor. Dediğiniz şeyi bir miktar eforla yapabiliriz elbette ama benim önerim Unity’nin fırından yeni çıkardığı kendi infinite runner örneğine bakmanız yönünde; gördüğüm kadarıyla burada yol düz bir şekilde oluşturuluyor: https://www.assetstore.unity3d.com/en/#!/content/87901

      • enceweb dedi ki:

        hocam bu tavsyenizi görmüş ve incelemiştim ama henüz bu oyundaki scriptleri anlayabilecek kadar birikimim yok :/ 🙂

      • yasirkula dedi ki:

        SonsuzYolScript’in içeriğini şu şekilde değiştirerek düz infinite yol oluşturmayı başardım: https://www.dropbox.com/s/7c7g2d68jo8iqnh/TempleRunKlonInfiniteDuzYol.cs?dl=0

        Basit anlamda yaptığım değişiklikler şöyle:
        – Start fonksiyonunda ileri yönde 1 değil 2 tane YolContainer oluşturdum
        – Update fonksiyonunda Player’ın yolun ilk yarısını geçip geçmediğini kontrol ettim
        – Eğer player yolun ilk yarısını geçmişse yolun ilk yarısını havuza yollayıp sonra yolun ikinci yarısının ucunda tekrar oluşturdum

        Yani aslında tahminimin aksine çok az bir kodla (yaklaşık 15-20 satır) dediğiniz şeyi yapmak mümkünmüş 😀 Oyunu test ederken bir de şunu gördüm ki; Window-Lighting-Settings’teki Fog’u açıp rengini de Main Camera’nın Background rengi ile aynı renk yapınca, özellikle zıplarken yolun ucu daha bir güzel duruyor.

  21. ekrem doğa dedi ki:

    ilginç emeğinize sağlık sizi takip ediyorum hocam benim bi sitem var http://siteneradyoekle.net adında buna uygulama yazarmısınız?

Bir 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.