Hướng dẫn về Unity: Cách tạo một trò chơi giống như Space Invaders

nội dung

Space Invaders , được biết đến ở Nhật Bản với tên Supēsuinbēdā (スペースインベーダー) , là một trong những trò chơi cổ điển nổi tiếng nhất trên thế giới. Được phát hành vào năm 1978 bởi công ty trò chơi Nhật Bản Taito, nó nhanh chóng trở thành một hit lớn.

Trò chơi điện tử Invaders cổ điển.

Pháo bắn đạn laser đại diện cho người chơi. Người chơi có thể ẩn đằng sau bất kỳ trong bốn ngọn đuốc (トーチカ) , còn được gọi là hộp đựng thuốc .

Có ba loại kẻ xâm lược: cua , mực và bạch tuộc . Chúng xuất hiện thành một nhóm gồm nhiều hàng và di chuyển từ trên xuống dưới màn hình. Kẻ xâm lược cua đã trở thành một biểu tượng mang tính biểu tượng được liên kết phổ biến với các trò chơi điện tử và trò chơi nói chung.

Mục tiêu của trò chơi là loại bỏ những kẻ xâm lược trước khi chúng đến cuối màn hình trong khi né tránh và ẩn nấp sau những ngọn đuốc. Ngoài bầy đàn, thỉnh thoảng còn có một UFO xuất hiện. Tuy nhiên, bạn sẽ tập trung vào bầy đàn.

Trong hướng dẫn này, bạn sẽ sao chép các tính năng chơi trò chơi cốt lõi của Space Invaders bằng Unity. Trên đường đi, bạn sẽ học cách:

  • Sinh sản và di chuyển bầy đàn xâm lược.
  • Làm cho những kẻ xâm lược ở đầu đàn bắn đạn laze.
  • Di chuyển và bắn trả với tư cách là người chơi.
  • Thay đổi nhịp độ âm nhạc và tốc độ đàn dựa trên số lần tiêu diệt.

Thời gian để bắt đầu!

Lưu ý : Hướng dẫn này giả định rằng bạn đã có kinh nghiệm cơ bản với Unity và kiến ​​thức trung cấp về C#. Ngoài ra, hướng dẫn này giả định rằng bạn đang sử dụng C# 7 và Unity 2020.3.

Bắt đầu

Tải xuống tài liệu dự án bằng cách nhấp vào nút Tải xuống Tài liệu ở đầu hoặc cuối hướng dẫn này.

Giải nén tệp zip vào một vị trí thuận tiện. Sau khi giải nén, bạn sẽ thấy các thư mục dự án Starter và Final . Mở Starter trong Unity.

Dự án chứa một số thư mục để giúp bạn bắt đầu. Mở Assets/RW và bạn sẽ tìm thấy các thư mục sau:

  • Ảnh động : Chứa các hoạt ảnh được tạo sẵn và trình tạo hoạt ảnh cho các viên đạn và vụ nổ prefabs.
  • Prefabs : Có tất cả các prefabs mà dự án sử dụng.
  • Tài nguyên : Chứa phông chữ và kết cấu.
  • Cảnh : Chứa cảnh chính mà bạn sẽ làm việc.
  • Tập lệnh : Có tất cả các tập lệnh của dự án. Hầu hết trong số chúng là vỏ rỗng mà bạn sẽ lấp đầy.
  • Âm thanh : Có tất cả các hiệu ứng âm thanh và tệp nhạc.
  • Sprites : Chứa tất cả các pixel art cho dự án.

Điều hướng đến RW/Scenes và mở Main . Nhấp vào Phát và bạn sẽ thấy khẩu pháo trình phát màu đỏ ở giữa dưới cùng của màn hình và nghe thấy vòng lặp nhạc. Ngoài ra, bạn sẽ thấy Điểm số và Trực tiếp .

Bạn chưa thể tương tác với trò chơi, nhưng bạn sẽ thêm tính tương tác trong hướng dẫn này.

Điểm bắt đầu hiển thị pháo, điểm số và số mạng.

Dừng trò chơi và chọn Chỉnh sửa ▸ Cài đặt dự án ▸ Vật lý 2D . Hãy xem Ma trận va chạm lớp . Lưu ý rằng dự án này có hai lớp tùy chỉnh: Anh hùng và Kẻ thù .

Ma trận va chạm lớp Physics2D

Phát hiện va chạm Vật lý 2D cho GameObject trong lớp Kẻ thù chỉ hoạt động với GameObject trên lớp Anh hùng. GameObject lớp anh hùng hoạt động cho cả Kẻ thù và GameObject lớp anh hùng khác. Thông tin này sẽ rất quan trọng sau này.

Bây giờ, hãy xem GameObjects trong Hierarchy . Một số có các thành phần tùy chỉnh được đính kèm mà bạn sẽ làm việc trong hướng dẫn này.

Cửa sổ phân cấp của dự án

Game Controller có các thành phần Invader Swarm , Torchka Manager và Game Manager được đính kèm. Ngoài những thứ này, còn có một thành phần Nguồn âm thanh mà bạn sẽ sử dụng cho các hiệu ứng âm thanh.

Cửa sổ Thanh tra của Game Controller GameObject

Âm nhạc có Điều khiển nhạc và Nguồn âm thanh . Audio Source phát Beats nằm trong RW/Sounds . Đây là âm nhạc chính của trò chơi. Hiện tại, âm nhạc có nhịp độ cố định, nhưng sau này bạn sẽ làm cho nó động.

Music GameObject trong cửa sổ Thanh tra

CANNON có Cannon Control và Box Collider 2D để phát hiện va chạm. Lưu ý lớp của nó được đặt thành Hero . Nó cũng có hai phần tử con ngay lập tức: Sprite , là sprite liên quan của nó và Muzzle , một GameObject trống đại diện cho vị trí khởi tạo viên đạn trong khi bắn.

Trình kiểm tra thành phần CANNON

Máy ảnh chính là máy ảnh chính và duy nhất của trò chơi và có Trình nghe âm thanh . Nó chính tả với độ lệch vị trí -10 dọc theo trục Z.

Tất cả các GameObject khác có Z được đặt thành 0. Trên thực tế, đối với những GameObject khác, giả sử trục Z không tồn tại vì đây là trò chơi 2D và bạn sẽ chỉ định vị chúng trên trục X và Y.

INVADERS Spawn Start và TORCHKA Spawn Center là hai GameObject trợ giúp trống được cấp bậc cha mẹ cho Helpers . Vị trí của họ sẽ giúp bạn sinh ra bầy đàn xâm lược và đuốc sau này.

Canvas và Hệ thống sự kiện dành cho giao diện người dùng. Canvas có các con sau:

  • Văn bản điểm : Phần này hiển thị điểm.
  • Lives Text : Bạn sẽ sử dụng nó để hiển thị các trận đấu còn lại của người chơi.
  • Bảng kết thúc trò chơi : Bảng này hiển thị thông báo Trò chơi kết thúc khi một người chơi hết mạng.
  • All Clear : Bạn sẽ sử dụng bảng này để hiển thị thông báo All Clear khi người chơi loại bỏ tất cả những kẻ xâm lược.
  • Nút khởi động lại : Nút này khởi động lại trò chơi.

Bây giờ bạn đã hoàn thành chuyến tham quan, đã đến lúc thêm những thứ hay ho. :] Trong phần tiếp theo, bạn sẽ làm việc với các điều khiển trình phát.

Triển khai Điều khiển Trình phát

Chọn tập lệnh CannonControl được đính kèm với CANNON . Mở nó trong trình chỉnh sửa mã của bạn. Dán đoạn mã sau vào bên trong lớp:

[ SerializeField ]
 riêng  float speed = 500f ;

 Cập nhật khoảng trống  riêng tư ()
{
    nếu như (Input.GetKey(KeyCode.D))
    {
        biến đổi.Dịch(tốc độ * Thời gian.deltaTime, 0 , 0 );
    }
    khác  nếu (Input.GetKey(KeyCode.A))
    {
        biến đổi.Dịch (-tốc độ * Thời gian.deltaTime, 0 , 0 );
    }
}

Đây là một sự cố mã:

  • Biến speedđiều khiển tốc độ của pháo.
  • Vào trong Update, bạn kiểm tra xem người chơi đang nhấn giữ phím D hay A. Nếu người chơi giữ phím D , khẩu pháo sẽ di chuyển sang phải theo speed * Time.deltaTimetừng khung hình. Nếu họ giữ phím A , khẩu pháo sẽ di chuyển sang trái cùng một lượng.

Lưu các tập tin. Quay lại Unity và chọn Play bên trong trình chỉnh sửa. Bây giờ bạn có thể di chuyển con tàu bằng cách sử dụng D và A .

Pháo bây giờ có thể di chuyển thông qua các phím A và D.

Tiếp theo, bạn sẽ thêm cơ chế bắn súng bằng cách sử dụng Bullet prefab bên trong RW/Prefabs .

Chọn Bullet và xem Thanh tra.

Nhà lắp ghép có thành phần Kinematic Rigidbody 2D . Đó là Động học vì bạn sẽ không dựa vào vật lý để di chuyển viên đạn mà thay vào đó dịch nó thông qua một tập lệnh.

Lớp của Rigidbody 2D được đặt thành Hero và  có thành phần Box Collider 2D để phát hiện va chạm. Ngoài ra còn có một thành phần Bullet chưa làm gì cả.

Mở tập lệnh Bullet bên trong trình chỉnh sửa mã của bạn. Thêm đoạn mã sau vào bên trong lớp:

[ SerializeField ]
 riêng  float speed = 200f ;

[ SerializeField ]
 phao riêng  lifeTime = 5f ;

 khoảng trống  bên trong Phá hủy bản thân ()
{
    gameObject.SetActive( sai );
    Phá hủy (gameObject);
}

 khoảng trống  riêng tư Tỉnh táo ()
{
    Gọi ( "Tự hủy" , lifeTime);
}

 Cập nhật khoảng trống  riêng tư ()
{
    biến đổi.Translate(tốc độ * Time.deltaTime * Vector2.up);
}

private  void  OnCollisionEnter2D ( Collision2D khác )
{
    Tự hủy ();
}

Trong đoạn mã trên, bạn:

  • Sử dụng Updateđể di chuyển viên đạn theo speed * Time.deltaTimemọi khung về phía trên cùng.
  • Dùng DestroySelfđể phá viên đạn GameObject. Trước khi gọi Destroy, bạn vô hiệu hóa dấu đầu dòng vì việc hủy cần một số khung để xử lý nhưng việc vô hiệu hóa gần như ngay lập tức.
  • Awakegọi DestroySelfđể tự động phá hủy viên đạn sau lifetimevài giây. DestroySelfcũng được gọi khi một viên đạn va chạm với GameObject khác.

Bạn sẽ cần hiệu ứng âm thanh trong khi chụp. Bên trong RW/Scripts , mở GameManager và thêm phần sau vào bên trong lớp:

 Phiên bản GameManager tĩnh bên trong ;

[ SerializeField ]
 riêng AudioSource sfx;

 khoảng trống  nội bộ PlaySfx ( AudioClip clip ) => sfx.PlayOneShot(clip);

 khoảng trống  riêng tư Tỉnh táo ()
{
    nếu (Trường hợp == null )
    {
        Ví dụ = cái này ;
    }
    khác  nếu (Trường hợp != this )
    {
        Phá hủy (gameObject);
    }
}

Đoạn mã trên biến GameManagerthành một singleton, điều này đảm bảo nó chỉ có một phiên bản duy nhất tại bất kỳ thời điểm nào. Nó cũng thêm một phương thức tiện ích, PlaySfxchấp nhận Đoạn âm thanh và phát nó bằng Nguồn âm thanh sfx .

Để sử dụng dấu đầu dòng, bạn cần khởi tạo nó. Mở lại CannonControl và thêm phần sau vào sau phần khai báo cho speed:

[ SerializeField ]
 mõm Transform riêng tư ;

[ SerializeField ]
 quay AudioClip riêng tư ;

[ SerializeField ]
 float riêng  coolDownTime = 0.5f ;

[ SerializeField ]
 riêng Bullet bulletPrefab;

 bộ đếm thời gian bắn phao riêng ;

Sau đó, sau mã chuyển động trước đó bên trong Update, hãy dán:

shootTimer += Time.deltaTime;
nếu như (shootTimer > coolDownTime && Input.GetKey(KeyCode.Space))
{
    bắnTimer = 0f ;

    Khởi tạo(bulletPrefab, mzzle.position, Quaternion.identity);
    GameManager.Instance.PlaySfx(bắn súng);
}

Mã này tăng shootTimertừng khung hình cho đến khi đạt đến coolDownTime. Nếu người chơi giữ phím Space , mã sẽ đặt lại shootTimervà khởi tạo bulletPrefabtại muzzle.position. Nó cũng phát shootinghiệu ứng âm thanh bằng cách sử dụng PlaySfxbên trong GameManager.

Lưu mọi thứ và quay lại Unity.

Quay trở lại nhà lắp ghép Bullet . Lưu ý các trường mới cho thành phần Bullet .

Cửa sổ Trình kiểm tra cho nhà lắp ghép Bullet.

Bây giờ, chọn Trình điều khiển trò chơi từ Hệ thống phân cấp. Đặt Sfx của Trình quản lý trò chơi thành Nguồn âm thanh được gắn vào Bộ điều khiển trò chơi .

Cửa sổ trình kiểm tra đang hiển thị thành phần Nguồn âm thanh của Bộ điều khiển trò chơi.

Chọn CANNON từ Hệ thống phân cấp. Trong Cannon Control , trước tiên hãy đặt Muzzle thành Muzzle Transform là con của CANNON . Sau đó đặt Bullet Prefab thành Bullet tìm thấy trong RW/Prefabs . Cuối cùng, đặt Shooting thành CannonBullet được tìm thấy trong RW/Sounds .

Thành phần Cannon Control trong cửa sổ Thanh tra

Lưu và chơi . Bây giờ bạn có thể di chuyển khẩu pháo và bắn đạn laze bằng cách giữ phím Space .

Pháo bây giờ có thể bắn đạn laze.

Anh hùng của bạn đã sẵn sàng! Bây giờ là lúc để thêm nhân vật phản diện. Trong phần tiếp theo, bạn sẽ thêm đàn xâm lược.

Tạo kẻ xâm lược

Làm thế nào để tất cả các nhân vật phản diện bắt đầu cuộc sống của họ trong trò chơi? Sinh sản tất nhiên! Bạn sẽ làm điều đó tiếp theo.

Sinh ra những kẻ xâm lược

Điều hướng đến RW/Scripts để kiểm tra tập lệnh SimpleAnimator . Bạn sẽ sử dụng nó để tạo hoạt ảnh cho những kẻ xâm lược, nhưng bạn không cần phải lo lắng về hoạt động bên trong của nó đối với hướng dẫn này.

Khi bạn thêm SimpleAnimator vào GameObject, bạn cũng thêm SpriteRenderer  đó là thành phần bắt buộc để tập lệnh hoạt động.

SimpleAnimator cũng yêu cầu một loạt các họa tiết. Nó sẽ tiếp tục cập nhật sprite của SpriteRenderer theo chu kỳ bằng cách sử dụng các sprite bên trong mảng, về cơ bản là tạo hoạt ảnh cho nó.

Bây giờ, chọn Invader Swarm được gắn vào Bộ điều khiển trò chơi . Mở tập lệnh được liên kết bên trong trình chỉnh sửa mã của bạn. Thêm đoạn mã sau vào bên trong lớp:

[ System.Serializable ]
 cấu trúc riêng  InvaderType
{
     tên chuỗi công khai ;
    công khai Sprite[] sprites;
    điểm
     int công khai ;  public int rowCount; 
}

Đây là một sự cố mã:

  • Mã này xác định cấu trúc InvaderType .
  • Mảng spriteslưu trữ tất cả các họa tiết được liên kết với loại kẻ xâm lược mà SimpleAnimator sử dụng để tạo hoạt ảnh cho kẻ xâm lược.
  • rowCountlà số hàng mà loại kẻ xâm lược sẽ có trong bầy.
  • namelưu trữ tên loại cho kẻ xâm lược và pointslưu trữ phần đóng góp điểm nếu người chơi loại bỏ kẻ xâm lược thuộc loại này. Những thứ này sẽ có ích sau này.

Bây giờ thêm phần sau ngay bên dưới InvaderType:

[ Tiêu đề( "Sinh sản" ) ]
[ SerializeField ]
 InvaderType riêng tư [] InvaderTypes;

[ SerializeField ]
 private  int columnCount = 11 ;

[ SerializeField ]
 private  int ySpacing;

[ SerializeField ]
 private  int xSpacing;

[ SerializeField ]
 Chuyển đổi riêng spawnStartPoint;

 phao riêng minX;

Bạn sẽ sử dụng tất cả các trường này cho logic sinh sản:

  • invaderTypes: Đại diện cho tất cả các loại kẻ xâm lược đang sử dụng.
  • columnCount: Tổng số cột cho swarm.
  • ySpacing: Khoảng cách giữa mỗi kẻ xâm lược trong bầy dọc theo trục Y.
  • xSpacing: Khoảng cách giữa mỗi kẻ xâm lược trong bầy dọc theo trục X.
  • spawnStartPoint: Điểm sinh sản cho kẻ xâm lược đầu tiên.
  • minX: Lưu trữ giá trị vị trí X tối thiểu cho bầy đàn.

Tiếp theo, dán đoạn mã sau vào sau tất cả các khai báo biến:

 khoảng trống  riêng Bắt đầu ()
{
    minX = spawnStartPoint.position.x;

    bầy GameObject = new GameObject { name = "Swarm" };
    Vector2 currentPos = spawnStartPoint.position;

    int row Index = 0 ;
    foreach ( var kiểu kẻ xâm lược trong kiểu kẻ xâm lược)
    {
        var tên kẻ xâm lược = kẻ xâm lượcType.name.Trim();
        cho ( int tôi = 0 , len = xâm lượcType.rowCount; i < len; i++)
        {
            cho ( int j = 0 ; j < cộtCount; j++)
            {
                var kẻ xâm lược = new GameObject () { tên = tên kẻ xâm lược };
                kẻ xâm lược.AddComponent<SimpleAnimator>().sprites = kẻ xâm lượcType.sprites;
                kẻ xâm lược.transform.position = currentPos;
                kẻ xâm lược.transform.SetParent(swarm.transform);

                currentPos.x += xSpacing;
            }

            currentPos.x = minX;
            currentPos.y -= ySpacing;

            hàng Index++;
        }
    }
}

Đây là một sự cố mã:

  1. Mã này thiết lập minXbên trong Start. Sau đó, nó tạo một GameObject trống có tên Swarm .
  2. xSpacingvà ySpacingcập nhật currentPosdọc theo trục X và Y tương ứng.
  3. currentPos.xgia tăng sau mỗi lần lặp lại kẻ xâm lược trong hàng. Sau khi hoàn thành một hàng, currentPos.ygiảm dần.
  4. Lặp lại các thành viên của invaderTypes, đối với mỗi thành viên invaderType, bạn lặp lại theo hàng để tạo các GameObject kẻ xâm lược riêng lẻ tại currentPosvị trí đó.
  5. xSpacingvà ySpacingcập nhật currentPosdọc theo trục X và Y tương ứng.
  6. Mỗi GameObject kẻ xâm lược được tạo có tên được đặt thành invaderName. Sau đó, bạn thêm một SimpleAnimatorthành phần và gán mảng sprite của nó cho thành phần spritesđược liên kết với invaderType.
  7. Cuối cùng, kẻ xâm lược trở thành con của Swarmvà vị trí của nó được đặt thành currentPos.

Lưu mọi thứ và quay lại Unity.

Chọn Trình điều khiển trò chơi từ Hệ thống phân cấp. Trên Invader Swarm , hãy đặt:

  • Khoảng cách Y đến 25
  • Khoảng cách X đến 25
  • Spawn Start Point to INVADERS Spawn Start , là con của Helpers .

Sau đó, đặt kích thước Loại kẻ xâm lược thành 3 và đặt các trường thành viên như sau:

  • 0: Đặt Tên thành SQUID , Points thành 30 và Row Count thành 1 .
  • 1: Đặt Tên thành CRAB , Points thành 20 và Row Count thành 1 .
  • 2: Đặt Tên thành OCTOPUS , Points thành 10 và Row Count thành 2 .

Bây giờ, điều hướng đến RW/Sprites và nhìn vào bảng ma trận INVADERS . Đây không phải là Space Invaders ban đầu nhưng chúng sẽ phù hợp với hướng dẫn này.

Quay lại Invader Swarm và thiết lập nó như sau, sử dụng spritesheet:

Đối với mục SQUID, hãy đặt danh sách Sprites để chứa các sprite sau từ spritesheet theo thứ tự sau:

  • bug_invaders_0
  • bug_invaders_5
  • bug_invaders_9
  • bug_invaders_4

Thực hiện bài tập tương tự, nhưng lần này là CRAB bằng cách sử dụng các họa tiết sau:

  • bug_invaders_13
  • bug_invaders_18

Cuối cùng, chỉ định các họa tiết cho OCTOPUS bằng cách sử dụng:

  • bug_invaders_7
  • bug_invaders_2

Đây là một tài liệu tham khảo trực quan về những thứ sẽ trông như thế nào bây giờ:

Thiết lập cho trường Loại kẻ xâm lược của thành phần Bầy đàn xâm lược của Bộ điều khiển trò chơi.

Lưu và chơi . Chú ý bầy đàn sinh sản và những kẻ xâm lược hoạt hình ở một nơi.

Trò chơi bây giờ đã sinh ra những kẻ xâm lược.

Tuyệt vời! Nhưng họ không di chuyển. Bạn sẽ khắc phục điều đó trong phần tiếp theo.

Di chuyển quân xâm lược

Quay lại tập lệnh InvaderSwarm.cs và thêm phần sau vào sau các khai báo biến hiện có:

[ Không gian ]
[ Tiêu đề( "Chuyển động" ) ]
[ SerializeField ]
 riêng  float speedFactor = 10f ;

những kẻ xâm lược Transform[,]
 riêng tư ; private  int rowCount;
bool riêng  isMovingRight = true ;
phao riêng maxX;
riêng nổi hiện tạiX;
float riêng xIncrement;
   

Tất cả các biến này sẽ giúp di chuyển đàn:

  • speedFactorbây giờ đại diện cho tốc độ mà những kẻ xâm lược di chuyển dọc theo trục X. Sau đó, tốc độ sẽ liên quan đến nhịp độ âm nhạc nên tốc độ thực tế là sản phẩm của cả hai.
  • invaderslưu trữ các Biến đổi của tất cả các GameObject kẻ xâm lược đã tạo.
  • rowCountlưu trữ tổng số hàng của bầy đàn.
  • isMovingRightđại diện cho hướng di chuyển và được đặt truetheo mặc định.
  • maxXlà vị trí X tối đa cho phong trào bầy đàn.
  • currentXđại diện cho vị trí X tổng thể của bầy đàn.
  • xIncrementlà giá trị trên mỗi khung hình di chuyển kẻ xâm lược dọc theo trục X.

Bây giờ, trong Start, hãy thêm đoạn mã sau vào ngay trên int rowIndex = 0;:

foreach ( var kiểu kẻ xâm lược trong kiểu kẻ xâm lược)
{
    rowCount += kẻ xâm lượcType.rowCount;
}
maxX = minX + 2f * xSpacing * cộtCount;
hiện tạiX = minX;
kẻ xâm lược = new Transform[rowCount, columnCount];

Mã này tính toán tổng số hàng và lưu trữ nó bên trong tệp rowCount. Sau đó, bạn tính toán maxXdựa trên tổng số cột và khoảng cách giữa mỗi kẻ xâm lược. Ban đầu, currentXđược đặt ở spawnStartPointvị trí ‘s X.

Bạn đã khai báo invadersmảng. Để điền nó, bạn sẽ cần thêm một dòng mã.

Dán dòng sau vào forvòng lặp trong cùng, ngay phía trên currentPos.x += xSpacing;:

kẻ xâm lược[rowIndex, j] = kẻ xâm lược.transform;

Dòng này chăm sóc dân số invaders.

Cuối cùng, ngay sau đó Start, dán:

 Cập nhật khoảng trống  riêng tư ()
{
    xIncrement = speedFactor * Time.deltaTime;
    nếu (isMovingRight)
    {
        currentX += xIncrement;
        nếu (currentX < maxX)
        {
            MoveInvaders(xIncrement, 0 );
        }
        khác 
        {
            Chuyển hướng();
        }
    }
    khác
    {
        hiện tạiX -= xIncrement;
        nếu (currentX > minX)
        {
            MoveInvaders(-xIncrement, 0 );
        }
        khác 
        {
            Chuyển hướng();
        }
    }
}

private  void  MoveInvaders ( float x, float y )
{
    cho ( int i = 0 ; i < rowCount; i++)
    {
        cho ( int j = 0 ; j < cộtCount; j++)
        {
            kẻ xâm lược[i, j].Translate(x, y, 0 );
        }
    }
}

private  void  ChangeDirection ()
{
    isMovingRight = !isMovingRight;
    MoveInvaders( 0 , -ySpacing);
}

Đây là một sự cố mã:

  • MoveInvaderschấp nhận hai giá trị float: xvà y. Nó di chuyển từng Biến đổi theo invaderscùng một giá trị dọc theo trục X và Y tương ứng.
  • ChangeDirectionchuyển đổi isMovingRightvà di chuyển đàn xuống theo ySpacingsố lượng.
  • Bên trong Update, bạn tính toán xIncrementvà cập nhật currentXdựa trên hướng của mọi khung hình.
  • Bạn dùng currentXđể kiểm tra xem vị trí swarm X có đang tiến đến ngưỡng hay không. Nếu có, bạn gọi ChangeDirection. Nếu không, bạn di chuyển đàn bằng cách sử dụng MoveInvaders.

Lưu tất cả mọi thứ. Quay trở lại Unity và nhấp vào Play . Bạn sẽ thấy lũ xâm lược đang di chuyển. Khi ở Chế độ chơi, hãy thử các giá trị khác nhau cho Hệ số tốc độ của Bầy đàn xâm lược và xem nó ảnh hưởng đến tốc độ của bầy đàn như thế nào.

Những kẻ xâm lược hiện đang di chuyển với tốc độ ngày càng nhanh qua rồi xuống màn hình.

Quân xâm lược đang di chuyển, nhưng chúng chưa bắn đạn. Bạn sẽ làm việc đó trong phần tiếp theo.

Khiến kẻ xâm lược bắn tia laze

Bạn sẽ sử dụng một biến thể của nhà lắp ghép Bullet cho quân xâm lược. Điều hướng đến RW/Prefabs và tìm EnemyBullet . Nó giống như Bullet , ngoại trừ các điểm sprite theo hướng Y ngược lại và lớp của nó được đặt thành Enemy .

Chọn EnemyBullet . Lưu ý Tốc độ của Bullet được đặt thành -200 . Điều này đảm bảo viên đạn di chuyển ngược hướng với viên đạn đại bác nhưng cùng độ lớn.

Cửa sổ Thanh tra cho nhà tiền chế EnemyBullet

Trong trò chơi, chỉ những kẻ xâm lược ở phía trước của bầy bắn đạn laze. Để đạt được điều này, bạn sẽ sử dụng bản cài sẵn BulletSpawner nằm trong RW/Prefabs .

Bạn sẽ khởi tạo nhiều trong số chúng bằng số lượng cột của kẻ xâm lược. Bạn cũng sẽ khiến những kẻ sinh ra đạn đi theo Kẻ xâm lược Biến hình ở phía trước bầy đàn.

Điều này sẽ đảm bảo rằng khi bắn, những viên đạn sẽ có vẻ như đến từ những kẻ xâm lược hàng đầu.

Trước khi bạn làm điều đó, bạn cần một cách để có được một kẻ xâm lược Chuyển đổi tại một hàng và cột cụ thể từ invadersmảng bên trong InvaderSwarm.

Mở tập lệnh InvaderSwarm.cs và thêm dòng sau vào sau InvaderTypephần khai báo cấu trúc:

 Phiên bản InvaderSwarm tĩnh bên trong ;

Điều này giúp biến InvaderSwarmthành một Singleton.

Sau đó dán đoạn sau vào ngay trên Start:

Biến đổi nội bộ GetInvader ( hàng int , cột int )
{
    nếu (hàng < 0 || cột < 0
        || hàng >= kẻ xâm lược.GetLength( 0 ) || cột >= kẻ xâm lược.GetLength( 1 ))
    {
        trả về  giá trị rỗng ;
    }

    trả lại kẻ xâm lược [hàng, cột];
}

 khoảng trống  riêng tư Tỉnh táo ()
{
    nếu (Trường hợp == null )
    {
        Ví dụ = cái này ;
    }
    khác  nếu (Trường hợp != this )
    {
        Phá hủy (gameObject);
    }
}

GetInvadertrả về kẻ xâm lược Biến đổi tại rowvà columnchỉ mục của kẻ xâm lược. Awakebiến nó InvaderSwarmthành Singleton bằng cách đảm bảo rằng khi trò chơi bắt đầu, chỉ một phiên bản của nó InvaderSwarmcòn sống.

Bây giờ, hãy chọn nhà lắp ghép BulletSpawner và xem Thanh tra. Lưu ý rằng nó có Bullet Spawner gắn liền với nó.

Ngoài ra còn có Kinematic Rigidbody 2D , Box Collider 2D và lớp được đặt thành Enemy . Bạn sẽ không thêm máy va chạm vào những kẻ xâm lược, mà sử dụng máy va chạm này để phát hiện các cú đánh từ đạn đại bác.

Cửa sổ Thanh tra cho BulletSpawner.

Trong trình chỉnh sửa mã của bạn, hãy mở tập lệnh BulletSpawner.cs được đính kèm với BulletSpawner và thêm phần sau vào bên trong lớp:

nội bộ  int currentRow;
cột int nội bộ  ;

[ SerializeField ]
 quay AudioClip riêng tư ;

[ SerializeField ]
 riêng GameObject bulletPrefab;

[ SerializeField ]
 Điểm sinh sản biến đổi riêng tư ;

[ SerializeField ]
 minTime float riêng ;

[ SerializeField ]
 thời gian maxTime riêng nổi  ;

 hẹn giờ nổi riêng ;
thời gian trôi nổi riêng tư  ;
chuyển đổi riêng tư theoTarget;

 Thiết lập khoảng trống  nội bộ ()
{
    currentTime = Random.Range(minTime, maxTime);
    followTarget = InvaderSwarm.Instance.GetInvader(currentRow, column);
}

 Cập nhật khoảng trống  riêng tư ()
{
    biến đổi.vị trí = theoTarget.vị trí;

    hẹn giờ += Time.deltaTime;
    nếu như (hẹn giờ <thời gian hiện tại)
    {
        trả lại ;
    }

    Khởi tạo(bulletPrefab, spawnPoint.position, Quaternion.identity);
    GameManager.Instance.PlaySfx(bắn súng);
    hẹn giờ = 0f ;
    currentTime = Random.Range(minTime, maxTime);
}

Đây là một sự cố mã:

  • currentTimeđại diện cho thời gian chờ cho đến khi bắn viên đạn tiếp theo. Nó được đặt thành một giá trị ngẫu nhiên giữa minTimevà maxTime.
  • currentRowvà columnliên kết một người tạo đạn với một kẻ xâm lược. Được columnđặt một lần và sẽ không thay đổi. Tuy nhiên, như bạn sẽ thấy ở phần sau, currentRowcác bản cập nhật nếu đạn của người chơi bắn trúng người sinh sản này.
  • Bên trong Setup(), bạn thiết lập followTargetbằng cách gọi GetInvadertừ InvaderSwarmthể hiện bằng cách sử dụng currentRowvà column. Bạn cũng đặt giá trị ban đầu thành currentTime.
  • Bên trong Update, bạn cập nhật vị trí của bộ sinh đạn để phù hợp với followTarget.position. Ngoài ra, bạn tăng cho timerđến khi nó đạt đến currentTime. Khi điều này xảy ra, bạn tạo một dấu đầu dòng spawnPoint.positiontrong khi phát shootinghiệu ứng âm thanh, sau đó đặt lại timervà currentTime.

Lưu tất cả mọi thứ. Quay trở lại Unity và mở BulletSpawner ở Prefab Mode . Đảm bảo các giá trị sau được đặt cho Bullet Spawner :

  • Bắn vào InvaderBullet đặt tại RW/Sounds .
  • Bullet Prefab to EnemyBullet đặt tại RW/Prefabs .
  • Điểm sinh sản đến Biến đổi SpawnPoint là con duy nhất của BulletSpawner .
  • Thời gian tối thiểu thành 1 và Thời gian tối đa thành 10 .

Thanh tra đang hiển thị tập lệnh Bullet Spawner.

Để sử dụng BulletSpawner , bạn cần quay lại tập lệnh InvaderSwarm.cs .

Đầu tiên, dán dòng sau vào cuối tất cả các khai báo biến:

[ SerializeField ]
 riêng BulletSpawner bulletSpawnerPrefab;

Sau đó, bên trong Start, thêm các dòng sau vào cuối:

cho ( int i = 0 ; i < cộtCount; i++)
{
    var bulletSpawner = Instantiate(bulletSpawnerPrefab);
    bulletSpawner.transform.SetParent(swarm.transform);
    đạnSpawner.column = i;
    bulletSpawner.currentRow = rowCount - 1 ;
    bulletSpawner.Setup();
}

Trong đoạn mã này, bạn tạo một bộ sinh đạn và thiết lập nó. Bạn khởi tạo bulletSpawnercho từng cột của bầy đàn và thiết lập cột đó columncurrentRowsau đó gọi Setupphương thức của nó. Bạn cũng cấp cha mẹ bulletSpawnercho Swarm để ngăn chặn sự lộn xộn trong Hệ thống phân cấp.

Lưu mọi thứ và quay lại Unity. Chọn Game Controller từ Hierarchy và đặt Bullet Spawner Prefab cho Invader Swarm thành BulletSpawner , nằm trong RW/Prefabs .

Lưu và chơi . Bây giờ bạn có những kẻ xâm lược bắn đạn vào người chơi.

Bầy hiện đang bắn đạn laze vào khẩu pháo.

Lưu ý rằng cả hai viên đạn đều biến mất khi viên đạn xâm lược và viên đạn đại bác va chạm. Viên đạn của kẻ xâm lược biến mất khi nó chạm vào khẩu đại bác và viên đạn của khẩu súng thần công biến mất khi nó chạm vào người tạo ra viên đạn. Chúng biến mất vì OnCollisionEnter2Dcác cuộc gọi DestroySelfbên trong Bullet.

Tuy nhiên, có một thứ còn thiếu, đó là các vụ nổ. :] Bạn sẽ thêm chúng vào tiếp theo.

Thêm vụ nổ

Điều hướng đến RW/Nhà lắp ghép . Chú ý nhà lắp ghép Explosion . Đó là một GameObject đơn giản với hoạt ảnh nhân vật được tạo sẵn mà bạn sẽ sử dụng cho hình ảnh vụ nổ.

Bây giờ, hãy mở lại GameManager.cs . Thêm phần sau sau khi khai báo sfx:

[ SerializeField ]
 GameObject riêng tư bùng nổPrefab;

[ SerializeField ]
 riêng nổi  floatTime = 1f ;

[ SerializeField ]
 AudioClip riêng tư ExplosionClip;

 khoảng trống  bên trong CreateExplosion ( Vị trí Vector2 )
{
    PlaySfx(clip vụ nổ);

    var nổ = Khởi tạo(vụ nổPrefab, vị trí,
        Quaternion.Euler( 0f , 0f , Random.Range( -180f , 180f )));
    Phá hủy (vụ nổ, thời gian nổ);
}

CreateExplosiontạo ra một vụ nổ với positionmột vòng quay ngẫu nhiên dọc theo trục Z và phá hủy nó sau explosionTimevài giây.

Để sử dụng CreateExplosion, hãy thêm dòng sau vào cuối bên DestroySelftrong Bulletlớp:

GameManager.Instance.CreateExplosion(transform.position);

Lưu tất cả. Quay lại Unity và chọn Trình điều khiển trò chơi từ Hệ thống phân cấp. Đối với bộ Trình quản lý trò chơi :

  • Explosion Prefab to Explosion nằm trong RW/Prefabs .
  • Explosion Clip to Explosion nằm trong RW/Sounds .

Thành phần Trình quản lý trò chơi trong cửa sổ Trình kiểm tra

Lưu cảnh và Phát . Bây giờ bạn có vụ nổ. :]

Bắn đạn bây giờ mang lại vụ nổ

Hiện tại, những viên đạn không ảnh hưởng đến quân xâm lược hoặc pháo. Trong các phần sau, bạn sẽ thêm điểm số và cuộc sống.

Thêm Điểm và Cuộc sống

Bạn có nhận thấy những nhãn UI siêu cổ điển đó trong chế độ xem trò chơi không? Ngay bây giờ họ chỉ là deadweight. Đã đến lúc bắt họ làm việc để có những mục tiêu và hậu quả mang lại ý nghĩa cho trò chơi này.

Thực hiện cuộc sống của người chơi

Mở GameManager.cs và thêm đoạn mã sau vào sau phần khai báo biến:

[ SerializeField ]
 private  int maxLives = 3 ;

[ SerializeField ]
 riêng Văn bản đời sốngLabel;

 cuộc sống riêng tư ;

nội bộ  void  UpdateLives ()
{
    cuộc sống = Mathf.Clamp(cuộc sống - 1 , 0 , maxLives);
    livesLabel.text = $"Lives: {lives} " ;
}

Gọi UpdateLivesgiảm livesbiến xuống một và cập nhật nhãn giao diện người dùng để phản ánh thay đổi. Hiện tại, không có gì xảy ra khi livesvề 0 nhưng bạn sẽ thay đổi điều đó sau.

Thêm phần sau vào cuối Awake:

cuộc sống = maxLives;
livesLabel.text = $"Lives: {lives} " ;

Mã này đặt giá trị mặc định cho livesvà cũng cập nhật nhãn giao diện người dùng.

Bây giờ, hãy mở CannonControl và dán các dòng sau vào sau phần khai báo biến:

[ SerializeField ]
 riêng  float respawnTime = 2f ;

[ SerializeField ]
 sprite SpriteRenderer riêng tư ;

[ SerializeField ]
 riêng Collider2D CannonCollider;

riêng Vector2 startPos;

private  void  Start () => startPos = transform.position;

Sau đó, thêm các dòng sau vào sau Update:

private  void  OnCollisionEnter2D ( Collision2D khác )
{
    GameManager.Instance.UpdateLives();
    StopAllCoroutines();
    StartCoroutine(Respawn());
}

System.Collections. Hồi sinh IEnumerator ()
{
    đã bật = sai ;
    CannonCollider.enabled = false ;
    ChangeSpriteAlpha( 0.0f );

    lợi nhuận  trả về  WaitForSeconds mới  ( 0,25f * respawnTime ) ;

    biến đổi. vị trí = startPos;
    đã bật = đúng ;
    ChangeSpriteAlpha( 0,25f );

    năng suất  trả về  WaitForSeconds mới  ( 0,75f * respawnTime ) ;

    ChangeSpriteAlpha( 1.0f );
    CannonCollider.enabled = true ;
}

private  void  ChangeSpriteAlpha ( giá trị float  )
{
    var color = sprite.color;
    color.a = giá trị ;
    sprite.color = màu;
}

Đây là những gì đang xảy ra:

  • ChangeSpriteAlphathay đổi độ mờ của sprite đại bác.
  • Khi một viên đạn bắn trúng khẩu đại bác, GameManager.UpdateLivestổng số mạng sẽ giảm xuống và Respawnquá trình điều tra bắt đầu.
  • Respawnđầu tiên vô hiệu hóa cannonCollidervà làm cho khẩu súng thần công trở nên vô hình. Sau một lúc, nó làm cho viên đạn pháo hơi trong suốt và đặt vị trí của khẩu pháo trở lại startPos. Cuối cùng, nó khôi phục độ mờ đục của sprite và kích hoạt lại máy va chạm.

Lưu mọi thứ và quay lại Unity. Chọn Bộ điều khiển trò chơi và đặt Nhãn trực tiếp của Trình quản lý trò chơi thành Văn bản trực tiếp , là phần tử con của Canvas .

Người kiểm tra cho người quản lý trò chơi

Đối với Điều khiển Cannon trên CANNON , đặt Sprite thành Sprite Renderer trên Sprite , một GameObject con của CANNON . Đặt Máy va chạm thành Máy va chạm hộp 2D trên CANNON .

Thanh tra cho thành phần Điều khiển Pháo

Bây giờ, lưu và chơi . Bạn sẽ thấy trình tự hồi sinh cũng như cập nhật mạng sống bất cứ khi nào một viên đạn bắn trúng khẩu pháo.

Pháo bây giờ mất mạng.

Những viên đạn dường như không ảnh hưởng đến những kẻ xâm lược. Bạn sẽ làm việc đó trong phần tiếp theo.

Thực hiện Điểm và Trò chơi kết thúc

Trước khi bạn làm bất cứ điều gì khác, hãy mở tập lệnh MusicControl.cs . Bạn muốn dừng nhạc khi trò chơi kết thúc, vì vậy hãy dán đoạn mã sau vào bên trong lớp:

[ SerializeField ]
 nguồn AudioSource riêng tư ;

nội  void  StopPlaying () => source.Stop();

StopPlayingdừng nguồn âm thanh khi được gọi.

Bây giờ, hãy mở tập lệnh GameManager.cs và thêm phần sau vào sau phần khai báo biến:

[ SerializeField ]
 nhạc MusicControl riêng tư ;

[ SerializeField ]
 Nhãn điểm văn bản riêng tư ;

[ SerializeField ]
 GameObject gameOver riêng tư ;

[ SerializeField ]
 GameObject riêng tư allClear;

[ SerializeField ]
 nút khởi động lại Nút riêng tư ;

 điểm int riêng ;

nội bộ  void  UpdateScore ( giá trị int  )
{
    điểm += giá trị ;
    scoreLabel.text = $"Điểm: {score} " ;
}

 khoảng trống  bên trong TriggerGameOver ( bool fail = true )
{
    gameOver.SetActive(thất bại);
    allClear.SetActive(!failure);
    restartButton.gameObject.SetActive( true );

    Thời gian.timeScale = 0f ;
    nhạc.StopPlaying();
}

Sau đó, dán các dòng sau vào cuối UpdateLives:

nếu (sống > 0 )
{
    trả lại ;
}

Kích hoạtGameOver();

Cuối cùng, thêm phần sau vào cuối Awake:

điểm = 0 ;
scoreLabel.text = $"Điểm: {score} " ;
gameOver.gameObject.SetActive( false );
allClear.gameObject.SetActive( false );

restartButton.onClick.AddListener(() =>
{
    SceneManager.LoadScene(SceneManager.GetActiveScene().name);
    Thời gian.timeScale = 1f ;
});
restartButton.gameObject.SetActive( false );

Đây là những gì mã này làm:

  • allClearlưu trữ một tham chiếu đến bảng Xóa tất cả , hiển thị khi người chơi loại bỏ tất cả những kẻ xâm lược. gameOvertham khảo bảng Trò chơi kết thúc hiển thị khi người chơi hết mạng.
  • UpdateScoregia số scoređược valuetruyền cho nó và cập nhật nhãn giao diện người dùng để phản ánh các thay đổi.
  • TriggerGameOverhiển thị bảng Game Over nếu failuređúng. Nếu không, nó sẽ hiển thị bảng All Clear . Nó cũng cho phép restartButton, tạm dừng trò chơi và dừng nhạc.
  • Awakexử lý onClicksự kiện cho nút khởi động lại. Nó tải lại cảnh khi nhấp vào.

Mở InvaderSwarm.cs và thêm phần sau vào bên trong lớp sau phần khai báo biến:

riêng  int killCount;
riêng System.Collections.Generic.Dictionary< string , int > pointMap;

 khoảng trống  nội bộ TăngDeathCount ()
{
    killCount++;
    if (killCount >= những kẻ xâm lược. Chiều dài)
    {
        GameManager.Instance.TriggerGameOver( false );
        trả lại ;
    }
}

nội bộ  int  GetPoints ( string AlienName )
{
    nếu (pointMap.ContainsKey(tên người ngoài hành tinh))
    {
        trả lại điểmBản đồ [tên người ngoài hành tinh];
    }
    trả về  0 ;
}

Sau đó dán dòng sau ngay phía trên int rowIndex = 0;bên trong Start:

pointMap = new System.Collections.Generic.Dictionary< string , int >();

Bên dưới dòng ngay bên dưới var invaderName = invaderType.name.Trim();thêm vào như sau:

pointMap[InvaderName] = InvaderType.points;

Đây là một sự cố mã:

  • pointsMaplà một Từ điển (ánh xạ từ chuỗi thành số nguyên). Nó ánh xạ loại kẻ xâm lược namevới pointsgiá trị của nó.
  • IncreaseDeathCounttheo dõi và cập nhật killCountkhi người chơi loại bỏ kẻ xâm lược. Khi người chơi loại bỏ tất cả những kẻ xâm lược, TriggerGameOvernhận falsevà hiển thị bảng All Clear .
  • GetPointstrả về các điểm được liên kết với loại kẻ xâm lược bằng cách chuyển tên của nó làm khóa.

Cuối cùng, mở BulletSpawner.cs để xử lý phát hiện va chạm đối với những kẻ xâm lược. Dán đoạn sau ngay sau Update:

private  void  OnCollisionEnter2D ( Collision2D khác )
{
    nếu (!other.collider.GetComponent<Bullet>())
    {
        trả lại ;
    }

    GameManager.Instance.
        UpdateScore(InvaderSwarm.Instance.GetPoints(followTarget.gameObject.name));

    InvaderSwarm.Instance.IncreaseDeathCount();

    followTarget.GetComponentInChildren<SpriteRenderer>().enabled = false ;
    currentRow = currentRow - 1 ;
    nếu (currentRow < 0 )
    {
        gameObject.SetActive( false );
    }
    khác 
    {
        Cài đặt();
    }
}

Đây là những gì mã này làm:

  • OnCollisionEnter2Dquay lại mà không làm bất cứ điều gì nếu đối tượng bắn trúng viên đạn không phải là loại Bullet.
  • Nếu viên đạn đại bác bắn trúng người sinh sản, điểm số và số lần tiêu diệt sẽ cập nhật. Ngoài ra, followTargetTrình kết xuất Sprite của hiện tại sẽ tắt, sau đó cập nhật tệp currentRow.
  • Nếu không còn bất kỳ hàng nào, GameObject sẽ bị tắt. Nếu không, bạn gọi Setupđể cập nhật tệp followTarget.

Ồ! Đó là rất nhiều việc. Lưu mọi thứ và quay lại Unity để hoàn thành bước này.

Chọn Nhạc và đặt Nguồn điều khiển nhạc thành thành phần Nguồn âm thanh trên cùng một GameObject.

Trình kiểm tra thành phần Điều khiển nhạc

Sau đó, chọn Bộ điều khiển trò chơi . Đối với Trình quản lý trò chơi , hãy đặt:

  • Music to Music Kiểm soát âm nhạc .
  • Điểm Nhãn để Điểm Văn bản .
  • Game Over đến Game Over Panel .
  • Tất cả rõ ràng đến tất cả rõ ràng .
  • Nút khởi động lại để khởi động lại nút .

Trình kiểm tra hiển thị thành phần Trình quản lý trò chơi

Lưu và chơi . Bây giờ bạn có thể giết những kẻ xâm lược! Bật Gizmos trong Chế độ xem trò chơi và chọn Swarm để xem cách cập nhật những người sinh đạn.

Các viên đạn laze bây giờ đánh và loại bỏ những kẻ xâm lược.

Giết tất cả những kẻ xâm lược để xem All Clear , hoặc để mạng sống cạn kiệt để xem Game Over . Sau đó, bạn có thể sử dụng nút Khởi động lại để tải lại cảnh.

Bảng Game Over
Bảng điều khiển All Clear

Những kẻ xâm lược hơi chậm và có cùng tốc độ trong suốt. Trong phần tiếp theo, bạn sẽ cập nhật tốc độ của chúng theo nhịp điệu của âm nhạc.

Thêm âm thanh động đơn giản

Truy cập MusicControl.cs . Mở nó bên trong trình chỉnh sửa mã của bạn. Thêm dòng sau vào đầu lớp:

 phao chỉ đọc  riêng tư defaultTempo = 1.33f ;

Dòng này biểu thị nhịp mặc định của nhạc mỗi giây. Bạn có thể tính toán giá trị này bằng cách xem xét bản nhạc có bốn nhịp và dài ba giây.

Bây giờ, dán như sau ở trên StopPlaying:

[ SerializeField ]
 internal  int pitchChangeSteps = 5 ;

[ SerializeField ]
 float riêng  maxPitch = 5.25f ;

riêng  float pitchChange;

 nhịp độ float bên trong { get ; bộ riêng  ; }

Sau đó, thêm các dòng sau vào sau định nghĩa cho StopPlaying:

 void  nội bộ TăngPitch ()
{
    nếu như (source.pitch == maxPitch)
    {
        trở lại ;
    }

    source.pitch = Mathf.Clamp(source.pitch + pitchChange, 1 , maxPitch);
    Nhịp độ = Mathf.Pow( 2 , thay đổi độ cao) * Nhịp độ;
}

 khoảng trống  riêng Bắt đầu ()
{
    nguồn.pitch = 1f ;
    Nhịp độ = defaultTempo;
    pitchChange = maxPitch / pitchChangeSteps;
}

Đây là cách mã hoạt động:

  • Inside Startvà source.pitchđược Tempođặt thành giá trị mặc định của chúng.
  • IncreasePitchtăng cao độ của âm thanh nguồn theo một lượng được xác định bởi pitchChange, lần lượt là tỷ lệ của maxPitchvà pitchChangeStepsmaxPitchcũng đặt ra giới hạn trên cho sân cỏ.
  • Sau khi thay đổi cao độ, bạn có thể tính toán nhịp độ dựa trên công thức sau:

pitchchange = -log(2)(tempo1/tempo2) trong đó tempo1 biểu thị nhịp độ trước khi thay đổi và tempo2 biểu thị nhịp độ sau khi thay đổi.

Bây giờ hãy mở tập lệnh InvaderSwarm.cs và thêm phần sau vào cuối phần khai báo biến:

[ SerializeField ]
 MusicControl riêng MusicControl;

riêng  int tempKillCount;

Trong IncreaseDeathCount, dán các dòng sau vào cuối:

tempKillCount++;
nếu (tempKillCount < kẻ xâm lược. Độ dài / musicControl.pitchChangeSteps)
{
    trả lại ;
}

musicControl.IncreasePitch();
tempKillCount = 0 ;

Bây giờ IncreaseDeathCounttheo dõi biến tempKillCountđể kiểm tra xem nó có vượt quá invaders.Length / musicControl.pitchChangeSteps. Nếu có, nó sẽ gọi IncreasePitchvà tempKillCountđặt lại.

Điều này có nghĩa là khi người chơi loại bỏ hầu hết invaders.Length / musicControl.pitchChangeStepsnhững kẻ xâm lược, cả cường độ âm thanh và nhịp độ đều tăng. Biến Tempobên trong MusicControltheo dõi nhịp độ được cập nhật.

Cuối cùng, bên trong Update, thay thế xIncrement = speedFactor * Time.deltaTime;bằng:

xIncrement = speedFactor * musicControl.Tempo * Time.deltaTime;

Dòng này đảm bảo xem xIncrementxét nhịp độ âm nhạc và những kẻ xâm lược di chuyển nhanh hơn khi âm nhạc nhanh hơn khi người chơi loại bỏ ngày càng nhiều kẻ xâm lược.

Lưu tất cả mọi thứ. Quay lại Unity và chọn Game Controller . Đặt Invader Swarm ‘s Music Control thành Music .

Lưu và chơi .

Thanh tra hiển thị thành phần Invader Swarm

Hãy thử bắn hạ những kẻ xâm lược. Bạn sẽ nhận thấy chúng bắt đầu di chuyển nhanh hơn.

Những kẻ xâm lược bị bắn, và đàn di chuyển với tốc độ ngày càng tăng.

Vẫn còn một vấn đề nhỏ: Nếu bạn bỏ lỡ bất kỳ kẻ xâm lược nào, chúng sẽ tiếp tục di chuyển khi đến cuối màn hình. Sẽ tốt hơn nếu kích hoạt Trò chơi kết thúc nếu đàn chạm đến đáy.

Để thực hiện việc này, hãy mở InvaderSwarm.cs và thêm phần sau vào cuối phần khai báo biến:

[ SerializeField ]
 riêng Chuyển đổi CannonPosition;

 phao riêng minY;
phao riêng  hiện tạiY;

Sau đó, dán các dòng sau vào đầu Start:

currentY = spawnStartPoint.position.y;
minY = CannonPosition.position.y;

Sau đó thêm phần sau vào cuối ChangeDirection:

hiện tạiY -= ySpacing;
nếu (hiện tạiY < minY)
{
    GameManager.Instance.TriggerGameOver();
}

Đây là những gì mã này làm:

  • Bên trong Start, bạn đặt minYở vị trí Y của pháo và currentYở vị trí Y của spawnStartPoint.
  • Bất cứ khi nào được gọi, nó ChangeDirectionsẽ giảm dần currentYcho đến khi nó nhỏ hơn minY, lúc đó trò chơi kết thúc và hiển thị Game Over .

Lưu tất cả mọi thứ. Quay lại Unity và chọn Game Controller . Đặt Cannon Vị trí của Invader Swarm thành Transform của CANNON .

Cửa sổ Trình kiểm tra hiển thị thành phần Invader Swarm

Lưu và chơi . Bây giờ, bạn sẽ thấy bảng Trò chơi kết thúc được kích hoạt nếu đàn đi xuống dưới vị trí của khẩu đại bác.

Bảng Trò chơi kết thúc hiển thị sau khi quân xâm lược đến bên dưới vị trí của khẩu đại bác.

Và bạn đã hoàn tất!

Đi đâu từ đây?

Bạn có thể sử dụng nút Tải xuống Tài liệu ở đầu và cuối hướng dẫn này để tải xuống cả dự án khởi đầu và dự án cuối cùng.

Bạn có thể nhận thấy rằng bạn đã không thêm bất kỳ ngọn đuốc nào. Hãy thử thêm chúng như một thử thách.

Tất cả mọi thứ bạn cần đã có sẵn. Bạn có thể cần kiểm tra mã bên trong TorchkasManager và tập lệnh Torchka . Nếu bạn gặp khó khăn, hãy xem Dự án cuối cùng để biết giải pháp. Chúc may mắn!

Toàn bộ trò chơi, với Torchkas!

Cảm ơn đã dành thời gian để đọc bài viết này. Tôi hy vọng bạn đã vui vẻ và học được điều gì đó mới. Xin vui lòng tham gia diễn đàn dưới đây cho bất kỳ câu hỏi hoặc ý kiến.

Đặc biệt cảm ơn người dùng opengameart jlunesc vì một số tài sản CC-BY được sử dụng trong dự án.

2D Space Shooter (for beginners)

Giới thiệu:
Tại đây, bạn có thể xem cách thực hiện trò chơi bắn súng không gian 2D đơn giản với công cụ Unity 3D. Tôi sẽ sử dụng vật lý 2D tích hợp sẵn. Bạn sẽ cần một số hình ảnh cho hướng dẫn này. Bạn có thể tải xuống tại đây. * Và bạn nên tải xuống các tệp âm thanh đóng gói tại đây.
*Nếu trình duyệt của bạn chỉ mở hình ảnh, thì bạn nên tải xuống thủ công. Nhấp chuột phải vào hình ảnh và lưu nó. Hoặc nhấp chuột phải vào liên kết tải xuống và chọn mục tiêu lưu.
1 bước
Tạo dự án Unity 2D mới. Nhập hình ảnh không gian đã tải xuống (bạn chỉ cần kéo và thả nó vào cửa sổ Nội dung hoặc nhấp chuột phải vào cửa sổ Nội dung – chọn Nhập nội dung mới – chọn hình ảnh không gian đã tải xuống và nhấp vào Nhập). Chọn spaceImage trong cửa sổ Nội dung và đặt Chế độ Sprite thành Nhiều trong Trình kiểm tra của nó. Nhấp vào Áp dụng.import assets

Bây giờ bấm vào Sprite Editor. Nhấp vào Lát. Kiểm tra xem Loại được đặt thành Tự động và nhấp vào Nút Slice. Nhấp vào Áp dụng và đóng trình chỉnh sửa sprite.

2. Bước
Lúc đầu, chúng tôi có thể khiến người chơi giao hàng. Trong Trò chơi đuổi bắt 2D, chúng tôi đã sử dụng bàn phím để di chuyển trình phát của mình. Bây giờ chúng ta sẽ sử dụng chuột để di chuyển. Tàu của chúng tôi sẽ bay đến điểm, nơi chúng tôi đã nhấp. Đưa hình ảnh con tàu vào khung cảnh. Unity sẽ tạo GameObject mới. Đổi tên thành Player. Và đặt Thẻ của nó thành Người chơi.
tạo tàu người chơi

Chúng tôi sẽ sử dụng vật lý 2D tích hợp sẵn. Thêm vào Trình phát: Box Collider 2D và Rigidbody 2D (Thêm Thành phần – Vật lý 2D – …). Đặt Thang trọng lực thành 0 (chúng ta không cần trọng lực) và Nội suy thành Nội suy (để di chuyển mượt mà hơn). Kích hoạt Freeze Rotation Z trong Constraints (để ngăn tàu quay).
thêm các thành phần cho người chơi

3. Bước
Bây giờ chúng ta có thể tạo một tập lệnh chuyển động cho trình phát của mình. Tạo tập lệnh C# mới (nhấp chuột phải vào cửa sổ Tài sản và chọn tạo – tập lệnh C#). Đặt tên cho nó là PlayerMove. Bây giờ giải thích một chút, chúng ta sẽ làm gì:
Phép trừ vectơ:
Với phép trừ véc tơ, chúng ta có thể nhận được hướng và khoảng cách từ đối tượng trò chơi này sang đối tượng trò chơi khác. Kiểm tra Hướng dẫn thống nhất để biết thông tin. Vectơ bị trừ này có thể được sử dụng làm hướng từ tàu của người chơi đến vị trí được nhấp. Chúng ta có thể thay đổi vận tốc của tàu theo vectơ này và tàu sẽ di chuyển đến vị trí được nhấp.* Độ dài của vectơ này là khoảng cách giữa tàu và vị trí được nhấp. Bạn có thể lấy nó với Vector3.magnitude. Phép tính căn bậc hai tốn cpu. Vì vậy, hãy cẩn thận với nó. Bạn có thể sử dụng Vector3.sqrMagnitude để thay thế. Kiểm tra Hướng dẫn thống nhất để biết thông tin.
* Đôi khi lấy véc tơ bị trừ trực tiếp không phải là lựa chọn tốt nhất. Con tàu sẽ bay nhanh nếu bạn nhấp xa và chậm nếu bạn nhấp gần. Vì vậy, bạn sẽ chỉ cần hướng từ vectơ bị trừ và chiều dài của nó phải là 1. Đây là một vectơ chuẩn hóa. Bạn có thể lấy nó từ vector đã trừ bằng Vector3.Normalize. Sau đó, bạn có thể nhân nó với tốc độ cần thiết của mình. Chúng tôi không cần vectơ chuẩn hóa cho hướng dẫn của mình.
véc tơ giải thích
Chúng ta có thể lấy vị trí từ con tàu của mình bằng transform.position. Sau đó, chúng ta cần vị trí thế giới từ vị trí được nhấp. Vị trí chuột là vị trí màn hình. Chúng ta nên chuyển đổi nó sang vị trí thế giới. Bạn có thể lấy điểm thế giới này bằng: Camera.ScreenToWorldPoint.
Camera.ScreenToWorldPoint
Chức năng này có thể chuyển đổi vị trí màn hình sang vị trí thế giới. Vị trí màn hình được xác định bằng pixel. Xin lưu ý rằng Vị trí Z sẽ giống với Vị trí Z của Máy ảnh. Kiểm tra Hướng dẫn thống nhất để biết thông tin.
Trong cảnh của chúng ta, chúng ta nên có Camera chính. Vì vậy, dòng C# sẽ là: clickPos = Camera.main.ScreenToWorldPoint (Input.mousePosition);. Ít nhất chúng ta có thể tính toán vectơ chỉ hướng với clickPos – transform.position. Và sử dụng vectơ này làm vectơ vận tốc cho con tàu của chúng ta. Tạo tập lệnh C# mới và đặt tên là PlayerMove Tập lệnh C# chuyển động bây giờ sẽ là:
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai PlayerMove : MonoBehaviour {

// biến cho vị trí được nhấp
Vector3 clickPos;
// chúng tôi sẽ sử dụng vectơ này làm vận tốc cho Rigidbody2D (hướng và tốc độ)
Vector3 di chuyển;
// biến cho tốc độ người chơi
tốc độ phao công = 1;
// chúng tôi sẽ cần tham chiếu đến Người chơi Rigidbody2D
Thân cứng2D rb;

// sẽ được thực thi một lần khi bắt đầu tập lệnh
khoảng trống Bắt đầu () {
// tham chiếu đến Người chơi Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
//người chơi nên giữ nguyên vị trí của nó khi bắt đầu trò chơi (hoặc nó sẽ chuyển sang clickPos (0,0,0) làm Vector3 mặc định)
clickPos = biến đổi. vị trí;
}

// sẽ được thực thi mọi khung hình
void Cập nhật () {
// kiểm tra chuột trái có được nhấn không
nếu (Input.GetMouseButton (0)) {
// chuyển đổi vị trí màn hình chuột sang vị trí thế giới
clickPos = Camera.main.ScreenToWorldPoint(Input.mousePosition);
}
// tính vectơ hướng từ tàu đến điểm được nhấp
di chuyển = clickPos – biến đổi.vị trí;
}

// sẽ được thực thi tại các bước thời gian cố định (mặc định 0,02). Sử dụng cái này cho vật lý Unity
void FixedUpdate() {
// thay đổi vận tốc thành vector chuyển động được tính toán
// z sẽ giữ nguyên số không. Tàu của chúng ta không nên di chuyển trên Z-Axe
rb.velocity = new Vector2 (move.x, move.y) * tốc độ;
}
}
Thêm tập lệnh này vào Player. Đặt tốc độ thành 1. Bắt đầu cảnh và kiểm tra xem tất cả có hoạt động không.
thêm tập lệnh
4. Bước
Tàu của chúng tôi sẽ bắn laze. Đặt hình ảnh laser vào cảnh. Unity sẽ tạo đối tượng trò chơi mới. Đổi tên nó thành Laser. Đặt Thứ tự trong Lớp thành -10. Tia laser sẽ được hiển thị dưới con tàu (chúng ta có thể đặt nó thành -1, có thể sau này chúng ta sẽ cần giá trị này cho các GameObject khác). Làm cho nó nhỏ hơn một chút (tỷ lệ 0,5 sẽ ổn). Thêm Box Collider 2D vào nó. Kích hoạt hộp kiểm Is Trigger (chúng tôi sẽ cần nó chỉ để kiểm tra va chạm). Thêm Rigidbody2D. Đặt Gravity thành 0 và Nội suy thành Nội suy.
tạo tia laze

5. Bước
Tia laser sẽ bay lên trên Y-axe. Chúng tôi cần một kịch bản kiểm soát cho họ. Tạo tập lệnh C# mới. Đặt tên cho nó là LaserShot. Lần này chúng ta sẽ di chuyển tia laser bằng AddForce. Chúng ta sẽ lấy tham chiếu đến Rigidbody2D và sau đó sử dụng lực đẩy theo hướng Y trên đó. Chúng ta nên phá hủy tia laser của mình nếu nó nằm ngoài màn hình. Chúng tôi không cần chúng bay mọi lúc (vì Unity sẽ tính toán các phát bắn vô hình và sẽ chậm hơn). Chúng ta có thể sử dụng thông báo OnBecameInvisible để gọi hàm hủy của mình. Kịch bản nên là:
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai LaserShot : MonoBehaviour {

//biến tham chiếu cho Rigidbody2D
Thân cứng2D rb;
// biến cho công suất lực
lực lượng phao công cộng;

// sẽ được thực hiện một lần
khoảng trống Bắt đầu () {
// tham chiếu đến Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
// khai báo Vector3 với giá trị lực trên trục Y
Vector3 directon = new Vector3(0, force, 0);
// thêm lực đẩy vào Hardbody2D để di chuyển trên Y-axe
rb.AddForce (directon, ForceMode2D.Impulse);
}
// sẽ được thực thi, nếu gameobject không hiển thị nữa trên màn hình
void OnBecameInvisible () {
// xóa gameobject này khỏi hiện trường
Tiêu diệt (gameObject);
}
}

Thêm tập lệnh này vào đối tượng trò chơi Laser. Và đặt lực lượng thành một cái gì đó như 5 (đó là sức mạnh lực lượng).
Chúng tôi sẽ sinh ra nhiều tia laser. Vì vậy, chúng tôi cần một nhà lắp ghép (như bản thiết kế) của chúng. Chỉ cần kéo và thả đối tượng trò chơi Laser vào cửa sổ Asstes. Unity sẽ tự động tạo prefab. Bạn có thể xóa Laser khỏi cửa sổ Hierarchy, nếu bạn đã tạo laser prefab.
tạo laser tiền chế
6. Bước
Bắn laze bây giờ có thể bay. Nếu chúng ta bắn, chúng ta chỉ nên sinh ra Laser trên vị trí của tàu. Chúng ta có thể sử dụng chức năng Khởi tạo để sinh sản. Là nút lửa, chúng tôi sẽ sử dụng nút chuột phải. Kịch bản của chúng tôi sẽ kiểm tra xem nút bắn có được nhấn hay không và đặt tia laser trong trường hợp này. Việc kiểm tra này sẽ được thực hiện trên mọi khung hình và để tránh chụp nhiều ảnh, chúng ta nên tạo độ trễ khi chụp. Chúng ta có thể sử dụng coroutine, có thể tạm dừng. Kiểm tra hướng dẫn thống nhất. Tạo tập lệnh C# mới và đặt tên là PlayerShoot. Kịch bản sẽ là:
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai PlayerShoot : MonoBehaviour {

// biến cho nhà lắp ghép bằng laser
laser GameObject công cộng;
// độ trễ giữa các lần bắn laser
thời gian trễ thả nổi công khai;
//boolean, nếu laser có thể được sinh ra
bool canShoot = true;

// sẽ được thực thi mọi khung hình
void Cập nhật () {
// kiểm tra xem tia laser có thể được sinh ra không và nhấn nút chuột phải
nếu (canShoot && Input.GetMouseButton(1)) {
// vô hiệu hóa kiểm tra chụp cho khung hình tiếp theo
canShoot = sai;
//đặt laze prefab trong cảnh ở vị trí tàu (xoay như tàu)
Khởi tạo (laser, biến đổi.vị trí, biến đổi.xoay);
// bắt đầu chức năng (sẽ cho phép chụp) dưới dạng coroutine
StartCoroutine (NoFire());
}
}

// chức năng coroutine, chúng ta có thể tạm dừng nó
IEnumerator NoFire () {
// tạm dừng hàm và quay lại sau trong “delayTime” giây
năng suất trả về WaitForSeconds mới (thời gian trễ);
// cho phép chụp để kiểm tra tiếp theo
canShoot = true;
}
}

Thêm tập lệnh này vào tàu của người chơi. Đặt nhà lắp ghép Laser trong trường Laser. Đặt Thời gian trễ thành 0,5. Bắt đầu cảnh và kiểm tra nó.
thêm tiền chế laser vào trình phát
7. Bước
Bây giờ chúng ta có thể tạo ra các tiểu hành tinh. Kéo và thả hình ảnh tiểu hành tinh vào cảnh. Đổi tên gameobject đã tạo thành Asteroid. Đặt Thứ tự trong Lớp trong Trình kết xuất Sprite của nó thành -5 (dưới tàu và trên laser). Thêm vào đó Máy va chạm vòng tròn 2D. Thêm Rigidbody2D. Đặt Thang trọng lực thành 0 và Nội suy thành Nội suy. Thêm thẻ mới Kẻ thù và đặt thẻ Tiểu hành tinh thành Kẻ thù.
tạo tiểu hành tinh
8. Bước
Tiểu hành tinh cần một kịch bản chuyển động. Tạo tập lệnh C# mới và đặt tên là AsteroidMove. Chúng tôi sẽ thay đổi vận tốc của tiểu hành tinh trên Y-axe. Và chúng ta nên tiêu diệt các tiểu hành tinh nếu chúng nằm ngoài màn hình. Sau đó, chúng tôi sẽ kiểm tra xem có tiểu hành tinh nào va vào người chơi không. Chúng tôi có thể sử dụng OnCollisionEnter2D. Thông báo này sẽ được gọi nếu các đối tượng trò chơi với Collider2D bị va chạm. Sau đó, chúng tôi có thể kiểm tra Thẻ của đối tượng trò chơi bị va chạm và hủy chúng nếu đó là Người chơi. Nếu người chơi bị phá hủy, chúng ta nên tải lại cảnh. Chúng ta nên sử dụng SceneManager để tải lại cảnh.
Tạo tập lệnh C# mới và đặt tên là AsteroidMove.
sử dụng UnityEngine;
sử dụng System.Collections;
// không gian tên với các điều khiển cảnh khác nhau
sử dụng UnityEngine.SceneManagement;

lớp công khai AsteroidMove : MonoBehaviour {

//biến cho tốc độ bay
tốc độ phao công cộng;
// tham chiếu cho Rigidbody2D
Thân cứng2D rb;

// sẽ được thực thi một lần khi bắt đầu tập lệnh
khoảng trống Bắt đầu () {
// tham chiếu đến Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
//khai báo véc tơ chỉ phương di chuyển (cái này sẽ nằm dọc theo trục Y)
Vector3 di chuyển = new Vector3(0, -1, 0);
// thay đổi vận tốc (tốc độ và hướng di chuyển)
rb.velocity = di chuyển * tốc độ;
}

// sẽ được thực thi nếu gameobject không được hiển thị nữa trên màn hình
void OnBecameInvisible () {
//xóa gameobject khỏi cảnh
Tiêu diệt (gameObject);
}

// sẽ được thực thi nếu các Collider2D khác nhau chạm vào nhau
void OnCollisionEnter2D (Collision2D gì đó) {
// kiểm tra Thẻ của đối tượng trò chơi đã chạm
if (something.gameObject.tag == “Người chơi”) {
//xóa gameobject khỏi cảnh
Tiêu diệt (gameObject);

// tải lại cùng một cảnh (tải lại)
SceneManager.LoadScene (SceneManager.GetActiveScene().name);
}
}
}

Thêm tập lệnh này vào Tiểu hành tinh. Đặt Tốc độ thành 1. Tạo tiểu hành tinh lắp sẵn (kéo và thả Tiểu hành tinh từ cửa sổ Phân cấp đến Tài sản). Xóa Tiểu hành tinh khỏi Hệ thống phân cấp.
tạo tiền chế tiểu hành tinh
9. Bước
Chúng tôi cần spawner, thứ có thể sinh ra các tiểu hành tinh một cách ngẫu nhiên. Bấm vào GameObject – Tạo trống. GameObject trống sẽ được tạo trong cảnh. Đổi tên nó thành AsteroidSpawner. Chọn một Biểu tượng để xem tốt hơn (kiểm tra ảnh chụp màn hình). Di chuyển nó sang bên trái trên Camera View (bạn có thể sử dụng công cụ di chuyển). Và đặt Z-Position thành 0 (nếu khác 0).
tạo vị trí bên trái cho spawner
Chọn AsteroidSpawner trong cửa sổ Hierarchy. Nhấp chuột phải vào nó và nhân đôi nó. Đổi tên đối tượng trò chơi mới đã tạo thành RightPosition. Biến RightPosition thành con của AsteroidSpawner (chỉ cần kéo và thả RightPosition trên AsteroidSpawner trong Hệ thống phân cấp). Di chuyển RightPosition sang bên phải và đặt Z-Position thành 0 (nếu khác).
tạo đúng vị trí cho spawner
Bây giờ hãy tạo tập lệnh C# mới và đặt tên là ObjectSpawner. Chúng tôi sẽ liên tục gọi một chức năng sinh sản. InvokeRepeating sẽ thực hiện công việc này. Kịch bản sẽ là:
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai ObjectSpawner : MonoBehaviour {

//biến cho vị trí, sẽ được sử dụng để tính toán vị trí ngẫu nhiên giữa hai điểm
chuyển đổi công khai RightPosition;
// độ trễ giữa các lần sinh sản
công cộng float spawnDelay;
// biến cho prefab, sẽ được sinh ra
Mục GameObject công khai;

// sẽ được thực hiện một lần khi bắt đầu
khoảng trống Bắt đầu () {
// Hàm “Spawn” sẽ được gọi lặp lại
InvokeRepeating(“Spawn”, spawnDelay, spawnDelay);
}

//chức năng sinh sản
khoảng trống đẻ trứng () {
// tính toán vị trí ngẫu nhiên giữa AsteroidSpawner và RighPosition
Vector3 spawnPos = new Vector3 (Random.Range (transform.poseition.x, RightPosition.position.x), biến đổi.poseition.y, 0);
//đặt prefab tại vị trí tính toán
Khởi tạo (Item, spawnPos, transform.rotation);
}
}

Chọn AsteroidSpawner trong Hệ thống phân cấp. Thêm tập lệnh này vào nó. Nhấp vào điểm chọn gần trường Vị trí bên phải và chọn Vị trí bên phải. Đặt Độ trễ đẻ trứng thành 5. Nhấp vào điểm chọn gần trường Vật phẩm và chọn nhà lắp ghép Tiểu hành tinh. Bắt đầu cảnh và kiểm tra nó.
10. Bước
Các tia laser có thể bay qua tất cả các tiểu hành tinh. Chúng tôi cần tập lệnh để kiểm tra va chạm và gây ra thiệt hại. Các đối tượng phải có điểm sức khỏe và chúng ta cần tập lệnh kiểm soát điểm sức khỏe. Là điểm sức khỏe, chúng ta có thể định nghĩa biến int hp. Đối với sát thương, chúng ta có thể viết phương thức, trừ biến sát thương khỏi điểm sức khỏe. Tạo tập lệnh C# mới và đặt tên là HpController.
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai HpController : MonoBehaviour {

// biến cho điểm sức khỏe
công khai int hp;

//funkton để tính toán thiệt hại (chúng tôi sẽ nhận được thiệt hại từ các chức năng khác)
void MakeDamage (thiệt hại int) {
//giảm biến hp
hp = hp – thiệt hại;
//kiểm tra xem hp âm hay không
nếu (hp <= 0) {
//xóa gameobject
Tiêu diệt (gameObject);
}
}
}

Chọn Asteroid prefab trong cửa sổ Assets và thêm tập lệnh HpController vào đó. Đặt biến HP thành 3.
thêm prefab tiểu hành tinh vào spawner
Bây giờ hãy mở tập lệnh LaserShot. Chúng tôi sẽ thêm kiểm tra va chạm vào nó. Laser có Collider2D làm Trình kích hoạt. Chúng tôi có thể sử dụng vật lý Unitys để kiểm tra va chạm: OnTriggerEnter2D. Nếu đối tượng trò chơi được chọn có thẻ Kẻ thù, chúng tôi sẽ sử dụng SendMessage. Phương thức này kiểm tra xem có bất kỳ thành phần nào trên đối tượng trò chơi khác có phương thức với tên được xác định hay không và gọi nó. Kiểm tra hướng dẫn thống nhất.

sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai LaserShot : MonoBehaviour {

//biến tham chiếu cho Rigidbody2D
Thân cứng2D rb;
//biến cho thiệt hại
thiệt hại int công khai;
// biến cho công suất lực
lực lượng phao công cộng;

// sẽ được thực hiện một lần
khoảng trống Bắt đầu () {
// tham chiếu đến Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
// khai báo Vector3 với giá trị lực trên trục Y
Vector3 directon = new Vector3(0, force, 0);
// thêm lực đẩy vào Hardbody2D để di chuyển trên Y-axe
rb.AddForce (directon, ForceMode2D.Impulse);
}
// sẽ được thực thi, nếu gameobject không hiển thị nữa trên màn hình
void OnBecameInvisible () {
// xóa gameobject này khỏi hiện trường
Tiêu diệt (gameObject);
}
// sẽ được thực thi nếu một Collider2D khác đi vào Trigger
void OnTriggerEnter2D (Collider2D khác) {
// kiểm tra xem gameobject khác có tag Enemy không
if (other.gameObject.tag == “Kẻ thù”) {
// thử gọi MakeDamage trên gameobject khác, gửi damage làm tham số cho nó
other.gameObject.SendMessage(“MakeDamage”, dam, SendMessageOptions.DontRequireReceiver);
//xóa gameobject khỏi cảnh
Tiêu diệt (gameObject);
}
}
}

Chọn Laser prefab trong cửa sổ Tài sản. Tập lệnh LaserShot hiện có sát thương thay đổi mới. Thay đổi nó thành 1.
thay đổi giá trị thiệt hại trong tập lệnh laser
Bạn có thể bắt đầu cảnh. Bây giờ các tiểu hành tinh sẽ bị phá hủy với 3 phát bắn.
11. Bước
Chúng ta nên tạo ra tàu địch ngay bây giờ. Tôi hơi lười biếng, vì vậy chúng tôi chỉ có thể sử dụng lại nhà lắp ghép Tiểu hành tinh. Đặt prefab Tiểu hành tinh vào cảnh (kéo và thả nó từ cửa sổ Nội dung vào Chế độ xem cảnh). Chọn nó trong Hierarchy và đổi tên thành Enemy. Thay đổi biến HP thành 1. Thay đổi nhân vật tiểu hành tinh thành nhân vật địch. Xóa Circle Collider 2D (nhấp chuột phải vào Circle Collider 2D và chọn Remove Component). Thêm Box Collider 2D mới. Tạo một prefab từ Kẻ thù (kéo và thả Kẻ thù từ Hệ thống phân cấp vào cửa sổ Tài sản). Xóa Kẻ thù khỏi Hệ thống cấp bậc sau khi nhà lắp ghép sẵn được tạo.
tạo kẻ thù
12. Bước
Tàu địch cần kịch bản bắn. Kẻ thù sẽ tìm thấy tàu của người chơi sau khi nó được sinh ra và sau đó bắn vào chúng. Chúng ta có thể tìm kiếm một gameobject với GameObject.FindWithTag(“Tag”);. Sau đó, kẻ thù sẽ sinh ra một viên đạn, viên đạn này sẽ tính toán vectơ hướng từ viên đạn đến người chơi rồi bay đến người chơi. Lúc đầu, chúng tôi sẽ tạo đối tượng trò chơi đạn. Kéo và thả hình ảnh viên đạn vào cảnh. Chọn đối tượng trò chơi đã tạo trong Hệ thống phân cấp. Đổi tên nó thành Bullet. Thay đổi Thứ tự của nó trong Lớp thành -6. Thêm Rigidbody2D. Đặt Gravity thành 0 và Nội suy thành Nội suy. Thêm Box Collider 2D và bật Is Trigger. Bây giờ chúng ta cần tập lệnh để điều khiển các viên đạn. Tạo tập lệnh C# mới và đặt tên là EnemyBullet.

sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai EnemyBullet : MonoBehaviour {

// biến tham chiếu cho đối tượng Người chơi game
Trình phát GameObject;
//biến tham chiếu cho Rigidbody2D
Thân cứng2D rb;
// biến cho công suất lực
lực lượng phao công cộng;
//biến cho giá trị thiệt hại
thiệt hại int công khai;

// sẽ được thực hiện một lần khi bắt đầu
khoảng trống Bắt đầu () {
// tham chiếu đến Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
//tìm kiếm đối tượng game bằng thẻ Player và tham khảo chúng
người chơi = GameObject.FindWithTag(“Người chơi”);
//kiểm tra xem Người chơi có ở trong cảnh không
nếu (người chơi != null) {
// tính véc tơ chỉ phương cho Player
Vector3 dir = player.transform.position – transform.position;
// tính góc giữa trục X và vectơ chỉ phương
góc float = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
// xoay viên đạn gameobject
biến đổi.Rotate(0, 0, angle);
// đẩy viên đạn vào rìu X ngôn ngữ của nó (nó sẽ chuyển tiếp cho hình ảnh này)
rb.AddRelativeForce(Vector2.right*force, ForceMode2D.Impulse);
// nếu Người chơi không có trong cảnh
} khác
//xóa dấu đầu dòng khỏi cảnh
Tiêu diệt (gameObject);
}

// sẽ được thực thi nếu Collider2D đi vào Trigger
void OnTriggerEnter2D (Collider2D khác) {
// kiểm tra xem gameobject bị va chạm có thẻ Player không
if (other.gameObject.tag == “Người chơi”) {
// cố gắng thực thi chức năng “MakeDamage” với tham số “thiệt hại” trong tập lệnh được kết nối với đối tượng trò chơi bị va chạm
other.gameObject.SendMessage(“MakeDamage”, dam, SendMessageOptions.DontRequireReceiver);
//xóa dấu đầu dòng
Tiêu diệt (gameObject);
}
}

//sẽ được thực thi nếu dấu đầu dòng không được hiển thị nữa (ngoài màn hình)
void OnBecameInvisible () {
//xóa dấu đầu dòng
Tiêu diệt (gameObject);
}
}

Thêm tập lệnh này vào Bullet. Đặt Force thành 3 và Damage thành 1. Bây giờ hãy tạo prefab từ Bullet (kéo và thả Bullet từ Hierarchy sang Assets). Nếu nhà lắp ghép đã được tạo, hãy xóa Dấu đầu dòng khỏi Hệ thống phân cấp.
tạo đạn kẻ thù
12. Bước
Bây giờ chúng ta có thể tạo kịch bản bắn kẻ thù. Kẻ thù sẽ kiểm tra vị trí của Người chơi và định kỳ sinh ra một Viên đạn (sẽ tính toán hướng cho Người chơi và bay đến chỗ họ). Tạo tập lệnh C# mới và đặt tên là EnemyShoot.

sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai EnemyShoot : MonoBehaviour {

// biến cho Bullet prefab
viên đạn GameObject công khai;
// độ trễ giữa các lần chụp
phao công cộng fireDelay;
// biến cho Player gameobject
Trình phát GameObject;
//boolean để kiểm tra xem Kẻ thù có thể bắn không
bool canShoot = true;

// sẽ được thực hiện một lần
khoảng trống Bắt đầu () {
//tìm kiếm đối tượng trò chơi với thẻ “Người chơi” và tham chiếu nó tới người chơi
người chơi = GameObject.FindWithTag(“Người chơi”);
}

// sẽ được thực thi mọi khung hình
void Cập nhật () {
// kiểm tra xem Người chơi có ở trong cảnh không và Kẻ thù có thể bắn
if (canShoot && player != null) {
// Kẻ thù không thể bắn trong lần kiểm tra tiếp theo
canShoot = sai;
//đặt Bullet prefab trong cảnh ở vị trí Kẻ thù (xoay mặc định)
Khởi tạo (dấu đầu dòng, biến đổi.vị trí, Quaternion.identity);
//bắt đầu chức năng firePause dưới dạng coroutine, có thể tạm dừng
StartCoroutine(firePause());
}
}

//chức năng quy trình
IEnumerator firePause() {
// tạm dừng chức năng cho fireDelay giây
năng suất trả về WaitForSeconds mới (fireDelay);
// Kẻ thù có thể bắn trong lần kiểm tra tiếp theo
canShoot = true;
}
}

Chọn Enemy prefab trong cửa sổ Nội dung và thêm tập lệnh EnemyShoot này vào đó. Thêm Bullet prefab vào trường Bullet (bạn có thể kéo và thả Bullet từ Nội dung vào trường này hoặc nhấp vào điểm chọn gần trường và chọn Bullet). Đặt Độ trễ lửa thành 2.

14. Bước
Người chơi hiện không có điểm sức khỏe. Chúng ta nên làm bộ điều khiển hp cho họ. Và chúng ta có thể thêm một giao diện người dùng đơn giản để hiển thị nó trên màn hình. Chúng tôi có thể thực hiện thanh sức khỏe với Giao diện Unity. Nhấp vào GameObject -> Giao diện người dùng -> và chọn Hình ảnh. Canvas có Hình ảnh sẽ được tạo. Đổi tên hình ảnh thành HealthBar. Chọn Canvas và đặt Chế độ tỷ lệ giao diện người dùng thành Tỷ lệ với Kích thước màn hình.
thêm hình ảnh giao diện người dùng
Nhấp đúp chuột vào Canvas. Chế độ xem cảnh sẽ thu nhỏ và bạn có thể thấy viền trắng. Nó đang hiển thị Kích thước giao diện người dùng trên màn hình. Bạn nên đặt các phần ui trong đó, nếu chúng sẽ được hiển thị. Chúng tôi đã có hộp màu trắng trong đó (HealthBar (Hình ảnh)). Chọn Công cụ hình chữ nhật (nếu không được chọn) và kéo dài HealthBar dưới dạng thanh hp.
điều chỉnh hình ảnh hp
Chọn HelathBar trong Hệ thống phân cấp. Thay đổi Hình ảnh nguồn thành UISprite (chúng tôi chỉ cần một sprite cho thanh hp của chúng tôi). Bạn có thể thay đổi màu sắc của nó. Đặt Image Typ thành Filled. Phương pháp điền vào ngang. Tô gốc sang trái (bạn có thể thử một cái gì đó khác với FillMethod và Fill gốc, nhưng Image Typ phải được tô). Bạn có thể thay đổi Fill Amount để xem thanh hp sẽ hoạt động như thế nào.
thay đổi hình ảnh hp sprite

15. Bước
Bây giờ chúng ta có thể tạo tập lệnh C# để điều khiển HP của người chơi. Tạo tập lệnh C# mới và đặt tên là PlayerHP.
sử dụng UnityEngine;
sử dụng System.Collections;
// chúng tôi cần không gian tên để truy cập trên Unity UI
sử dụng UnityEngine.UI;
sử dụng UnityEngine.SceneManagement;

lớp công khai PlayerHP : MonoBehaviour {

// tham chiếu đến đối tượng trò chơi HealthBar
GameObject HealthBar công khai;
// biến tham chiếu đến thành phần Hình ảnh trong HealthBar
Hình ảnh img;
//HP hiện tại
công khai int hp;
// giá trị HP tối đa, sẽ được sử dụng cho % đếm
nổi maxHp;

// sẽ được thực hiện một lần
khoảng trống Bắt đầu () {
// tham chiếu đến thành phần Hình ảnh trong PlayerHP
img = HealthBar.GetComponent < Hình ảnh > ();
// đặt HP tối đa thành HP hiện tại
maxHp = hp;
// thay đổi lượng lấp đầy giữa 0 và 1 (ở đây sẽ là 1 hoặc 100%)
img.fillAmount = hp/maxHp;
}

// sẽ được gọi từ tập lệnh trên các đối tượng trò chơi khác (như Bullet)
void MakeDamage (thiệt hại int) {
//giảm giá trị hp
hp = hp – thiệt hại;
//kiểm tra xem hp bằng 0 hay âm
nếu (hp <= 0) {
// tải cảnh hiện tại (tải lại)
SceneManager.LoadScene (SceneManager.GetActiveScene().name);
}
// thay đổi lượng lấp đầy giữa 0 và 1
img.fillAmount = hp/maxHp;
}
}

Nhấp đúp chuột vào Camera chính trong Hệ thống phân cấp để quay lại chế độ xem camera. Chọn máy nghe nhạc. Thêm tập lệnh PlayerHP vào Trình phát. Đặt HealthBar vào trường Health Bar (bạn có thể kéo và thả nó từ Hệ thống phân cấp (mở rộng Canvas nếu không nhìn thấy) hoặc nhấp vào điểm chọn gần trường Health Bar và chọn HealthBar). Đặt biến HP thành 10.
điều chỉnh tập lệnh hp
Ok, cảnh trò chơi nên được thực hiện ngay bây giờ. Chúng ta có thể tinh chỉnh nó một chút.
16. Bước
Chọn Máy ảnh chính. Nhấp vào Nền trong Trình kiểm tra và thay đổi nó thành màu đen.
chọn màu nền
17. Bước
Chúng ta nên thêm các ngôi sao chuyển động. Các hạt thống nhất là tốt cho việc này. Nhấp vào GameObject và chọn Hệ thống hạt. Chọn nó trong Hierarchy và đổi tên thành Stars. Đặt Z-Position thành 10. Và X-Rotation thành 90. Di chuyển nó lên trên Camera View. Bật Làm ấm trước. Điều chỉnh Thời gian bắt đầu (hạt sẽ bay qua chế độ xem camera). Điều chỉnh tốc độ bắt đầu theo ý muốn. Đặt Kích thước bắt đầu thành 0,2 (thành thứ bạn thích). Nhấp vào menu Shape và đặt Shape thành Box. Thay đổi giá trị X thành 15 (hộp hạt phải lớn hơn khi xem camera trên X-Axe). Nhấp vào trình đơn Renderer và đặt Order in Layer thành -100.
thêm sao
18. Bước
Entpack hiện đã tải xuống kho lưu trữ SpaceSound ( SpaceSound ). Nhập 3 tệp âm thanh vào Unity (Bạn có thể kéo và thả chúng vào cửa sổ Nội dung hoặc nhấp chuột phải vào cửa sổ Nội dung -> Nhập nội dung mới … chọn các tệp âm thanh trong trình tự của bạn và nhấp vào Nhập). Bây giờ chúng ta có thể tạo nhạc nền. Chọn Máy ảnh chính. Thêm Space Music vào nó. Unity sẽ tạo thành phần mới Audio Sorce (hoặc Thêm thành phần này theo cách thủ công và đặt Audio Clip thành SpaceMusic). Kích hoạt Vòng lặp.
thêm nhạc
18. Bước
Chúng ta nên tạo ra âm thanh bắn súng. Chúng tôi có thể phát đoạn âm thanh nếu Bullet xuất hiện. Mở tập lệnh EnemyBullet. AudioClip nên được khai báo. Và chúng ta có thể phát âm thanh này bằng AudioSource.PlayClipAtPoint.

sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai EnemyBullet : MonoBehaviour {

// biến tham chiếu cho đối tượng Người chơi game
Trình phát GameObject;
//biến tham chiếu cho Rigidbody2D
Thân cứng2D rb;
// biến cho công suất lực
lực lượng phao công cộng;
//biến cho giá trị thiệt hại
thiệt hại int công khai;
//biến cho clip âm thanh
công AudioClip BulletSound;

// sẽ được thực hiện một lần khi bắt đầu
khoảng trống Bắt đầu () {
// tham chiếu đến Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
//tìm kiếm đối tượng game bằng thẻ Player và tham khảo chúng
người chơi = GameObject.FindWithTag(“Người chơi”);
//kiểm tra xem Người chơi có ở trong cảnh không
nếu (người chơi != null) {
// tính véc tơ chỉ phương cho Player
Vector3 dir = player.transform.position – transform.position;
// tính góc giữa trục X và vectơ chỉ phương
góc float = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
// xoay viên đạn gameobject
biến đổi.Rotate(0, 0, angle);
// đẩy viên đạn vào rìu X ngôn ngữ của nó (nó sẽ chuyển tiếp cho hình ảnh này)
rb.AddRelativeForce(Vector2.right*force, ForceMode2D.Impulse);
//phát âm thanh (gameobject sẽ được tạo tại vị trí phát âm thanh rồi tự hủy)
AudioSource.PlayClipAtPoint (BulletSound, biến đổi.vị trí);
// nếu Người chơi không có trong cảnh
} khác
//xóa dấu đầu dòng khỏi cảnh
Tiêu diệt (gameObject);
}

// sẽ được thực thi nếu Collider2D đi vào Trigger
void OnTriggerEnter2D (Collider2D khác) {
// kiểm tra xem gameobject bị va chạm có thẻ Player không
if (other.gameObject.tag == “Người chơi”) {
// cố gắng thực thi chức năng “MakeDamage” với tham số “thiệt hại” trong tập lệnh được kết nối với đối tượng trò chơi bị va chạm
other.gameObject.SendMessage(“MakeDamage”, dam, SendMessageOptions.DontRequireReceiver);
//xóa dấu đầu dòng
Tiêu diệt (gameObject);
}
}

//sẽ được thực thi nếu dấu đầu dòng không được hiển thị nữa (ngoài màn hình)
void OnBecameInvisible () {
//xóa dấu đầu dòng
Tiêu diệt (gameObject);
}
}

Chọn Bullet prefab trong cửa sổ Assets. Tập lệnh EnemyBullet của nó hiện có trường mới cho âm thanh Bullet Sound. Đặt LaserSound trong đó.
thêm âm thanh cho dấu đầu dòng
Chúng ta có thể làm tương tự với laser của người chơi. Mở tập lệnh “LaserShot”.

sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai LaserShot : MonoBehaviour {

//biến tham chiếu cho Rigidbody2D
Thân cứng2D rb;
//biến cho thiệt hại
thiệt hại int công khai;
// biến cho công suất lực
lực lượng phao công cộng;
//biến cho clip âm thanh
công AudioClip BulletSound;

// sẽ được thực hiện một lần
khoảng trống Bắt đầu () {
// tham chiếu đến Rigidbody2D
rb = GetComponent < Rigidbody2D > ();
// khai báo Vector3 với giá trị lực trên trục Y
Vector3 directon = new Vector3(0, force, 0);
// thêm lực đẩy vào Hardbody2D để di chuyển trên Y-axe
rb.AddForce (directon, ForceMode2D.Impulse);
//phát âm thanh (gameobject sẽ được tạo tại vị trí phát âm thanh rồi tự hủy)
AudioSource.PlayClipAtPoint (BulletSound, biến đổi.vị trí);
}
// sẽ được thực thi, nếu gameobject không hiển thị nữa trên màn hình
void OnBecameInvisible () {
// xóa gameobject này khỏi hiện trường
Tiêu diệt (gameObject);
}
// sẽ được thực thi nếu một Collider2D khác đi vào Trigger
void OnTriggerEnter2D (Collider2D khác) {
// kiểm tra xem gameobject khác có tag Enemy không
if (other.gameObject.tag == “Kẻ thù”) {
// thử gọi MakeDamage trên gameobject khác, gửi damage làm tham số cho nó
other.gameObject.SendMessage(“MakeDamage”, dam, SendMessageOptions.DontRequireReceiver);
//xóa gameobject khỏi cảnh
Tiêu diệt (gameObject);
}
}
}

Chọn nhà lắp ghép Laser. Và đặt LaserSound trong trường Bullet Sound.
thêm âm thanh cho laser

19. Bước
Ít nhất chúng ta cần âm thanh vụ nổ. Mở tập lệnh “HpController”.
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai HpController : MonoBehaviour {

// biến cho điểm sức khỏe
công khai int hp;
//biến cho clip âm thanh
công khai AudioClip ExplosionsSound;

//funkton để tính toán thiệt hại (chúng tôi sẽ nhận được thiệt hại từ các chức năng khác)
void MakeDamage (thiệt hại int) {
//giảm biến hp
hp = hp – thiệt hại;
//kiểm tra xem hp âm hay không
nếu (hp <= 0) {
//phát âm thanh (gameobject sẽ được tạo tại vị trí phát âm thanh rồi tự hủy)
AudioSource.PlayClipAtPoint (Tiếng nổ, biến đổi.vị trí);
//xóa gameobject
Tiêu diệt (gameObject);
}
}
}

Chọn prefab Asteroid và đặt ExplosionsSound vào trường Explosions Sound mới. Chọn Enemy prefab và đặt ExplosionsSound vào trường Explosions Sound mới (giống với Asteroid).
thêm tiếng nổ
20. Bước
Một điều nữa. Chúng ta nên tạo ra vụ nổ nếu Kẻ thù (hoặc Tiểu hành tinh) bị phá hủy. Một lần nữa Hiệu ứng hạt rất tốt cho việc này. Click vào GameObject -> chọn Particle System. Đổi tên Hệ thống hạt đã tạo thành Explosion. Đặt tất cả Xoay thành không. Thời lượng đến 1. Vô hiệu hóa Vòng lặp. Bắt đầu Tuổi thọ lên 1. Bắt đầu Tốc độ lên 2. Kích thước bắt đầu lên 2. Số hạt tối đa lên 30. Nhấp vào Phát xạ và nhấp vào +. Đặt Độ bùng nổ tối thiểu và tối đa tại Thời điểm 0,0 thành 30. Nhấp vào Hình dạng và đặt Hình dạng thành Hình tròn với Bán kính 0,1.
thêm hệ thống hạt
Kích hoạt màu theo thời gian. Nhấn vào nó. Nhấp vào trường Màu. Bạn sẽ thấy dòng thời gian màu bây giờ. Trên là alfa controll (visiblity), dưới là color. Thay đổi điểm alfa cuối cùng thành 0. Thay đổi điểm màu đầu tiên và cuối cùng thành thứ gì đó bạn thích. Nhấp vào Trình kết xuất và đặt Thứ tự trong Lớp thành 10.

Nó chỉ là ví dụ cho vụ nổ. Hãy thử cài đặt của riêng bạn. Trong Unity 5.5 Hệ thống hạt đã được làm lại. Vì vậy, bây giờ bạn có thể làm hiệu ứng tốt hơn nhiều.
màu cho hạt
Chúng ta nên lập một kịch bản để tiêu diệt Explosion “đã chơi” khỏi hiện trường. Tạo tập lệnh C# mới và đặt tên là TimeDestroyer.

sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai TimeDestroyer: MonoBehaviour {

// biến thời gian trước gameobject sẽ bị hủy
thời gian nổi công khaiToDestroy;

// sẽ được thực hiện một lần khi bắt đầu
khoảng trống Bắt đầu () {
//xóa gameobject khỏi hiện trường
Tiêu diệt (gameObject, timeToDestroy);
}
}

Chọn Explosion trong cấu trúc phân cấp và thêm tập lệnh “TimeDestroyer” vào đó. Đặt Thời gian để Tiêu diệt thành 2. Tạo prefab Explosion (kéo và thả Explosion từ hệ thống phân cấp vào Nội dung). Xóa Explosion khỏi hệ thống phân cấp.
tạo vụ nổ nhà lắp ghép
21. Bước
Bây giờ chúng tôi có nhà lắp ghép Explosion. Chúng ta nên sinh ra chúng nếu một Kẻ thù hoặc Tiểu hành tinh bị phá hủy. Mở tập lệnh HpController.
sử dụng UnityEngine;
sử dụng System.Collections;

lớp công khai HpController : MonoBehaviour {

// biến cho điểm sức khỏe
công khai int hp;
//biến cho clip âm thanh
công khai AudioClip ExplosionsSound;
// biến cho nhà lắp ghép nổ
Vụ nổ GameObject công khai;

//funkton để tính toán thiệt hại (chúng tôi sẽ nhận được thiệt hại từ các chức năng khác)
void MakeDamage (thiệt hại int) {
//giảm biến hp
hp = hp – thiệt hại;
//kiểm tra xem hp âm hay không
nếu (hp <= 0) {
//phát âm thanh (gameobject sẽ được tạo tại vị trí phát âm thanh rồi tự hủy)
AudioSource.PlayClipAtPoint (Tiếng nổ, biến đổi.vị trí);
//đặt vụ nổ vào vị trí gameobject
Khởi tạo (Bùng nổ, biến đổi.vị trí, Quaternion.identity);
//xóa gameobject
Tiêu diệt (gameObject);
}
}
}

Chọn Nhà lắp ghép tiểu hành tinh. Tập lệnh HpController hiện có trường Explosion mới. Đặt Explosion prefab trong lĩnh vực này. Làm điều này một lần nữa với Enemy prefab. Chọn Enemy prefab và chọn Explosion cho trường Explosion.
thêm nhà lắp ghép vụ nổ

22. Bước
Chúng tôi có thể thêm lửa động cơ cho Trình phát của chúng tôi. Bấm vào GameObject và chọn Hệ thống hạt. Đổi tên nó thành EngineFire. Di chuyển nó trên tàu. Và biến nó thành con của Trình phát (kéo và thả EngineFire trên Trình phát trong Hệ thống phân cấp). Đặt Z_Position thành 0. X_Rotation thành 90. Duration thành 1. Bật Prewarm. Bắt đầu Lifetime đến 0,5. Bắt đầu Kích thước thành 0,5. Không gian mô phỏng đến thế giới. Max Particles thành 50. Nhấp vào Emission và đặt Rate thành 50. Thay đổi Shape thành Box với kích thước bằng không.
cháy động cơ bên trái
Bật màu trong suốt thời gian sử dụng. Nhấp vào trường màu và đặt màu theo ý muốn. Kích hoạt kích thước trong suốt thời gian tồn tại. Đặt đường cong kích thước từ 1 thành 0. Bấm vào Renderer. Đặt Thứ tự trong Lớp thành -1. One EngineFire sẽ sẵn sàng ngay bây giờ. Chọn nó, nhấp chuột phải và nhấp vào Duplicate. Di chuyển ngọn lửa trùng lặp sang phía tàu khác.
thêm lửa động cơ bên phải
23. Bước
Ok, tôi nghĩ nó là đủ cho trò chơi đơn giản. Bạn có thể xây dựng nó cho một nền tảng. Nhấp vào Tệp -> Cài đặt bản dựng. Chọn Nền tảng (thử windows) và nhấp vào Xây dựng.

tải xuống gói thống nhất tải xuống gói thống nhất của hướng dẫn này.
Việc nhập gói có thể bị lỗi. Các thẻ gameobjects có thể được đặt lại thành không xác định. Vì vậy, bạn nên thêm thẻ Enemy. Và sau đó thay đổi các thẻ từ Tiểu hành tinh và Kẻ thù thành Kẻ thù.
More about this source textSource text required for additional translation information
Send feedback
Side panels

 

Translate »