İlan
04 Haz 2026 26 çevrimiçi üye Duyurular
Ana Sayfa Oyun Geliştirme
Ana Sayfa Forum Oyun Geliştirme Unity Komut Hızlı Erişim Yöntemi...
İlan Yan banner placeholder

Unity Komut Hızlı Erişim Yöntemi

CeaDigital 16.04.2026 23:18 644 görüntüleme 1 cevap
Son Mesaj
CeaDigital
Üye
Üye
Katılım18 Ara 2025
Konular9
Mesajlar110
Elmas Konular0
Başarım0
ZirveCoin 0
Ticaret Puanı
+0 -0
16.04.2026 23:18 #1
https://www.raywenderlich.com/

Georgi Ivanov tarafından1 Eylül 2016 · Makale (40 dakika) · Başlangıç


demo
Unity'nin gücünün çoğu, zengin betik dili C#' dadır . Kullanıcı girdisini işlemek, sahnedeki nesneleri işlemek, çarpışmaları tespit etmek, yeni GameObject'ler oluşturmak ve oyun mantığınıza yardımcı olmak için sahnenin etrafına yönlü ışınlar atmak için kullanabilirsiniz. Kulağa korkutucu gelebilir, ancak Unity, bu görevleri acemi geliştiriciler için bile bir esinti haline getiren iyi belgelenmiş API'ler sunar!
Bu eğitimde, düşmanların ortaya çıkmasını, oyuncu kontrolünü, mermileri ateşlemeyi ve oyunun diğer önemli yönlerini ele almak için Unity komut dosyası kullanan yukarıdan aşağıya bir nişancı oluşturacaksınız.
Not : Bu eğitimde, C# veya benzeri programlama dillerinde zaten biraz deneyiminiz olduğu ve Unity'nin arayüzü ve iş akışı hakkında bilgi sahibi olduğunuz varsayılmaktadır. Bilgi tazelemeye ihtiyacınız varsa, ayrıntılı Unity'ye Giriş eğitimimize göz atın .
Bu eğitim, Unity 5.3 veya üstü için yazılmıştır. Sen Unity son sürümünü indirebilirsiniz burada .
Unity, UnityScript ve Boo'yu da desteklerken, C# çoğu geliştiricinin kullanma eğiliminde olduğu programlama dilidir ve bunun iyi bir nedeni vardır. C#, dünya çapında milyonlarca geliştirici tarafından uygulama, web ve oyun geliştirme için kullanılmaktadır ve size yardımcı olacak çok sayıda bilgi ve öğretici bulunmaktadır.

Başlarken​

BlockBuster başlangıç projesini indirin , sıkıştırmasını açın ve oluşturulan klasörü Unity'de açın.
Açıldıktan sonra görmeniz gerekenler:
BaşlangıçSahnesi
Sahne görünümünde etrafa bir göz atın . Oyun için savaş alanı olacak küçük bir arena, bir kamera ve bir ışık var. Düzeniniz ekran görüntüsündekinden farklıysa, sağ üstteki açılır menüyü seçin ve 2'ye 3 olarak değiştirin .
Ekran Görüntüsü 2016-03-28, 2.38.37 PM
Kahramansız bir oyun nedir? İlk göreviniz, sahnedeki oyuncuyu temsil edecek bir GameObject oluşturmaktır.

Oyuncu Oluşturma​

Hiyerarşi yılında tıklayın Oluştur düğmesini basıp Sphere gelen 3D bölümünde. Küreyi (X:0, Y:0.5, Z:0) konumuna getirin ve Oyuncu olarak adlandırın :
Oyuncu Küresi
Unity , GameObject'lerini oluşturmak için bir varlık-bileşen sistemi kullanır . Bu, tüm GameObject'lerin, kendisine davranış ve özelliklerini vermek için eklenebilecek bileşenler için kaplar olduğu anlamına gelir. Unity'de yerleşik olarak bulunan bileşenlere birkaç örnek:
  • Transform : Her GameObject bu bileşenle birlikte gelir. Bir GameObject'in konumunu, dönüşünü ve ölçeğini tutar.
  • Box Collider : Çarpışmaları tespit etmek için kullanılabilen küp şeklinde bir çarpıştırıcı.
  • Mesh Filtresi : Bir 3B modeli göstermek için kullanılan ağ verileri.

Oyuncu GameObject sahnedeki diğer nesnelerle çarpışmaları yanıt vermek gerekecektir.
Bunun gerçekleşmesi için Hiyerarşi penceresinde Oynatıcıyı seçin ve Denetçi penceresinde Bileşen Ekle düğmesini tıklayın. Açılan menüden Fizik > Rigidbody'yi seçin , bu, Player'a Unity'nin fizik motorunu kullanabilmesi için bir Rigidbody bileşeni ekler.
Set: Böyle Rigidody değerlerini ayarlayın Drag için 1 , Açısal Drag için 0 ve kontrol Y yanındaki onay kutusunu Freeze Pozisyon .

Bu, Player'ın yukarı ve aşağı hareket edememesini ve dönerken ilave sönümleme olmamasını sağlayacaktır.

Oyuncu Hareket Komut Dosyası Oluşturma​

Artık Player hazır olduğuna göre, klavyeden girdi alacak ve Player'ı hareket ettirecek komut dosyasını oluşturma zamanı.
Proje penceresinde, Oluştur düğmesine tıklayın ve Klasör öğesini seçin . Yeni klasöre Komut Dosyaları adını verin ve içinde Player adlı bir alt klasör oluşturun . Player klasörünün
içinde Oluştur düğmesini tıklayın ve C# Script öğesini seçin . Yeni komut dosyanıza PlayerMovement adını verin . Sıra şöyle görünür:
Klasör Yapısı
Not: Bunun gibi klasörleri kullanmak, her şeyi rollerine göre düzenlemeyi kolaylaştırır ve dağınıklığı azaltır. Player'ın kullanması için birkaç komut dosyası oluşturacaksınız, böylece kendi klasörünü vermeniz mantıklı olacaktır.
PlayerMovement.cs komut dosyasını çift tıklayın . Bu, komut dosyası yüklenmiş olarak tercih ettiğiniz kod düzenleyiciyi açacaktır. Unity, tüm platformlarda önceden yüklenmiş MonoDevelop ile birlikte gelir ve Windows kullanıcıları, Visual Studio'yu yüklemeyi ve bunun yerine yükleyiciyi çalıştırırken bunu kullanmayı seçebilir.
Bu öğretici, MonoDevelop kullandığınızı varsayar, ancak Visual Studio kullanıcılarının herhangi bir sorun yaşamadan takip edebilmeleri gerekir.
Seçtiğiniz editör açıldığında, aşağıdakilerle karşılaşacaksınız:

Bu, Unity'nin yeni komut dosyaları için oluşturduğu varsayılan sınıftır. MonoBehaviourBu betiğin oyun döngüsünde çalışmasını sağlayan ve belirli olaylara tepki vermek için ek işlevselliğe sahip olmasını sağlayan temel sınıftan türetilmiştir . iOS dünyasından geliyorsanız, bu nesne bir UIViewController. Unity, komut dosyası çalışırken önceden belirlenmiş bir sırada birkaç yöntemi çağırır. İşte en yaygın olanlardan birkaçı:
  • Start(): Bu yöntem, komut dosyası ilk güncellemesini almadan hemen önce çağrılır.
  • Update(): Oyun çalışırken ve komut dosyası etkinken, bu yöntem her karede tetiklenir.
  • OnDestroy(): Bu metot, bu betiğin bağlı olduğu GameObject yok edilmeden hemen önce çağrılır.
  • OnCollisionEnter(): Bu betiğin eklendiği çarpıştırıcı veya katı cisim başka bir çarpıştırıcıya veya katı cisme dokunduğunda bu yöntem çağrılır.
Olayların tam listesi için Unity'nin MonoBehaviours ile ilgili belgelerine bakın .
Bu iki satırı Start()yöntemin üzerine ekleyin :
halka açık şamandıra ivmesi;
genel şamandıra maxSpeed;

Bu şöyle görünmelidir:

Bunlar, genel değişken bildirimleridir ; bu, bu değişkenlerin Müfettiş'te görüneceği ve komut dosyası ile düzenleyici arasında gidip gelmek zorunda kalmadan ince ayar yapılabileceği anlamına gelir. hızın zamanla
accelerationne kadar Player'sarttığını açıklar . maxSpeed"hız sınırı"dır.
Bunun hemen altında, aşağıdaki değişkenleri bildirin:
özel Rigidbody rijitBody;
özel KeyCode[] inputKeys;
özel Vector3[] yönForKeys;

Özel değişkenler Müfettiş aracılığıyla ayarlanamaz, bunları uygun zamanda başlatmak geliştiricilerin sorumluluğundadır. Player GameObject'e eklenmiş
rigidBodyolan Rigidbody bileşenine bir referans tutacaktır .
inputKeysgirişi algılamak için kullanılacak bir dizi anahtar koddur. yönlü verileri tutacak
directionsForKeysbir dizi Vector3değişkeni tutar .
Start()Yöntemi aşağıdakiyle değiştirin :
geçersiz Başlangıç () {
inputKeys = new KeyCode[] { KeyCode.W, KeyCode.A, KeyCode.S, KeyCode.D };yönForKeys
= new Vector3[] { Vector3.forward, Vector3.left, Vector3.back, Vector3.right };
sertBody = GetComponent<Rigidbody>();
}

Bu kod parçası, her bir tuş için karşılık gelen yönleri birbirine bağlar; örneğin, W'ye basmak nesneyi ileriye doğru hareket ettirir. Son satır, ekli Rigidbody bileşenine bir referans alır ve rigidBodydaha sonra kullanmak üzere değişkene kaydeder .
Player'ı gerçekten hareket ettirmek için klavyeden giriş yapmanız gerekir.
Yeniden adlandırma Update()için FixedUpdate()ve aşağıdaki kodu ekleyin:
// 1
geçersiz Sabit Güncelleme () {
for ( int i = 0 ; i < inputKeys.Length; i++){
var key = inputKeys;

// 2
if (Input.GetKey(anahtar)) {
// 3
Vector3 hareketi = yönlerForKeys * hızlanma * Time.deltaTime;
}
}
}

Burada olan birkaç önemli şey var:
  1. FixedUpdate()kare hızından bağımsızdır ve Rigidbodies ile çalışırken kullanılmalıdır. Mümkün olduğu kadar hızlı koşmak yerine, bu yöntem sabit aralıklarla tetiklenecektir.
  2. Bu döngü, giriş tuşlarından herhangi birine basılıp basılmadığını kontrol eder.
  3. Basılan tuşun yönünü alın, hızlanma ve son kareyi tamamlamak için geçen saniye sayısıyla çarpın. Bu, Playernesneyi hareket ettirmek için kullanacağınız bir yön vektörü (X, Y ve Z eksenlerindeki hız) üretir .
Oyun programlamada yeniyseniz, neden ile çarpmanız gerektiğini kendinize sorabilirsiniz Time.deltaTime. Oyun çalışırken kare hızı (veya saniyedeki kare sayısı) donanıma ve altındaki strese bağlı olarak değişecektir, bu durum güçlü makinelerde işlerin çok hızlı olmasına, daha zayıf makinelerde ise çok yavaş olmasına neden olarak istenmeyen davranışlara neden olabilir. Genel kural, her (sabit) karede bir eylem gerçekleştirdiğinizde, ile çarpmanız gerektiğidir Time.deltaTime.
Aşağıdaki yöntemi aşağıya ekleyin FixedUpdate():
void movePlayer ( Vector3 hareketi ) {
if (rijidBody.velocity.magnitude * hızlanma > maxSpeed) {
sertBody.AddForce(hareket * -1 );
} başka {
sertBody.AddForce(hareket);
}
}

Yukarıdaki yöntem, bindirme cismine kuvvet uygulayarak hareket etmesine neden olur. Mevcut hız aşılırsa maxSpeed, kuvvet oyuncuyu yavaşlatmak için ters yönde hareket eder ve maksimum hızı etkili bir şekilde sınırlar.
içinde FixedUpdate(), kapanış ayracından önce if-statementaşağıdaki satırı ekleyin:
movePlayer(hareket);


Mükemmel! Bu betiği kaydedin ve Unity düzenleyicisine dönün. Proje penceresinde, sürükle PlayerMovement üzerine senaryoyu Player Hiyerarşi içeride.
Bir GameObject'e bir komut dosyası eklemek, bir bileşenin örneğini oluşturur; bu, onu eklediğiniz GameObject için tüm kodun yürütüleceği anlamına gelir.
Kullanım Müfettiş seti için Acceleration için 625 ve Max Hız için 4375 :
AssignScript
Sahneyi çalıştırın ve Player'ı WASD tuşlarıyla hareket ettirin:
Top, oyuncu kontrolü ile hareket edebilir
Bu sadece birkaç satır kod için oldukça iyi bir sonuç! :]
Ancak, bariz bir sorun var - oyuncu hızla gözden kaybolabilir, bu da kötü adamlarla savaşmayı biraz zorlaştırır.

Kamera Komut Dosyasını Oluşturma​

Gelen Scripts klasörü olarak adlandırılan yeni komut dosyası oluşturmak CameraRig ve eklemek Ana Kamera . Adımları anlamak için biraz yardıma mı ihtiyacınız var? Çözüm için aşağıdaki ipucunu kontrol edebilirsiniz.

Ortaya çıkartmak

Şimdi, yeni oluşturulan CameraRigsınıfın içinde , Start()yöntemin hemen üzerinde aşağıdaki değişkenleri oluşturun :
genel şamandıra moveSpeed;
genel GameObject hedefi;

özel Dönüşüm teçhizatıDönüştür;

Tahmin edebileceğiniz gibi moveSpeed, kameranın hedefi takip etme hızıdır - bu, sahne içindeki herhangi bir oyun nesnesi olabilir.
İçine Start()aşağıdaki satırı ekleyin:
rigTransform = this .transform.parent;

Bu kod, sahne hiyerarşisindeki ana Camera nesnesinin dönüşümüne bir referans alır. Bir sahnedeki her nesne, bir nesnenin konumunu, dönüşünü ve ölçeğini tanımlayan bir Dönüştürme özelliğine sahiptir .
KameraTeçhizatıHiyerarşi
Aynı komut dosyasında aşağıdaki yöntemi ekleyin:
geçersiz Sabit Güncelleme () {
if (hedef == boş ){
dönüş ;
}

rigTransform.position = Vector3.Lerp(rigTransform.position, target.transform.position,
Time.deltaTime * moveSpeed);
}

CameraRigHareket kodu içinde olandan biraz daha basittir PlayerMovement. Bunun nedeni, bir Rigidbody'ye ihtiyacınız olmamasıdır; rigTransform ve hedef konumları arasında basitçe enterpolasyon yapmak yeterlidir.
Vector3.Lerp()uzayda [0, 1]iki nokta ve iki uç nokta boyunca bir noktayı tanımlayan aralığında bir kayan nokta alır. Sol uç nokta , 0sağ uç nokta ise 1. Geçen 0.5etmek Lerp()hem uç nokta arasında tam bir noktaya dönecekti.
Bu, rigTransformbiraz gevşeme ile hedef konuma daha yakın hareket eder . Kısacası – kamera oyuncuyu takip eder.
Unity'ye dön. Main Cameraiçinde hala seçili olduğundan emin olun Hierarchy. Müfettiş olarak, set Taşı Hız için 8 ve Hedef için Player :
RigHookup
Oyunu çalıştırın ve sahnede hareket edin; kamera nereye giderse gitsin hedef dönüşümü sorunsuz bir şekilde takip etmelidir.
Kamera oyuncuyu takip eder.

Düşman Yaratmak​

Düşmansız bir nişancı oyununu yenmek kolay ama biraz sıkıcı olurdu. :] Üst menüden GameObject\3D Object\Cube öğesine tıklayarak bir düşman küpü oluşturun . Küpünüzü Düşman olarak yeniden adlandırın ve bir Rigidbody bileşeni ekleyin .
Müfettiş, ilk Küp en set Transform için (0, 0.5,4) . Gelen Sınırlamalar rijit cisim bileşeninin bölümünde, kontrol Y onay kutusunu Freeze pozisyonu kategorisinde.
Güncellenmesi gereken özellikler ekran görüntüsünde vurgulanmıştır.
Mükemmel - şimdi düşmanlarınızı tehditkar bir şekilde hareket ettirmek için. Adlı bir komut dosyası oluşturun Düşman içinde komut dosyaları klasöründe. Şimdiye kadar bu konuda bir profesyonel olmalısınız, ancak değilseniz, referans için öğreticide daha önce verilen talimatları kontrol edin.
Ardından, sınıfın içine aşağıdaki genel değişkenleri ekleyin:
genel şamandıra moveSpeed;
Kamu int sağlığı;
kamu int hasarı;
public Transform targetTransform;

Muhtemelen bu değişkenlerin neyi temsil ettiğini çok fazla zorlanmadan anlayabilirsiniz. Daha moveSpeedönce kamera teçhizatını oluşturmak için kullandınız ve burada da aynı etkiye sahip. healthve damagebir düşmanın ne zaman ölmesi gerektiğini ve ölümünün Player. Son olarak, targetTransformreferanslar Player'sdönüşümü.
Oyuncudan bahsetmişken, düşmanın yok etmek istediği tüm Oyuncu iyiliğini temsil edecek bir sınıf oluşturmanız gerekecek.
Proje Tarayıcısında, Player klasörünü seçin ve Player adında yeni bir komut dosyası oluşturun ; bu komut dosyası çarpışmalara tepki verecek ve Oyuncunun sağlığını takip edecektir. Düzenlemek için komut dosyasını çift tıklayın.
Player'ın sağlığını depolamak için aşağıdaki genel değişkeni ekleyin:
public int sağlık = 3 ;

Bu, sağlık için varsayılan bir değer sağlar, ancak Müfettiş'te de değiştirilebilir.
Çarpışmaları işlemek için aşağıdaki yöntemleri ekleyin:
void collidedWithEnemy ( Düşman düşman ) {
// Düşman saldırı kodu
if (sağlık <= 0 ) {
// Yapılacak
}
}

geçersiz OnCollisionEnter ( Collision col ) {
Düşman düşman = col.collider.gameObject.GetComponent<Düşman>();
çarpıştıWithEnemy(düşman);
}

OnCollisionEnter()çarpıştırıcılı iki katı cisim dokunduğunda tetiklenir. CollisionArgüman temas noktaları ve darbe hızları gibi şeyler hakkında bilgi içerir. Bu durumda, yalnızca çarpışan nesnenin Düşman bileşeniyle ilgilenirsiniz, böylece collidedWithEnemy()saldırı mantığını çağırabilir ve yürütebilirsiniz - daha sonra ekleyeceksiniz.
Enemy.cs'e geri dönün ve aşağıdaki yöntemleri ekleyin:
geçersiz Sabit Güncelleme () {
if (targetTransform != null ) {
this .transform.position = Vector3.MoveTowards( this .transform.position, targetTransform.transform.position, Time.deltaTime * moveSpeed);
}
}

public void TakeDamage ( int damage ) {
sağlık -= hasar;
if (sağlık <= 0 ) {
Destroy( bu .gameObject);
}
}

herkese açık geçersiz Saldırı ( Oyuncu oyuncu ) {
player.health -= bu .hasar;
Destroy( bu .gameObject);
}

Zaten aşinasınız FixedUpdate(), küçük fark, MoveTowards()yerine kullanıyor olmanızdır Lerp(). Bunun nedeni, Düşmanın her zaman aynı hızda hareket etmesi ve hedefe yaklaşırken gevşememesi gerektiğidir. Bir düşmana mermi isabet ettiğinde TakeDamage(); Düşman 0 sağlığa ulaştığında kendini yok edecektir. Attack()benzer - hasar verir Playerve sonra düşman kendini yok eder.
Geri dönün Player.cs ve collidedWithEnemy()yerine Enemy attack codeaşağıdaki yorumunu:
düşman.Attack( bu );

Oyuncu hasar alacak ve bu süreçte düşman kendi kendini imha edecek.
Unity'ye geri dönün. Takın Düşman senaryoyu için Düşman nesne ve Inspector'da, Düşman üzerine aşağıdaki değerleri ayarlayın:
  1. Hareket Hızı : 5
  2. Sağlık : 2
  3. Hasar : 1
  4. Hedef Dönüşümü : Oyuncu
Şimdiye kadar tüm bunları kendin yapabilmiş olmalısın. Kendi başınıza deneyin ve sonucu aşağıdaki GIF ile karşılaştırın:

Ortaya çıkartmak

Oyunda, Oyuncu ile çarpışan bir Düşman, geçerli bir düşman saldırısı oluşturur. Unity'nin fiziğiyle çarpışmaları tespit etmek neredeyse önemsiz bir iştir.
Son olarak, Player komut dosyasını Hiyerarşideki Player'a ekleyin .
Oyunu çalıştırın ve konsola göz kulak olun:
Düşman çarpışmaları konsol hataları yaratır
Düşman 'a ulaştığında, Playersaldırıyı başarılı bir şekilde gerçekleştirir ve Oyuncunun sağlık değişkenini 2'ye düşürür. Ancak NullReferenceExceptionkonsolda, Playerkomut dosyasına işaret eden bir fırlatma var :
CollisionException
Aha - Playersadece düşmanlarla değil, aynı zamanda Arena gibi oyun dünyasının diğer bölümleriyle de çarpışabilir. Bu oyun nesneleri bir yok Enemy scriptve bu nedenle döner .GetComponent()null
Player.cs'i açın . içinde OnCollisionEnter(), collidedWithEnemy()bir ififadeye sarın :
if (düşman) {
çarpıştıWithEnemy(düşman);
}

Artık boş yok!

Prefabriklerle Çalışmak​

Sadece etrafta koşuşturmak ve düşmanlardan kaçınmak oldukça tek taraflı bir oyundur. Oyuncuyu savaş için silahlandırma zamanı.
Hiyerarşide Oluştur düğmesini tıklayın ve 3B Nesne/Kapsül öğesini seçin . Bunun adı Mermi ve şu değerleri dönüştürmek vermek:
  1. Konum: (0, 0, 0)
  2. Döndürme: (90, 0, 0)
  3. Ölçek: (0.075, 0.246, 0.075)
Varsayılan değerleri ayarlama
Oyuncu her atış yaptığında, bir örneğini ateşler Projectile. Bunu yapmak için, bir Prefab. Sahnede zaten sahip olduğunuz nesnelerin aksine, Prefabrikler oyun mantığı tarafından isteğe bağlı olarak oluşturulur.
Varlıklar altında Prefabrik adlı yeni bir klasör oluşturun . Şimdi Projectile nesnesini bu klasöre sürükleyin . İşte bu: bir Prefabrik'iniz var!
Prefabrik Oluşturma
Prefabrik'inizin biraz komut dosyasına ihtiyacı olacak. Projectile adlı Komut Dosyaları klasörü içinde yeni bir komut dosyası oluşturun ve buna aşağıdaki sınıf değişkenlerini ekleyin:
genel şamandıra hızı;
kamu int hasarı;

Vector3 çekimYön;

Bu öğreticide şimdiye kadarki herhangi bir hareketli nesne gibi, bu da savaş mantığının bir parçası olduğu için hız ve hasar değişkenlerine sahip olacak. shootDirectionNereye vektör belirler Projectilegidecek.
Aşağıdaki yöntemleri sınıf içinde uygulayarak bu vektörü çalıştırın:
// 1
geçersiz Sabit Güncelleme () {
this .transform.Translate(shootDirection * hız, Space.World);
}

// 2
public void FireProjectile ( Ray shootRay ) {
this .shootDirection = shootRay.direction;
bu .transform.position = shootRay.origin;
}

// 3
geçersiz OnCollisionEnter ( Collision col ) {
Düşman düşman = col.collider.gameObject.GetComponent<Düşman>();
if (düşman) {
düşman.TakeDamage(hasar);
}
Destroy( bu .gameObject);
}

İşte yukarıdaki kodda neler oluyor:
  1. ProjectileFarklı bu oyunda her şeyden daha hareket eder. Bir hedefi veya zaman içinde kendisine uygulanan bir gücü yoktur; bunun yerine, tüm yaşam döngüsü boyunca önceden belirlenmiş bir yönde hareket eder.
  2. Burada Prefabrik'in başlangıç konumunu ve yönünü ayarlarsınız. Bu Rayargüman oldukça gizemli görünüyor, ancak yakında nasıl hesaplandığını öğreneceksiniz.
  3. Bir mermi bir düşmanla çarpışırsa, kendisini çağırır TakeDamage()ve yok eder.
Sahne Hiyerarşisinde, Projectile komut dosyasını Projectile GameObject öğesine ekleyin . Set Speed için 0,2 ve Hasar için 1 , ardından Uygula Müfettiş üst yakınında bulunan düğmeyi. Bu, az önce yaptığınız değişiklikleri bu hazır yapının tüm örneklerine uygulayacaktır.
Denetçide değerleri ayarlama
Kaldır Mermi sahne Hiyerarşi nesneyi - Artık ihtiyaç yoktur.

Ateşleme Mermileri​

Artık hareket edebilen ve hasar verebilen bir prefabrike sahip olduğunuza göre, ateş etmeye hazırsınız.
İçinde Oyuncu klasöründe , adlı yeni komut dosyası oluşturmak PlayerShooting ve eklemek Player sahnede. Sınıfın içinde aşağıdaki değişkenleri bildirin:
genel Mermi mermiPrefabrik;
genel LayerMask maskesi;

İlk değişken, daha önce oluşturduğunuz Mermi Hazır Yapısına bir referans içerecektir. Player'ınız her mermi attığında, bu Hazır Yapıdan yeni bir örnek oluşturacaksınız. maskDeğişken filtre GameObjects için kullanılır.
Bekle, Rays'i kullanmak mı? Bu büyücülük nedir?
Hayır, kara büyü yok - oyununuzda belirli bir yönde bir çarpıştırıcı olup olmadığını bilmeniz gereken zamanlar vardır. Bunu yapmak için Unity, belli bir noktadan sizin belirlediğiniz bir yöne görünmez bir ışın gönderebilir. Işınla kesişen çok sayıda GameObject ile karşılaşmanız muhtemeldir, bu nedenle bir maske kullanmak istenmeyen nesneleri filtrelemenize olanak tanır.
Raycast'ler inanılmaz derecede faydalıdır ve çeşitli amaçlar için kullanılabilir. Genellikle başka bir oyuncunun bir mermiyle vurulup vurulmadığını test etmek için kullanılırlar, ancak bunları fare işaretçisinin altında herhangi bir geometri olup olmadığını test etmek için de kullanabilirsiniz. Raycast'ler hakkında daha fazla bilgi edinmek için Unity sitesindeki bu Unity canlı eğitim videosunu izleyin .
Aşağıdaki görüntü, bir küpten bir koniye bir ışın dökümünü göstermektedir. Işının üzerinde bir simge küresi maskesi olduğundan, GameObect'i yok sayar ve koni üzerinde bir isabet bildirir:
Bir raycast'in iş başında gösterilmesi
Şimdi kendi ışınlarını ateşlemenin zamanı geldi.
PlayerShooting.cs dosyasına aşağıdaki yöntemi ekleyin :
void shoot ( RaycastHit hit ) {
// 1
var projectile = Instantiate(projectilePrefab).GetComponent<Projectile>();
// 2
var pointAboveFloor = hit.point + new Vector3( 0 , this .transform.position.y, 0 );

// 3
var yön = pointAboveFloor - transform.position;

// 4
var shootRay = new Ray( bu .transform.position, yön);
Debug.DrawRay(shootRay.origin, shootRay.direction * 100.1f , Color.green, 2 );

// 5
Physics.IgnoreCollision(GetComponent<Collider>(), projectile.GetComponent<Collider>());

// 6
mermi.FireProjectile(shootRay);
}

İşte yukarıdaki kodun yaptığı şey:
  1. Bir mermi Hazır Yapısını Projectilebaşlatır ve başlatılabilmesi için bileşenini alır .
  2. Bu nokta her zaman şöyle görünür (x, 0.5, z). X ve Z, fare tıklama konumundan gelen ışının çarptığı zemindeki koordinatlardır. Bu hesaplama önemlidir, çünkü mermi zemine paralel olmalıdır - aksi takdirde aşağı doğru ateş ederdiniz ve sadece amatörler yere doğru ateş ederdi. :]
  3. Player GameObject'den 'ye olan yönü hesaplar pointAboveFloor.
  4. Merminin yörüngesini orijine ve yönüne göre tanımlayan yeni bir ışın oluşturur.
  5. Bu çizgi arasında çarpışmalar görmezden Unity fizik motoru söyler Player colliderve Projectile collider. Aksi takdirde OnCollisionEnter(), Projectile scriptuçma şansı bulamadan önce çağrılırdı.
  6. Son olarak, merminin yörüngesini belirler.
Not:Debug.DrawRay() Işın dökümü olduğunda kullanmak , ışının nasıl göründüğünü ve neye çarptığını görselleştirmenize yardımcı olabileceğinden çok değerlidir.
Ateşleme mantığı yerindeyken, oyuncunun tetiği gerçekten çekmesine izin vermek için aşağıdaki yöntemleri ekleyin:
// 1
geçersiz raycastOnMouseClick () {
RaycastHit vuruşu;
Ray rayToFloor = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(rayToFloor.origin, rayToFloor.direction * 100.1f , Color.red , 2 );

if (Physics.Raycast(rayToFloor, out hit, 100.0f , mask, QueryTriggerInteraction.Collide)) {
ateş etmek (vurmak);
}
}

// 2
geçersiz Güncelleme () {
bool mouseButtonDown = Input.GetMouseButtonDown( 0 );
if (mouseButtonDown) {
raycastOnMouseClick();
}
}

Her numaralı yorumu sırayla alarak:
  1. Bu yöntem, kameradan farenin tıkladığı noktaya bir ışın gönderir. Ardından, bu ışının verilen LayerMask ile bir oyun nesnesiyle kesişip kesişmediğini kontrol eder.
  2. Her güncellemede, komut dosyası sol fare düğmesine basıldığını kontrol eder. Birini bulursa, çağırır raycastOnMouseClick().
Unity'ye geri dönün ve Inspector'da aşağıdaki değişkenleri ayarlayın:
  • Mermi Hazır Yapı: Hazır Yapı klasöründen Mermi'ye başvurun
  • Maske: Zemin
ÇekimKomut Dosyası Kurulumu
Not: Unity, maskeler oluşturabileceğiniz sınırlı sayıda önceden tanımlanmış katmanlabirlikte gelir .
Bir GameObject'in Katman açılır menüsünü tıklayıp Katman Ekle'yi seçerek kendinizinkini oluşturabilirsiniz:
katman konumu
Bir GameObject'e bir katman atamak için, Katman açılır menüsünden onu seçin:
Katman seçme
Katmanlar hakkında daha fazla bilgi için Unity'nin Katmanlar belgelerine bakın .
Projeyi çalıştırın ve istediğiniz zaman ateş edin! Mermiler istenilen yöne ateşleniyor ama bir şeyler biraz ters gidiyor, değil mi?
MermisizDöndürme2
Mermiler hareket yönünü gösteriyor olsaydı çok daha havalı olurdu. Bunu düzeltmek için Projectile.cs komut dosyasını açın ve aşağıdaki yöntemi ekleyin:
geçersiz döndürmeInShootDirection () {
Vector3 newRotation = Vector3.RotateTowards(transform.forward, shootDirection, 0.01f , 0.0f );
transform.rotation = Quaternion.LookRotation(newRotation);
}

Not:RotateTowards ile çok benzer MoveTowards, ancak vektörleri konumlar yerine yönler olarak ele alır. Ayrıca, zaman içinde dönüşü değiştirmenize gerek yoktur, bu nedenle sıfıra yakın bir adım kullanmanız yeterli olacaktır. Unity'deki dönüştürme döndürmeleri , bu öğreticinin kapsamı dışında kalan kuaterniyonlarkullanılarak ifade edilir . Bu eğitim için bilmeniz gereken tek şey, 3B'de döndürmeler içeren hesaplamalar yaparken vektörlere göre avantajlarının olmasıdır.
Kuaterniyonlar ve neden yararlı oldukları hakkında daha fazla bilgi edinmek ister misiniz? Şu mükemmel makaleye göz atın: Endişelenmeyi Bırakmayı ve Kuaterniyonları Sevmeyi Nasıl Öğrendim?
sonuna FireProjectile()bir çağrı ekleyin rotateInShootDirection(). FireProjectile()şimdi aşağıdaki gibi görünmelidir:
public void FireProjectile ( Ray shootRay ) {
this .shootDirection = shootRay.direction;
bu .transform.position = shootRay.origin;
döndürmeInShootDirection();
}

Oyunu bir kez daha çalıştırın ve birkaç farklı yöne ateş edin; bu sefer mermiler vuruldukları yönü gösterecekler:
MermiRotasyon
Debug.DrawRayDaha fazla ihtiyaç duymayacağınız için aramaları kaldırın .

Daha Fazla Kötü Adam Yaratmak​

Tek bir düşmana sahip olmak çok zor değil. Ama artık Prefabrikler hakkında bilgi sahibi olduğunuza göre, istediğiniz tüm düşmanları ortaya çıkarabilirsiniz! :]
Oyuncunun tahminde bulunmasını sağlamak için her Düşmanın sağlığını, hızını ve konumunu rastgele ayarlayabilirsiniz.
Boş bir oyun nesnesi oluşturma - GameObject\Create Empty . O Ad EnemyProducer ve eklemek Kutu Çarpıştırıcısı bileşeni. Denetçideki değerleri aşağıdaki gibi ayarlayın:
  1. Konum: (0, 0, 0)
  2. Kutu Çarpıştırıcısı:
    • Tetikleyici: doğru
    • Merkez: (0, 0,5, 0)
    • Boyut: (29, 1, 29)
Kutu çarpıştırıcı değerlerini ayarlama
Eklediğiniz çarpıştırıcı, Arena içindeki belirli bir 3B alanı tanımlar. Bunu görmek Enemy Produceriçin Hiyerarşide GameObject öğesini seçin ve Sahne görünümünün içine bakın:
Yeşil tel ana hatları bir çarpıştırıcıyı temsil ediyor.
Yeşil tel ana hatları bir çarpıştırıcıyı temsil ediyor.
Bu alanda Xve Zekseni boyunca rastgele bir konum seçen ve bir düşman Prefabrik oluşturan bir komut dosyası yazmak üzeresiniz .
EnemyProducer adlı yeni bir komut dosyası oluşturun ve onu EnemyProducer GameObject öğesine ekleyin . Yeni kurulan sınıfın içine aşağıdaki örnek üyeleri ekleyin:
public bool olmalıdırSpawn;
public Enemy[] düşmanPrefabrikler;
halka açık kayan nokta [] moveSpeedRange;
public int [] HealthRange;

özel Sınırlar spawnArea;
özel GameObject oyuncusu;

İlk değişken yumurtlamayı etkinleştirir ve devre dışı bırakır. Senaryo, rastgele bir düşman prefabrik seçecek enemyPrefabsve onu başlatacak . Sonraki iki dizi, minimum ve maksimum hız ve sağlık değerini belirleyecektir. Ortaya çıkma alanı, Sahne görünümünde gördüğünüz yeşil kutudur. Son olarak, Player için bir referansa ihtiyacınız olacak ve onu kötü adamlara hedef olarak ileteceksiniz.
Komut dosyasının içinde aşağıdaki yöntemleri tanımlayın:
public void SpawnEnemies ( bool shouldSpawn ) {
if (shouldSpawn) {
oyuncu = GameObject.FindGameObjectWithTag( "Oyuncu" );
}
bu .shouldSpawn = mustSpawn;
}

geçersiz Başlangıç () {
spawnArea = this .GetComponent<BoxCollider>().bounds;
SpawnEnemies(Spawn gerekir);
InvokeRepeating( "spawnEnemy" , 0.5f , 1.0f );
}

SpawnEnemies()Player etiketine sahip bir oyun nesnesinin referansını alır ve bir düşmanın doğması gerekip gerekmediğini belirler.
Start()yumurtlama alanını başlatır ve oyun başladıktan 0,5 saniye sonra bir yöntemin çağrılmasını planlar. Her saniye tekrar tekrar aranacaktır. Bir ayarlayıcı yöntemi olarak hareket etmenin yanı sıra SpawnEnemies(), etiketli bir oyun nesnesinin referansını da alır Player.
Player oyun nesnesi henüz etiketlenmedi - bunu şimdi yapacaksınız. Dan Oyuncu nesneyi seçin Hiyerarşi seçin ve ardından Müfettiş sekmede Player dan Etiket açılır menüsünden:
Ekran Görüntüsü 2016-05-26 12.45.49 PM
Şimdi, bireysel bir düşman için gerçek yumurtlama kodunu yazmanız gerekiyor.
Düşman komut dosyasını açın ve aşağıdaki yöntemi ekleyin:
public void Initialize ( Transform hedefi, float moveSpeed, int sağlık ) {
this .targetTransform = hedef;
bu .moveSpeed = moveSpeed;
bu .sağlık = sağlık;
}

Bu sadece nesneyi oluşturmak için bir ayarlayıcı görevi görür. Sıradaki: düşman liglerinizi ortaya çıkaracak kod. EnemyProducer.cs dosyasını açın ve aşağıdaki yöntemleri ekleyin:
Vector3 randomSpawnPosition () {
float x = Random.Range(spawnArea.min.x, spawnArea.max.x);
float z = Random.Range(spawnArea.min.z, spawnArea.max.z);
kayan nokta y = 0.5f ;

geri yeni vector3 (x, y, z);
}

void spawnEnemy () {
if (shouldSpawn == false || oyuncu == null ) {
return ;
}

int indeks = Random.Range( 0 , düşmanPrefabs.Length);
var newEnemy = Instantiate(enemyPrefabs[index], randomSpawnPosition(), Quaternion.identity) as Enemy;
newEnemy.Initialize(player.transform,
Random.Range(moveSpeedRange[ 0 ], moveSpeedRange[ 1 ]),
Random.Range(healthRange[ 0 ], healthRange[ 1 ]));
}

Tek yaptığı spawnEnemy()rastgele bir düşman hazır yapısı seçmek, onu rastgele bir konumda somutlaştırmak ve Düşman komut dosyası genel değişkenlerini başlatmak.
EnemyProducer.cs neredeyse kullanıma hazır!
Unity'ye geri dön. Düşman nesnesini Hiyerarşiden Hazır Yapılar klasörüne sürükleyerek bir Düşman hazır yapısı oluşturun . Düşman nesnesini olay yerinden kaldırın - artık ona ihtiyacınız yok. Ardından, komut dosyası genel değişkenlerini şu şekilde ayarlayın:Enemy Producer
  1. Yumurtlamalı: Doğru
  2. Düşman Hazır Yapıları:
    • Boyut: 1
    • Element 0: Düşman prefabrike referansı
  3. Hareket Hızı Aralığı:
    • Boyut: 2
    • Öğe 0: 3
    • Öğe 1: 8
  4. Sağlık Aralığı:
    • Boyut: 2
    • Öğe 0: 2
    • Öğe 1: 6
Düşman Yapımcı Kurulumu
Oyunu çalıştırın ve kontrol edin - sonsuz bir kötü adam akışı!
YumurtlamaDüşmanlar
Tamam, bu küpler çok korkutucu görünmüyor. İşleri renklendirme zamanı.
Sahnede bir 3B Silindir ve Kapsül oluşturun . Onları Ad Enemy2 ve Enemy3 sırasıyla. Daha önce ilk düşmanla yaptığınız gibi, her ikisine de bir Rigidbody bileşeni ve Düşman komut dosyası ekleyin . Enemy2'yi seçin ve Inspector'da konfigürasyonunu şu şekilde değiştirin:
  1. Ölçek: (0, 0,5, 0)
  2. Sağlam vücut:
    • Yerçekimini Kullan: Yanlış
    • Donma Konumu: Y
    • Dondurma Dönüşü: X, Y, Z
  3. Düşman Bileşeni:
    • Hareket Hızı: 5
    • Sağlık: 2
    • Hasar: 1
    • Hedef Dönüşümü: Yok
Şimdi aynısını Enemy3 için yapın , ancak Scale değerini 0.7 olarak ayarlayın :
DiğerDüşmanlarPrefabrikAyarlar
Ardından, orijinal Enemy'de yaptığınız gibi bunları Prefabrike dönüştürün ve Enemy Producer'da hepsini referans alın . Müfettişteki değerler şöyle görünmelidir:
    • Düşman Hazır Yapıları:
      • Boyut: 3
      • Element 0: Düşman
      • 1. Öğe: Düşman2
      • 2. Öğe: Düşman3
Düşman Hazır Yapılar
Oyunu çalıştırın; Arena içinde farklı prefabriklerin ortaya çıktığını göreceksiniz.
YumurtlamaFarklıDüşmanlar
Yenilmez olduğunuzu anlamanız uzun sürmez! Bu ne kadar harika olsa da, oyun alanını biraz düzleştirmeniz gerekiyor.

Oyun Denetleyicisini Uygulama​

Artık atış, hareket ve düşmanlarınız olduğuna göre, temel bir oyun kumandası uygulayacaksınız. Player"Ölü" olduğunda oyunu yeniden başlatır. Ancak önce, ilgili taraflara Oyuncunun 0 sağlığa ulaştığını bildirmek için bir mekanizma oluşturmanız gerekecek.
Player komut dosyasını açın ve aşağıdakileri sınıf bildiriminin üstüne ekleyin:
Sistemi kullanarak ;

Sınıfın içine aşağıdaki yeni genel etkinliği ekleyin:
public event Action<Player> onPlayerDeath;

Bir olay , herhangi bir dinleyiciye nesneler değişiklikleri yayın sağlayan bir C # dili özelliğidir. Etkinliklerin nasıl kullanılacağını öğrenmek için Unity'nin etkinliklerle ilgili canlı eğitimine göz atın. .
Düzenleme collidedWithEnemy()aşağıdaki kodu gibi görünmek için:
void CollidedWithEnemy ( Düşman düşmanı ) {
düşman.Attack( bu );
if (sağlık <= 0 ) {
if (onPlayerDeath != null ) {
onPlayerDeath( bu );
}
}
}

Olaylar, nesnelerin kendi aralarındaki durum değişikliklerini bildirmeleri için düzgün bir yol sağlar. Bir oyun kumandası, yukarıda açıklanan olayla çok ilgilenecektir. Gelen Scriptsklasörün adı verilen yeni bir komut dosyası oluşturmak Oyun kumandası, . Düzenlemek için dosyaya çift tıklayın ve aşağıdaki değişkenleri ekleyin:
public EnemyYapımcı düşman Yapımcı;
genel GameObject playerPrefabrik;

Senaryonun düşman üretimi üzerinde bir miktar kontrole sahip olması gerekecek, çünkü Oyuncu öldükten sonra düşmanları ortaya çıkarmak mantıklı değil. Ayrıca, oyunu yeniden başlatmak, Player'ı yeniden oluşturmanız gerekeceği anlamına gelir, bu da demek oluyor ki... bu doğru, bir Prefabrik olacak.
Aşağıdaki yöntemleri ekleyin:
geçersiz Başlangıç () {
var player = GameObject.FindGameObjectWithTag( "Oyuncu" ).GetComponent<Player>();
player.onPlayerDeath += onPlayerDeath;
}

geçersiz onPlayerDeath ( Oyuncu oyuncu ) {
düşmanProducer.SpawnEnemies( false );
Destroy(player.gameObject);

Invoke( "restartGame" , 3 );
}

içinde Start(), komut dosyası, komut dosyasına bir başvuru alır Playerve daha önce oluşturduğunuz etkinliğe abone olur. Oyuncunun sağlığı 0'a ulaştığında onPlayerDeath(), düşman üretimi durdurulur, Player nesnesini sahneden kaldırır ve restartGame()3 saniye sonra yöntemi çağırır .
Son olarak, oyunu yeniden başlatma eyleminin uygulamasını ekleyin:
void restartGame () {
var düşmanlar = GameObject.FindGameObjectsWithTag( "Düşman" );
foreach ( var düşman içinde düşman)
{
Yok et(düşman);
}

var playerObject = örneğini (playerPrefab, yeni vector3 ( 0 , 0.5f , 0 ), Quaternion.identity) olarak GameObject;
var cameraRig = Camera.main.GetComponent<CameraRig>();
cameraRig.target = playerObject;
düşmanProducer.SpawnEnemies( true );
playerObject.GetComponent<Player>().onPlayerDeath += onPlayerDeath;
}

Burada biraz temizlik yapıyorsunuz: sahnedeki tüm düşmanları yok ediyorsunuz ve yeni bir Player nesnesi yaratıyorsunuz. Ardından kamera teçhizatının hedefini bu örneğe yeniden atar, düşman yapımına devam Game Controllereder ve oyuncu ölümü olayına abone olursunuz.
Şimdi Unity'ye dönün, Prefabrikler klasörünü açın ve tüm Enemy prefabriklerinin etiketini Enemy olarak değiştirin . Sonra, yapmak Oyuncu içine sürükleyerek Prefabrik içine oyun nesnesi Prefabs klasöründe. Boş bir oyun nesnesi oluşturun, GameController olarak adlandırın ve az önce oluşturduğunuz komut dosyasını ekleyin. Müfettiş'te gerekli tüm referansları bağlayın.
Şimdiye kadar bu kalıba oldukça aşinasınız. Referansları kendiniz yerleştirmeyi deneyin ve ardından sonuçlarınızı aşağıda gizlenmiş olan çizime göre kontrol edin:

Ortaya çıkartmak

Oyun kumandasını çalışırken görmek için oyunu tekrar çalıştırın.
Oyun Döngüsü
İşte bu - ilk Unity oyununuzu yazdınız! Tebrikler! :]

Buradan Nereye Gidilir?​

Tamamlanan projeyi buradan indirebilirsiniz .
Şimdiye kadar basit bir aksiyon oyununu bir araya getirmek için ne gerektiğini iyi anlamış olmalısınız. Oyun yapmak basit bir iş değildir; kesinlikle çok çalışma gerektirir ve komut dosyası yazmak, bir projeyi hayata geçirmek için gereken unsurlardan yalnızca biridir. İyi bir cila seviyesi eklemek için oyunlarınıza animasyonlar ve kullanıcı arayüzü eklemeniz gerekecek. Bu nedenle, bu konulardaki diğer eğitimlerimize göz atmanızı şiddetle tavsiye ederim:
  • Unity kullanıcı arayüzüne giriş
  • Unity Animasyona Giriş
Unity'de yerleşik kendi oyunlarınızı nasıl tasarlayacağınızı, kodlayacağınızı ve yayınlayacağınızı öğrenmek istiyorsanız, Unity Games by Tutorials'a göz atın .
Kitap, ister yeni başlayan ister daha deneyimli bir oyun geliştiricisi olun, Unity'de oyun geliştirme hakkında bilmeniz gereken her şeyi öğretiyor. Kitapta dört harika oyun inşa edeceksiniz:
  • 3D çift çubuklu nişancı
  • Klasik bir 2D platform oyunu
  • Bir 3D kule savunma oyunu (sanal gerçeklik moduyla!)
  • Birinci şahıs nişancı
Umarım bu öğreticiyi beğenmişsinizdir ve her zaman yaratmak istediğiniz o oyunda bir çatlak almak için ilham bulmuşsunuzdur. Sorular veya yorumlar? Aşağıdaki tartışmaya katılın!
Burhanese2007
Üye
Üye
Katılım13 Ara 2025
Konular7
Mesajlar47
Elmas Konular1
Başarım0
ZirveCoin 0
Ticaret Puanı
+0 -0
21.04.2026 23:53 #2
Paylaşım için teşekkürler
Bu konuyu görüntüleyenler
1 misafir
Cevap yazmak için giriş yapın.
Benzer Konular
7 cevap
2K görüntüleme
13 cevap
2K görüntüleme
10 cevap
1.9K görüntüleme
5 cevap
1.8K görüntüleme
- Ücretsiz Açık Kaynak Oynatıcısı
WebServisi · 28 Mar 2026
27 cevap
1.7K görüntüleme
İlan Yan banner placeholder