Yeniden merhabalar,
Bu derste, Unity‘de yazdığınız bir C# script’inden başka bir C# script’indeki değişkene ulaşmanın birkaç yolunu göstereceğim:
- Hedef script’i public bir değişkende tutmak
- Hedef script’e kod vasıtasıyla ulaşmak
- Değişkeni static yapmak
Bu konuda sıklıkla soru aldığım için, umarım bu ders akıllardaki bir takım soruları cevaplayacaktır. Hazırsanız derse başlayalım!
Öncelikle, işleri kolaylaştırması adına iki script’e ve ulaşmak istediğimiz değişkene isimler verelim. Ders boyunca, Dusman script’inden Player script’indeki “public Vector3 konum;” değişkenine ulaşmaya çalışacağız. Ulaşmaya çalıştığımız değişkenin ya public olması lazım, ya da o değişkene ulaşmaya yarayan public bir property veya fonksiyonun Player script’inde tanımlı olması lazım. Aksi taktirde bu değişkene ulaşamayız.
Hedef script’i public bir değişkende tutmak
En basit yöntem bu sayılabilir. Dusman script’inde public Player player;
değişkeni oluşturun ve Dusman objesinin Inspector’undan Player değişkene değer olarak, Player objesini verin. Artık player.konum şeklinde konum değişkenine ulaşabilirsiniz.
Eğer Dusman script’i bir prefab’da yer alıyorsa ve Player objesi sahnenizde yer alan bir obje ise (yani prefab değilse), Dusman objesinin Player değişkenine Player objesini değer olarak veremezsiniz. Çünkü sahnedeki objeler prefab’ların değişkenlerine değer olarak verilemez. Bu durumda, bahsedeceğim diğer yöntemlere başvurmak zorundasınız.
Hedef script’e kod vasıtasıyla ulaşmak
Oyun esnasında bir objeye veya component’e dinamik olarak erişmek için birkaç fonksiyon mevcut:
GameObject obje = GameObject.Find(“Objenin ismi”): ismi girilen objeyi GameObject olarak döndürür. Aynı isimde birden çok obje varsa, ilk bulunan obje döndürülür. Eğer bu isimde bir obje yoksa null döndürülür
GameObject obje = GameObject.FindWithTag(“Objenin tag’ı”): tag’ı girilen objeyi GameObject olarak döndürür. Aynı tag’e sahip birden çok obje varsa, ilk bulunan obje döndürülür. Eğer bu tag’e sahip bir obje yoksa null döndürülür
Player playerScripti = obje.GetComponent<Player>(): obje’nin Player component’ini döndürür. Eğer objede Player component’i yoksa null döndürülür
Player playerScripti = FindObjectOfType<Player>(): sahnedeki Player component’ine sahip objeyi bulur ve bu objenin Player component’ini döndürür. Eğer birden çok objede Player component’i varsa, ilk bulunan objenin Player component’i döndürülür. Sahnedeki hiçbir objede Player component’i yoksa null döndürülür
Fark edeceğiniz üzere, bu fonksiyonlar vasıtasıyla oyun esnasında sahnedeki herhangi bir objeye dinamik olarak erişebilirsiniz. Ancak bu fonksiyonlar biraz yavaş fonksiyonlardır (özellikle FindObjectOfType ve GameObject.Find), o yüzden bu fonksiyonları Update gibi bir fonksiyonda kullanırsanız bu performans sorunlarına yol açabilir. Onun yerine, ulaşmak istediğiniz objeyi tutacak private bir değişken oluşturup, bu fonksiyonlar yardımıyla Start fonksiyonunda değişkene değerini verebilir ve script’in geri kalanında objeye bu değişken vasıtasıyla ulaşabilirsiniz. Örneğin:
private Player player; void Start() { // Player objesinin tag'ının Player olması lazım! player = GameObject.FindWithTag( "Player" ).GetComponent<Player>(); // veya (daha yavaş) player = GameObject.Find( "Player" ).GetComponent<Player>(); // veya (çok daha yavaş) player = FindObjectOfType<Player>(); } void Update() { // Artık değişkene player.konum şeklinde ulaşabiliriz Debug.Log( player.konum ); }
Player fonksiyonuna kod vasıtasıyla ulaşmanın daha hızlı bir yolu ise, Player script’ine hızlıca ulaşmaya yarayan bir static değişken oluşturmaktır. Bunun için Player script’inde public static Player instance;
şeklinde bir değişken tanımlayıp Awake fonksiyonunda (Awake, Start fonksiyonundan önce çağrılır) instance=this;
komutunu çalıştırabilirsiniz:
public static Player instance; void Awake() { // Player script'i, instance değişkenine değer olarak kendisini (this) veriyor instance = this; }
Bundan böyle Dusman script’inden konum değişkenine Player.instance.konum şeklinde rahatça ulaşabilirsiniz. Bu yöntem, yukarıda bahsettiğim fonksiyonları kullanmaya göre çok daha hızlıdır.
Değişkeni static yapmak
Aslında bu yöntem, bir önceki yöntemde bahsettiğim static instance değişkeni oluşturmakla bayağı benzerdir. Tek fark, static instance değişkeni oluşturmak yerine direkt konum değişkenini static yapmamızdır. Yani public Vector3 konum;
değişkenini, public static Vector3 konum;
olarak değiştirmek yeterlidir. Artık Dusman script’inden bu değişkene direkt Player.konum şeklinde erişebiliriz.
Bu yöntemin kötü yanı, artık konum değişkenine Inspector’dan değerini veremeyecek olmanızdır çünkü static değişkenler Inspector’da gözükmez. Yani eğer konum değişkenine değerini script’inizden veriyorsanız bu yöntem idealken, konum değişkenine Inspector’dan değer veriyor idiyseniz bu yöntem yerine bir önceki static instance değişkenli yöntemi tercih etmelisiniz.
Bu yöntemle ilgili bilmeniz gereken bir başka husus ise, static değişkenlerin varsayılan değerlerini yalnızca bir kere aldıklarıdır. Bir örnek ile biraz daha açayım: diyelim ki ulaşmak istediğiniz değişken public int skor;
(veya public int skor = 0;
) olsun. Burada skor değişkeninin varsayılan değeri 0’dır. Bu değişkene sahip script’in olduğu obje her yok olup yeniden oluştuğunda, skor‘un değeri tekrar varsayılan değer olan 0’a döner. Ancak siz bu değişkeni public static int skor;
şeklinde static yaparsanız, değişkene ilk kez ulaşırken değişken yine 0 döndürürken, değişkene sahip script’in olduğu obje yok olup yeniden oluştuğunda skor‘un değeri sıfırlanmaz, en son değeri neyse o şekilde kalır. Yani mesela level bitti, ana menüye dönüş yapıldı ve ardından level tekrar başlatıldı diyelim. Bu durumda normalde skorun sıfırlanması beklenirken, en son level’da skor ne idiyse değeri o şekilde devam eder. Her level başında skor’un değeri sıfırlansın isterseniz, skor’un olduğu script’in Awake fonksiyonunda skor = 0;
şeklinde değeri elle sıfırlamanız gereklidir.
Böylelikle bu dersin de sonuna geldik, sonraki derslerde görüşmek dileğiyle!
Hocam ben endless runner tarzı bir oyun yapmayı deniyorum. Altın prefabının scripti içinden prefab halinde olmayan sahnedeki bir nesnenin child objelerine ulaşmak istiyorum ama kod çalışmıyor.Neden olabilir?
Dediğiniz gibi, prefab’dan sahnedeki objelere doğrudan (Inspector’dan referans vererek) ulaşamazsınız. Bu derste bahsettiğim yöntemleri denediğinizi varsayıyorum. Örneğin hangi yöntem çalışması gerekirken çalışmadı?
Selamun Aleyküm hocam. Build almada sıkıntı yaşıyorum. Telefonum pc’ye bağlı olmadığında telefonu bağlayın hatası alıyorum. Build yaparken telefonumun pc’ye bağlı kalması gerekli mi? Yoksa ayarlardan yapmam gereken bir değişiklik var mı?
Aleykümselam. Sadece Build yaparsanız telefonu bağlamanız gerekmiyor. Build&Run’da gerekiyor.
Anladım hocam. Teşekkür ederim. Bir de hatalar almaktayım. Bu hataları nasıl çözebilirim inşallah?
“Exception: Failed running C:\Program Files\Unity\Hub\Editor\2020.3.12f1\Editor\Data\il2cpp/build/BeeSettings/offline/bee.exe –useprebuiltbuildprogram –no-colors”
https://yasirkula.com/2018/06/05/unity-oyun-ici-dinamik-paneller-sekme-destekli/#comment-56671
Hımm tamam hocam teşekkür ederim. Bir de hata alıyorum. Hataların hepsini yazınca buraya gönderemedim. Bundan dolayı teker teker yazarak ilerlemek istiyorum müsadenizle.
“Exception: Failed running C:\Program Files\Unity\Hub\Editor\2020.3.12f1\Editor\Data\il2cpp/build/BeeSettings/offline/bee.exe –useprebuiltbuildprogram –no-colors”
hocam pardon iki defa yazmışım aynı yorumu.
Yasir Bey merhabalar öncelikle eğer vaktiniz olursa bir soru sormak istiyorum.Blok kırma oyunu yapmaktayım başlangıç seviyesindeyim hem unity olsun hem c# da.Sorum şu oyuna güçlendirici ekliyorum top ona çarptığında bütün blokların içinden geçerek onları destro edecek.Sorum şu güçlendiriciye çarpma gerçekleştiğinde diğer bloklar(prefabdan çekildi) hepsinin isTrigger ını nası aktif edebilirim
Yardımcı olursanız minnetar olurumçİyi çalışmalar
Bunun için tüm blokları bir listede tutmanız lazım:
public static readonly List<Blok> Bloklar = new List<Blok>( 256 );
void OnEnable() { Bloklar.Add( this ); }
void OnDisable() { Bloklar.Remove( this ); }
Ardından Blok.Bloklar şeklinde bu listeye erişebilirsiniz.
Çok teşekkür ederim Yasin Bey ilginiz,alakanız ve yardımınız için.
Merhaba hocam.Tavsiyenize ihtiyacım var. Bir sahnedeki tuşa bastığımda başka bir sahnedeki gameobject’i aktifliğini değiştirmek istiyorum(görünüp görünmemesi için renk alfasını değiştirmesi de olabilir) bunu Scriptler arası transfer ile yapmaya çalıştım.Ulaşmak istediğim gameobjectin olduğu sahneye script yazıp serializedfield yardımı ile sahneden ekleme yapmayı denedim, FindObject i denedim, static yapmayı denedim. Fakat diğer sahneden tuşa bastığımda Null reference hatası alıyorum. Toparlayacak olursam bir sahneden başka sahnede ki gameobjecte nasıl erişebilirim?
Mevcut sahneler haricindeki sahnelerde yer alan objelere erişemezsiniz. Aklıma gelen en kolay çözüm yolu static bir değişken kullanmak ve diğer sahnedeki objenin Awake’inde, bu static değişken true ise objeyi gizlemek.
Hocam ilgilendiğiniz için teşekkürler. Dediğinizi denedim yanlış yapmadıysam o da olmadı(Null reference veriyor). Benim amacım aslında market sahnesinden satın alınan bir şeyin eşyalar sahnesinde gözükmesi ama beceremedim. En son Coroutine yapmayı denedim satın alınca 2 saniye sonra eşyalar sahnesine gidiyor, 1 saniye sonrada deaktif olan eşyayı aktif ediyor. Bu işlemi yapan scriptide singleton objenin içine attım, sonra aktif olunacak nesneyi scriptten Gameobject.Find yaptım ama null reference verdi yine. Resources diye bir olay varmış onu araştırıyorum belki o çözüm olabilir.
public static bool bir değişkenin değerini değiştirmek veya bu değişkene erişmek asla null hatası vermez. Markette A eşyasını satın alınca, Market script’indeki “public static bool aEsyasiSatinAlindi;” değişkenini true yapıp, eşyalar sahnesinin Awake’inde ise bu değişkenin değeri true ise ilgili eşyayı aktif hale getireceksiniz sadece.
Hocam çok teşekkürler. Bugün zihnim biraz kapalı idi , ilk cevabınızda da demişsiniz ama ben ısrarla bool yerine gameobjecte ulaşmaya çalışmışım.Neyse tecrübe kazandım diyelim. Zaman ayırdığınız için teşekkürler tekrardan.
Merhaba,
Level1Boss isimli karaktere ait Level1BossManager scripti var ve ben bu karakteri BossSpawner isimli scriptten Level1Boss adında spawn ediyorum. Level1BossManager de health sistemi tanımlı. BossSpawner dan health 0 a yada daha düşük bir değere düştüğü anda destroy işlemi gerçekleştirmek istiyorum. Bunun için Level1BossManager de public static Level1BossManager instance ve awake fonksiyonları da tanımlı. BossSpawner da if(Level1BossManager.instance.health<=0){destroy(Level1Boss)} yazdığımda hiç destroy olmuyor debug.log alıyorum consolda da hiçbirsey olmuyor. Sorun nerededir? Teşekkürler
Destroy(Level1Boss.gameObject) işe yarıyor mu?
Çok teşekkür ederim. Start’a yazıyormuşum update alınca düzeldi şimdi fakat şimdi de if(Level1BossManager.instance.health<=0) için NullReferenceException: Object reference not set to an instance of an object hatası veriyor. Bunu nasıl düzeltebilirim?
Birde health'in 0' a eşit yada 0'ın altına düştüğü anın kontrolü için update kullanıyorum ve bu sürekli çalışan ve sistemi yorucu bir durum oluyor. Time.timescale =0 durumunda bile çalışıyor bu kontrol. Bunun yerine health değişkeninin durumu kontrol edebileceğim bir metod var mıdır?
teşekkür ederim.
Boss objesini yok ettiğinizde Level1BossManager.instance null oluyorsa haliyle NullReferenceException alırsınız. if(Level1BossManager.instance) şeklinde, instance’ın null olup olmadığına bakmanız lazım. Sadece health değiştiğinde bir kod çalıştırmak için health’i property yapıp set fonksiyonunda istediğiniz kodu çalıştırmanızı öneririm.
Yasir Bey gerçekten çok teşekkür ederim inceliyorum propertyleri. Kendi kodlarıma ve oyunuma göre kodlara nasıl dökebileceğimi araştırmaya çalışıyorum. Şimdi doğru mu anlamışım, bölüm sonu çıkan boss u öldürdükten sonra boss yok olacak, Level Complete UI açılacak ve sonra zaman sıfırlanacak. Bu işlemeleri sırasıyla yaptığım da haliyle gameobject destroy olduğu için geri kalan işlemleri yapmak için başka bir sciptten health sıfırın altına düşüp düşmediğini sürekli kontrol etmem gerek. İşte bu sürekli kontrol etmek için update fonksiyonu kullanmak yerine propertileri kullanıyoruz. Doğru mu anlamışım ve bu işlemler için tavsiye edeceğiniz daha kısa bir yöntem var mıdır? Biraz uzun yazdım lütfen kusura bakmayın.
Evet burada Update yerine property kullanabilirsiniz. Başka bir scriptten canı kontrol etmenin bir alternatifi ise, boss’ta bir event/UnityEvent bulundurmak ve can propert’sinde değer 0’ın altına inerse bu event’i çağırmak. Boss’un öldüğünü hangi script’lerin bilmesi gerekiyorsa, o script’lerin levelin başında bu event’e kaydolmaları lazım.
cevap geleceğini sanmıyorum ama aradığım cevabı bulamadım şunun kodlamaya çevrilmiş hali nedir
public class a scripti : Monobehaviour
// a scripti ile b scriptindeki true olan bool değişkenini false yapmak istiyorum
// şunun kodlamaya çevrilmiş hali nedir
b_scripti.bool = false
// bunu nasıl yazabilirim
Bu dersi zaten bunun için yazdım dersi okudunuz mu?
sana basit bir şekilde anlatayım
diyelim ki nesne adlı bir gameobject var door adlı bir component ve isLocked diye bir değişken var başka bir gameobjectteki scriptten islockedi değiştirmek istiyorsan mesela anahtarın scriptinden
GameObject.Find(“gameobject”).GetComponent<door>().isLocked = false;
şeklinde yazıp
Hocam öncelikle çok teşekkürler çok faydalı konulara değiniyorsunuz sormak istediğim birşey var kodlara yeni aşina oluyorum uygulama içi satın alma yapacağım youtube de bir video izledim arkadaş kodlarıda paylaşmış link paylaşmak yasakmı bilmiyorum ama dilerseniz bana mailde gönderebilrisiniz şimdi hocam burada satın alım başarılı oluyor tamam ama ben satın alım gerçekleştik den sonra Text e yazmasını yani göstermesini istiyorum birtürlü yapamadım 100 altın aldım butona tıkladım bunu Text de göstereceğim Video Link: https://www.youtube.com/watch?v=RchTCScO3MU
public Text değişkende Text’i tutun. Altın satın alma başarılı olunca bunu SetActive(true) ile görünür yapın. Birkaç saniye sonra isterseniz SetActive(false) ile tekrar görünmez yapın. Birkaç saniye beklemek için coroutine kullanabilirsiniz.
İyi günler ben bir Npc(görev alma) scripti yazıyorum tek sctirpti farklı karakterlere atarak textlerini görevi kabul edip etmediklerini inceptor üzerinden ayarlayabiliyorum fakat her karakter farklı görev vermeli o yüzden benim “public Script sciptIsmi ” gibi bir komuta ihtiyacım var lakin ne kadar araştırsam da buna benzer bir yöntem bulamadım kısaca aynı scriptle farklı scriptlere yönlendirme yapabilir miyim yoksa her npc için aynı kod yazmak zorunda kalacağım 😦
Şu dersimdeki UnityEvent işinize yarayabilir. Böylece her görev component’i, istediği fonksiyonları çağırabilir.
Hocam yazdığım kod çalışmıyor hata nerde bulamadım oyuna altın sistemi eklemeye çalışıyorum altına goldtemas adında bir script ekledim
{
gold gos;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == “Player”)
{
gos.GetComponent().abc();
Destroy(gameObject);
}
}
}
sahnedeki boş bir objeye ise gold adında bir script ekledim oda şöyle
{
public int gol;
[SerializeField]
Text goll = default;
// Start is called before the first frame update
void Start()
{
goldGoster();
}
// Update is called once per frame
void Update()
{
}
void goldGoster()
{
goll.text = “Gold: ” + gol;
}
public void abc()
{
gol += 5;
goldGoster();
}
}
karakter altına temas edince gol +5 değer kazanması ve altının yok olması lzm fakat olmuyor sizce hata nerede olabilir?
Hocam goldtemas scriptinde gos.GetComponent().abc(); şeklinde yazılı kopyalarken orayı almamış farklı şekilde start fonksiyonuna gos = GetComponent(); olarak yazıp trigger kısmınada gos.abc(); olarak da denedim iki türlüde gold scriptindeki abc fonksiyonunu çalıştıramadım.
OnTriggerEnter2D çalışmıyor olabilir. Bu gibi durumlarda, altın artana kadar çalışan tüm satırlara Debug.Log koyup hangi satırda log’ların kesildiğine bakabilirsiniz.
Hocam OnTriggerEnter2D çalışıyor sadece destroy varken altın yok oluyor temas edince fakat abc() yi eklediğim zaman ikiside çalışmıyor
Yani hocam demek istediğim OnTriggerEnter2D destroy(gameObject) varken çalışıyor fakat ne zaman abc(); yi eklersem çalışmayı kesiyor
Konsolda bir hata yoksa bunun sebebini bilemedim.
Teşekkür ederim hocam yine de
Aynı sıkıntıyı yaşayan olursa sorunu çözdüm buraya yazıyorum
gos = GetComponent(); yerine gos = (gold)FindObjectOfType(typeof(gold)); yazdım sorun çözüldü
Benim amacım değişkene ulaşmak değil mesela şunu istiyorum; a ya basınca Player daki PlayerController scriptindeki ienumerator u StartCoroutine ile çaıştırmak istiyorum ama a ya basmayı algılayan kod başka kodda. Bir türlü yapamadım. Veya şu da olabilir
void CoroutineBaslatici() olur bunu çalıştırırım ve bu şekilde bu kodun içine StartCoroutine koyarım öyle çalıştırırım. Ama başka kodun ne void () ine ne de ienumerator una erişemedim.
Değişkene ulaşmakla fonksiyona ulaşmak arasında önemli bir fark yok. Diyelim değişkene GetComponent<Player>().asd diye ulaşıyorsanız, fonksiyona GetComponent<Player>().Asd() şeklinde ulaşabilirsiniz. Ya da değişkene Player.asd diye erişiyorsanız, fonksiyona Player.Asd() diye erişebilirsiniz.
İşe yaradı teşekkürler.
hocam vallahi bu msjı görürmüsünüz bilmem ama inş görürüsünüz başka bir c# dosyasındaki metodu nasıl çalıştırabilirim
Derste bahsettiğim yöntemlerle public fonksiyonlara da erişebilirsiniz. Örneğin player.konum yerine player.BirFonksiyon() yazabilirsiniz.
Yasir Hocam Konu ile pek alakalı değil fakat bir sorum olacaktı bakarsanız sevinirim,
Instantiated ile prefab obje yapıyorum fakat bu obje orignal game obje gibi snap pointe gittiginde snappointe yapışmıyor. prefab ile original gameobje aynı ozelliklerde olması gerekmezmi,
Aynı özelliklere sahip olması gerekir. Belki siz snap kısmında if(snapEdilenObje==prefabObje) gibi bir kod çalıştırıyorsunuzdur, prefab obje ile ondan Instantiate ile türeyen obje farkı nesneler olduğu için, bu kod Instantiate edilmiş objede false döndürür.
yasir hocam script aşağıdaki linkteki gibi. eklemem gereken birşeymi var acaba plate objesi içinde mi snap scripti yazmam lazım? target objesini tekrardan oluşturmuyor mu initiate code .tşk.
https://hatebin.com/etmtcuufvm
Prefab’ı Instantiate ettikten sonra, Instantite’in döndürdüğü objeyi target’a değer olarak vermeniz lazım gibi duruyor.
hocam benim animasyonlarla ilgili bir sıkıntım var. konu ile alakasız ama yardımcı olursan sevinirim.
bir animasyon oluşturdum ve animasyonu eklediğim image öğesinin fillAmount değeri 1f olduğunda bu animasyonun çalışmasını istiyorum. ekrandaki butonlara basınca bu image öğesinin fillAmount değeri artmaya başlıyor. fillAmount değeri 1 olduğunda animasyon ilk kez çalışıyor (animator.enabled=true ile componenti açıyorum) ve sonlanıyor (sonlanınca Invoke ile 1f saniye sonra animator.enabled = false oluyor). Ardından . bu arada script üzerinden de fillAmount’un değeri tekrardan 0 oluyor. Tekrar ekrandaki butonlara basılıyor ve zaman içerisinde fillAmount değeri yeniden 1 oluyor fakat bu sefer animasyon çalışmıyor, sadece script üzerinden fillAmount değeri hemen 0 a düşüyor.
bunu nasıl çözebilirim acaba ? şimdiden teşekkürler 🙂
Sorunumu çözdüm. Ben animasyonu da fillAmount değerini sıfırlamayı da aynı obje üzerinden yapıyordum. Sanırım o yüzden ilk seferde çalışıp, sonrakilerde çalışmıyordu.
bunu iptal ettim ve objeyi duplicate edip, animasyonu duplicate olan objede oluşturdum. Kopya olan objenin içerisine bir script yazarak ObjeyiKapat adlı bir method yazdım ve içerisinde gameobject.setactive(false) yazdım. Daha sonra start methodundan önce OnEnable() methodu yazdım ve içerisine Invoke(“ObjeyiKapat”, 1f); yazdım.
Diğer script üzerinde de public gameobject ile kopya objeye eriştim. Scriptte fillAmount değeri 1f olunca klon objenin SetActive özelliğini true yaptım. Böylece animasyon fillAmount değeri her 1f olduğunda tekrar çalıştı.
3 gündür çeşit çeşit yöntemler deneyip sonuca ulaşınca insan seviniyor 🙂
Elinize sağlık 🙂
Merhaba,
konuyla yakından alakalı olmayabilir..benim sorum
Bir obje baska bir obje tarafından kullanıldıgında kullanılan objeye “Flag” veya “kullanıldı” gibi bir ozellik atamak istiyorum ki bir daha başka bir obje tarafından kullanılmasın ustuste objeler kullanaılabilir olmasın diye.. bunu nasıl yaparım Yasir bey
şöyle bir kod buldum ama.. manage diye bir şey yaratılamıyor..
public Managed[] managedObjects;
void Start()
{
// Find them if not set already in the editor
this.managedObjects = FindObjectsOfType(typeof(Managed)) as Managed[];
}
void Update()
{
foreach (Managed managed in this.managedObjects)
{
if (managed)
{
// do something
}
}
}
}
Eğer objelerin tag’leri ile bir işlem yapmıyorsanız, kullanılan objelerin
gameObject.tag
değerini örneğin “Finish” yapabilirsiniz. Daha sonra da obje kullanılmış mı kontrol etmek içinobje.CompareTag("Finish")
fonksiyonunu çağırabilirsiniz. Aksi taktirde, kullanılan objeleri “List<GameObject>” veya “HashSet<GameObject>” türünde bir değişkende tutabilirsiniz. Alternatif olarak, KullanilanObje adında yeni bir script oluşturup bunugameObject.AddComponent<KullanilanObje>()
ile kullanılan objelere verebilirsiniz. Obje kullanılmış mı kontrol etmek için deobje.GetComponent<KullanilanObje>() != null
sorgusu yapabilirsiniz.List oluşturdum değer atadım ve sıfırıncı elemente ulaşmak istediğim zaman bu hatayı veriyor.(ulaşmak isteğim değer static)
cannot be accessed with an instance reference; qualify it with a type name instead
Değişken A script’indeyse ve adı b ise, değişkene A.b diye erişin. İlk elemana erişmek için: A.b[0]
List oluşturdum ve sahneden oyun nesneleri listeye ekledim sıfırıncı elemente erişmek istiyorum. Oyun nesnesindeki a scriptin static değişkene nasıl erişebilir.
Static değişkene bahsettiğim gibi ClassIsmi.degiskenIsmi şeklinde erişilir. Hâlâ sıkıntı yaşıyorsanız “c# static değişkenler” şeklinde google araması yaparak oradaki derslere bakmanızı öneririm.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SkeletonAI : MonoBehaviour
{
private GameObject player;
void Start ()
{
player= GameObject.FindWithTag(“Player”).GetComponent();
}
void Update ()
{
transform.LookAt(player.transform);
if(Vector3.Distance(player.transform.position, this.transform.position)<10)
{
Vector3 direction=player.transform.position-this.transform.position;
this.transform.rotation=Quaternion.Slerp(this.transform.rotation,
Quaternion.LookRotation(direction),0.1f);
}
}
}
burada playerin transformunu takip ettiremiyorum yardımcı olurmusunuz.
this.transform.rotation yapmak yerine (aynı şeyi zaten LookAt fonksiyonu ile yapıyorsunuz) “transform.Translate(new Vector3(0,0,5*Time.deltaTime);” satırı ile saniyede 5 metre hızla player’a doğru hareket edebilirsiniz.
Hocam merahab
2 sahnem var ilk sahnemde köşede highscore yazdıracagım ikinci sahnemde oyunum mevcut
ilk sahneme public Text oluşturyorum UI panelden text olusturup ekliyorum ınspectorden atıyorum high score yazılıyor sorun yok sorun surada oluşuyor ikinci sahne bu text game objecti olmadığı için nesneyi bulamıyor ilk ekrana döndüğümde haliyle highsocre bulamadığ için ekrana basımıyor. Bunu inpectorden değilde sciript ile nasıl atama yapabilirim
Kolay gelsin,
Hocam ben 3D Mobil proje üzerinde uğraşıyorum asset store dan hazır sahne aldığım zaman hiçbir kasma olmadan çok akıcı oynayabiliyorum. Ama kendim o free objeleri kullanıp sahne tasarladığımda çok takılma oluyor. Hatta aynı objeleri bile kullansam kasıyor ama o demo sahneyi kullandığımda çok akıcı bir şekilde oynanıyor. Render ayarlarıyla alakalı bir tavsiyeniz var mı? Nasıl düzeltebilirim bu durumu? Demo sahnenin objelerinin aynısını bir kare evin içine koysam bile kasma oluyor çünkü
Kameranın ayarlarına, sahnedeki ışık sayısına ve Window-Lighting Settings’deki ayarlara da bakın. İki sahne arasında bunlar farklılık gösteriyor olabilir. Mümkünse Skybox kullanmayın, gölgeleri kapatın ve ışık sayısına minimuma indirgeyin.
Kolay Gelsin,
Editör ekranında objeleri hareket ettirirken mesela iki tane küpü nasıl üst üste getirebiliriz. x,y ve z ayarlarıyla ayarlamak zamanı çok alıyor. Bir videoda gördüm ancak kısayol tuşunu bilmediğim için soruyorum. Adam kısayol tuşuna basıp objeyi köşesinden tutuyor ve direkt üst üste biniyor yani x,y ve z ile manuel uğraşmıyor. Yardımın için teşekkür ederim.
V (vertex, köşe) tuşuna basılı tutarak yapabilirsiniz.
Merhaba Süleyman Bey,
Oyunumda butona tıkladığımda belirli bir obje bulunduğu konumdan 20 birim yer değiştiriyor ve tekrar tıkladığımda aynı yerine geliyor. Bunu:
transform.positiyon=new vector3(…) yöntemi ile yaptım. Bu yer değiştirmeyi bir anda değilde zamana bölerek yani obje bir güç tarafından o noktaya itiyormuş gibi nasıl yaparım. Yapmak istediğim obje direkt olarak 20 birim kaymak yerine saniyeler içinde gidecek.
Bunun için coroutine kullanabilirsiniz. Örneğin şu dersimdeki ObjeyiKimildat coroutine’ini inceleyebilirsiniz: https://yasirkula.com/2018/11/20/unity-3d-coroutineler/
Kolay gelsin Süleyman Bey,
Mesela sahnemde aynı componenti kullanan 3 tane obje var. Her obje kendi üzerine tıklandığında hareket ediyor vs. Ben kod ile bu 3 objenin aynı anda componentine ulaşabilir miyim? Yani şöyle açıklayayım; Objelerin içerisinde bir bool değişkenim var bu true olduğunda sola doğru gidiyorlar false olduğunda sağa doğru. Kod ile bunların 1 tanesi hariç hepsini istediğim şekilde (true/false) tanımlayabilir miyim? Teşekkür ederim..
Script’inizde 3 tane public değişken tanımlayıp bu 3 objeyi Inspector’dan değişkenlere değer olarak verin derim. Eğer 3 obje oyun esnasında spawn oluyorsa veya başka bir durum varsa onu belirtirseniz alternatif bir çözüm yolu düşünebiliriz.
3 tane değişken olayı amacıma ulaşmamı sağlıyor ancak her seferinde 3 obje olması gerekiyor. Benim bir bölümde 3 bir bölümde 10 tane objem oluyor bunu dinamik yapabilmem için bir tavsiyeniz var mı?
Bir array (mesela GameObject[]) veya list (mesela List<GameObject>) değişken kullanabilirsiniz. Bu değişkene Inspector’dan istediğiniz kadar objeyi değer olarak verebilirsiniz.
merhabalar hocam, böyle bir sorun ile karşı karşıyayım. https://youtu.be/i45ikEs9qBo
8 saniyelik video.
Video da gördüğünüz gibi adobe animate ve adobe after da hiçbir sıkıntı yok. Ama unity de titreşimli oluyor. Acaba adobe animate üzerinden farklı format ilemi render almam gerekiyor? Yardımcı olursanız çok sevinirim video 8 saniye fark çok anlaşılıyor karşılaştırma yaptım teşekkürler şimdiden.
Büyük ihtimalle pivot ile ilgili bir sıkıntı. Sorunu daha rahat tespit etmeme yardımcı olması için bu animasyonu yasirkula@gmail.com‘a atabilirseniz kendim Unity içerisinde test edebilirim.
İyi Günler Süleyman Bey,
Acaba elinizde kamera ile ilgili bir script var mı?
Android oyun yapmaya çalışıyorum 3D şeklinde ve karakterimin kamerasını sağa sola çevirmek için bir scripte ihtiyacım var yani ekranda elimizi kaydırarak kameranın açısını/karakterin yönünü değiştirmem lazım. Yardımlarınızı bekliyorum kolay gelsin..
Şu script ile kameranın hedefi yumuşak bir şekilde takip etmesini sağlayabilirsiniz:
Yasir bey
Unity android için yaptığım oyunda karakter titriyor( yalpalanıyor ) ve nesnelerin kaplamaları yarılıyor.
oyun fps si ortalama 80 fps nasıl dzeltebilirim yardımcı olurmusun . Teşekkurler
Eğer kamera hareket ederken karakter titriyorsa belki titreyen şey kameradır. Karakteri Update’te hareket ettiriyorsanız kamerayı LateUpdate’te, karakteri FixedUpdate’te hareket ettiriyorsanız kamerayı da FixedUpdate’te hareket ettirin. Kaplamaların yarılmasını örnek bir resimle gösterebilir misiniz?
Yasir bey
Kamerayı karakterin içine attım .
Karakterin hareket script’inde bir sıkıntı vardır tahminimce. Script’in tüm alakasız kısımlarını silip script’i burada paylaşırsanız inceleyebilirim.
Merhaba, ben bir prefab’dan canvas içindeki imageyi SetActive(true) yapacağım. Önce public olarak bir GameObje değişken tanımlıyorum oradan prefab içindeki scripe sürüklemem lazım fakat hierarhcy panelinde sadece prefab gözüküyor. Ben bu prefab dan nasıl imageyi setActive yapacağım? teşekkürler 🙂
Bu durumda yazıda bahsettiğim “Hedef script’e kod vasıtasıyla ulaşmak” yöntemini kullanmanız lazım. Ben olsam oradaki “static instance” değişkenli yolu kullanırdım.
public Canvas canvasb;
canvasb = GameObject.FindGameObjectWithTag(“Canvas”).GetComponent();
bu kodu denediğimde NullReferenceException bu hatayı alıyorum
Kodu çalıştırdığınız esnada sahnede Canvas tag’ına sahip bir obje bulunamadı diyor. Objenin isminin değil tag’ının Canvas olduğundan ve objenin o anda inaktif değil aktif olduğundan emin olun.
hocam bir scripten başka bir scripte getcomponet ile ekliyorum sonra hareket.bullet = true diyorum ve nullreferanceexeption hatası alıyorm nasıl çözerim
GetComponent’i çağırdığınız esnada objede o component henüz yokmuş olabilir. Ama daha büyük bir olasılıkla, GetComponent ile değişkene attığınız component’e sahip obje yok olmuştur (Destroy ile veya sahneler arası geçiş esnasında) ve bu yüzden hata alıyorsunuzdur.
Hocam sizin yazıları Ali kaya denilen şahış izinsiz olarak kendi blogunda yayınlıyor ve Yazar olarak kendi adını yazıyor. https://alikaya.info/unity3d-ogrenimi-ders-3-2017/ buyurun link bu diğer derslerine bakmadım ama vardır büyük ihtimalle.
Bilgilendirdiğiniz ve ilginiz için teşekkür ederim.
Kolay gelsin hocam,
Sayfanı beğenerek takip ediyorum ve başarılarının devamını diliyorum. Konu ile alakalı değil ama internet üzerinde bulamadığım bir sorunun cevabını sormak istiyorum belki yanlış araştırdığım için bulamadım bilmiyorum ama yardımcı olabilirsen minnettar olurum.
Hocam, ana sayfamda; başlat, ayarlar ve oyundan çık butonu var. Bu butonların anchorlarını ayarlayarak sayfaya göre şekillenmesini sağladım. Ancak içlerinde bulunan yazılar sayfa büyüyünce çok küçük oluyor ve okunmuyor. Buton boyutlarında sorun yok sayfaya göre şekilleniyor ama içerisindeki yazının fontunu sayfaya göre bir türlü ayarlayamadım. Yardımını bekliyorum, saygılar..
İlk önerim Canvas objenizin Canvas Scaler’ının Scale Mode’u ile oynamanız. Gerekirse de yazının “Best Fit” ayarını açarak dinamik olarak boyutunun değişmesini sağlayabilirsiniz.
başka bir scriptden başka bir objenin ontriggerenter2d sini nasıl kullanabilirim
O fonksiyonu public yapıp, dersteki değişkene ulaşma yöntemlerinin aynısını uygulayarak fonksiyona ulaşabilirsiniz (yani A script’inin b değişkenine A.b ile erişecek idiyseniz, onun yerine istediğiniz fonksiyona A.OnTriggerEnter2D(…) ile erişebilirsiniz).
Tek bir hedefim var oda mobil oyun için, ama bir türlü c# dilinin mantığını kavrayamadım.
elinizde varmıdır bir ders veya kaynak?
Yani demek istediğim C# dilini (mantığını) hiçbir bilgisi olmayan birine nasıl anlatabilirsiniz?
bu soruya cevap 🙂
Benim önerim C#’ın temellerini Unity’den bağımsız olarak öğrenmeniz çünkü Unity ile C# programlamaya başlamak konusunda Türkçe çok iyi kaynak bulmakta belki zorlanırsınız ama “c# giriş dersleri -visual” diye arama yaparsanız, Türkçe ve kaliteli C# başlangıç dersleri bulabilirsiniz. Bu dersler ile C# ile programlamanın temelini iyice kavradığınıza inandıktan sonra Unity’e geçiş yapabilirsiniz.
Sadece şuna dikkat edin: C# ile konsol tabanlı ve pencere tabanlı (visual) uygulamalar yapılabilir, siz başlangıç seviyesinde olduğunuz için konsol tabanlı derslere bakın, visual C# yazan derslere hiç bakmayın. Zaten temeli kaptıktan sonra görsel kısmı Visual C# ile değil Unity’de C# kullanarak yapacaksınız. Konsol tabanlı derslerin kodlarında
Console.WriteLine
gibi satırlar görürsünüz.Hocam scripti çağırıyorum çağırdığım scriptten public olmasına rağmen değişkenlere de metotlarada ulaşamıyorum. Sizce sorun ne olabilir ?
Değişkenlere ulaşmaya çalıştığınızda aldığınız hata mesajı nedir?
Tanımlandı ancak kullanılmadı gibi bir hata ve değişkenlerim static
Script’i nasıl çağırdığınızı ve çağırdığınız script’teki public değişkene nasıl ulaşmaya çalıştığınızı görebilir miyim?
Yardımcı olmaya çalıştığınız için teşekkür ederim benim statik değişken olduğu için player.staticdeger şeklinde çağırdım hallettim 🙂
Öncelikle merhaba hocam benimde bir sorum olucaktı Unity 3d ile bir oyun geliştiriyorum bu oyununda başlangıçta eğer daha önceden takım olusturulmadiysa takım oluştur sayfasına geçicek daha önceden takım olusturduysa direk ana menüye geçicek birde takım oluşturduğunda takımın logosu adı felan bunları nasıl ana menüde gösterebilirim bunun ile ilgili bir yazınız varsa linkini atabilirmisiniz yada dili farketmez bir ders varsa atarsanız çok sevinirim ne zamandır googlda arıyorum bir türlü bulamıyorum nasıl arayacagimi da bilemiyorum 😊 bu konuda yardimci olursaniz cok sevinirim.
Kendiniz araştırırken “unity persist data” şeklinde arayabilirsiniz. Unity oyunlarında veri kaydetmenin en kolay yolu PlayerPrefs’tir. PlayerPrefs ile kaydettiğiniz veriler oyun kapansa da değerini korur (ama oyun cihazdan silinirse değerler kaybolabilir). Diğer alternatiflerden bazıları JsonUtility, XMLSerializer ve BinaryFormatter’dır. Bunlarla veriyi bir dosyaya çeşitli formatlarda kaydedebilir, daha sonra veriyi geri yükleyebilirsiniz.
Takımın adı gibi basit şeyleri PlayerPrefs ile çok hızlı bir şekilde kaydedebilirsiniz ama eğer logoyu kullanıcı kendisi bilgisayarından seçecekse (yani var olan bir kaç logo arasından tercih yapmayacaksa), o zaman bu logonun bir kopyasını Application.persistentDataPath klasöründe tutup onun konumunu PlayerPrefs veya bahsettiğim diğer metotlar ile kaydedebilirsiniz. Daha sonra bu konumdan logoyu Texture2D olarak yüklemek için, Texture2D.LoadImage fonksiyonunu kullanabilirsiniz.
Merhaba yasir bey. İyisinizdir umarım 🙂 Bir sorum olacak bu konuyla pek alakası yok ama nereye yazacağımı bilemedim. Ben bir mobil oyun yapıyorum. Oyun başında logo geldikten sonra loading ekranı gelicek. Bu loading ekranı 3-4 saniye tutucam. Bu sürede arkaplanda nesneler objeler yüklenicek. Bir nevi optimizasyon. Bunu nasıl yaparım ? Bir kaynak var mıdır İngilizce türkçe ? Ya da siz daha önce bu konuda makale yazdıysanız link atabilir misiniz ? Bu benim için çok önemli 🙂 İyi günler iyi çalışmalar
İsterseniz şu dersime göz atabilirsiniz: https://yasirkula.com/2015/10/03/unity-3d-basit-bir-loading-ekrani-yapimi/
Veya “Unity loading screen” şeklinde arama yapınca da çeşitli video dersler bulabilirsiniz. Benim dersim Javascript’i kullanıyor, onu en yakın zamanda C#’a çevireceğim.
Yaşadığını öğrendiğimiz için Mutluyuz : D
Teşekkürler 😀
Siteden de ki içerikleri yedeklemeyi lütfen unutma 🙂 bildiğin ansiklopedi yatıyor burada