Just 4 fun!

Of course I can change the world, If you give me a source code

Post Ads (Documentation)

Author Info (Documentation)

style="display:block"
data-ad-client="ca-pub-2623284640924516"
data-ad-slot="8347113188"
data-ad-format="auto">

Monday, December 12, 2016

LẬP TRÌNH GAME - HÀNH TRÌNH KHÔNG CHỈ CÓ MÁU VÀ NƯỚC MẮT


LẬP TRÌNH GAME - HÀNH TRÌNH KHÔNG CHỈ CÓ MÁU VÀ NƯỚC MẮT

Vậy là bạn đang có ý định tạo một trò chơi, huh? Hãy chuẩn bị đi, đó là một hành trình dài và gian khổ.
Cuộc phiêu lưu của một lập trình game bắt đầu với một ý tưởng về một trò chơi mà họ muốn làm. “Một trò chơi với một số quái vật bên trong của một ngôi nhà tối tâm, đáng sợ và người chơi chỉ có thể tránh né chúng và tìm lối ra” – Nó chỉ đơn giản như thế. Với những người mới bắt đầu họ nghĩ nó rất đơn giản. Nhưng đó là một sai lầm, bởi trong game bạn còn phải tạo ra thêm vô số thứ khác như tạo và xắp đặt bàn, ghế, cánh cửa, tủ quần áo, tivi…cùng một số âm thanh cho mỗi con quái vật…rồi làm thế nào để cho chúng di chuyển, làm thế nào để đốt một ngọn đuốc…
Bạn có thể nói, “Vâng, nhưng tôi chỉ muốn làm cho một trò chơi như Mario. Nó cũng đâu quá khó”. Mặc dù được tạo ra hơn 25 năm trước đây, trò chơi platformer 2D này cũng khá khó khăn để thực hiện. Nếu bạn hỏi bất kỳ lập trình game nào đã thực hiện hoặc đang cố gắng để làm một game như thế, và bạn sẽ nghe một “câu chuyện” dài đến nửa đêm khi họ coding để cố gắng làm cho các đối tượng di chuyển và thực hiện va chạm một cách chính xác…. Mặc dù nó có vẻ đơn giản từ góc nhìn của một game thủ, nhưng từ quan điểm của một lập trình game, có vô số các quy trình cần phải được tính toán cẩn thận và thực hiện rất công phu khi làm cho một trò chơi.
Nếu chỉ có một điều bạn cần biết trước khi bắt đầu học cách để làm cho trò chơi, nó này: Tạo trò chơi phải mất rất nhiều thời gian và nỗ lực!
1. Có một ý tưởng hay.

Khi bạn nghĩ rằng bạn hoàn toàn sẵn sàng để tạo ra một trò chơi, hoặc để bắt đầu cuộc hành trình của bạn trong việc phát triển trò chơi, vấn đề đầu tiên bạn sẽ gặp phải được tìm ra một ý tưởng hay. Tất cả những “trạng thái” trong trò chơi của bạn đều phụ thuộc vào ý tưởng ban đầu này.
Bạn có thể rơi vào 2 loại:
a) Bạn là một người mới bắt đầu với rất ít hoặc không có kinh nghiệm lập trình
Trong trường hợp này, bắt đầu rất đơn giản. Nếu bạn duyệt qua các diễn đàn, các bạn sẽ thường thấy các nhà phát triển trò chơi kỳ cựu nói với những người mới bắt đầu là hãy làm một game Pong, thay vì thực hiện những ý tưởng mà bạn đang theo đuổi. Đề nghị này không phải là một sự xúc phạm, đó là một chiến lược đã được chứng minh. Khi bạn bắt đầu, hãy cố gắng học cách “sao chép” một trò chơi cũ như Pac Man, Missile Command, hoặc có lẽ là một trò chơi đơn giản như đánh cờ. Bạn cũng sẽ ngạc nhiên khi có rất nhiều thứ bạn sẽ được học từ những game như thế, và những gì bạn học sẽ được sẽ áp dụng cho các trò chơi chất phức tạp hơn sau này của bạn.
b) Bạn là một lập trình viên có kinh nghiệm hoặc đã ít nhất là đã từng đọc một cuốn sách viết về C
Khi bạn đã biết chương trình là gì thì sẽ có một chút dễ dàng hơn cho bạn để bắt đầu các trò chơi cao cấp hơn. Ngay cả khi bạn là một lập trình viên giàu kinh nghiệm, bạn sẽ không “bị đau” nếu bắt đầu từ những thứ đơn giản để biết được lập trình trò chơi khác với lập trình ứng dụng hoặc phát triển web như thế nào. Ngoài ra bạn có thể sẽ học thêm một ngôn ngữ mới hay biết được một số điều mới mẽ.
Bắt đầu từ đâu?
Sau khi bạn có một ý tưởng cho trò chơi của bạn, bước tiếp theo là quyết định cách bạn sẽ tạo ra trò chơi của bạn. Có hai phương án sau:
–  Tự mình lập trình tất cả mọi thứ
–  Tận dụng game engine hay một game buider
Game engine
Một sai lầm phổ biến với các lập trình game mới là họ thực sự nghĩ rằng “game engine” cơ bản là một phần mềm kỳ diệu mà bạn chỉ cần đưa vào chúng những graphics của bạn, thay đổi một vài dòng code giống như skining một trang web forum, thì… tôi đã có một trò chơi cho mình! Điều này hoàn toàn không đúng. Thuật ngữ “game engine” được sử dụng rất rộng rãi và bị hiểu sai, nó thực sự không có ý nghĩa cụ thể. Một lập trình game có thể đưa ra một “game engine” chỉ trong một vài tuần, trong khi một đội lập trình game chuyên nghiệp lại phải mất một năm để tạo ra nó.
Tuy nhiên, về cốt lõi chúng đều thực hiện những nhiệm vụ tương tự nhau. Một game engine là một tập hợp các code làm việc chặc chẽ với nhau để xử lý các yếu tố cơ bản mà hầu như tất cả các trò chơi đều cần đến. Những yếu tố đó có thể là: graphics rendering (2d hay 3d), Physics (phát hiện và đáp ứng va chạm), player input  (xử lý bàn phím và các sự kiện cảm ứng), và những thứ có khả năng khác như kết nối mạng, animation, các menu, high scores…. Game engine sẽ giúp cho bạn xử lý khá nhiều công việc, chắc chắn chúng có thể giúp bạn tiết kiệm rất nhiều thời gian và công sức khi tạo ra trò chơi của bạn, nhưng đừng suy nghĩ rằng bạn sẽ không mất nhiều thời gian và công sức khi sử dụng các game engine.
Game Builders
Game Builders là một dạng khác của game engine. Nói cách khác, thông thường với game builder bạn chỉ cần đưa vào một số graphics viết một vài dòng lệnh đơn giản, bấm vào một số checkboxes và thay đổi một số cài đặt để add thêm một số hành vi, sau đó chỉ cần nhấn vào nút “Build” thì trò chơi của bạn được thực hiện . Game Builders có thể là một cách tốt cho những đứa trẻ làm một trò chơi và thúc đẩy sự sáng tạo của chúng, nhưng quá trình tạo ra rất nhanh chóng và dễ dàng, làm cho chúng không linh hoạt và có nhiều hạn chế.
Lập trình từ đầu đến cuối
Nhiều nhà phát triển trò chơi muốn “bắt đầu từ đầu” và xây dựng một trò chơi từ mặt đất lên, tự mình làm (hầu như) mọi thứ. Đây là một cách tuyệt vời để tìm hiểu về phát triển game và lập trình nói chung. Để đi từ hướng này, điều đầu tiên bạn cần làm là chọn cho mình một ngôn ngữ lập trình.
2. Ngôn ngữ lập trình
Có rất nhiều ngôn ngữ mà nhiều người mới bắt đầu sẽ “bị lạc”trong đó và không bao giờ học được điều gì. Dưới đây là những ngôn ngữ thích hợp nhất bạn nên học khi phát triển cho Mac-iOS.
C
Đây là một trong những ngôn ngữ được ưa thích nhất bởi các lập trình viên. Trong nó có vẽ rất phức tạp, nhưng nó thực sự rất logic. Trong những năm 1990 và đầu những năm 2000, hầu hết các trò chơi được viết bằng C. Marathon, Duke Nukem 3D, Quake 3, và hàng tá những game khác. Mặc dù ngày này C ít được quan tâm nhưng vẫn là một lựa chọn hoàn toàn tốt.
Một trong những phần khó khăn nhất để hiểu về các ngôn ngữ lập trình C là quản lý bộ nhớ và con trỏ. Đối với người mới bắt đầu, điều này có thể rất khó hiểu nên khi nhảy thẳng vào C cho trò chơi đầu tiên của bạn, sẽ rất lâu để bạn tạo ra trò chơi của mình. Mặc dù vậy cũng có những điều tuyệt vời khi học nó, là một khi bạn biết nó, bạn có thể tìm hiểu hầu như bất kỳ ngôn ngữ mới nào một cách nhanh chóng.
C++
Ngày nay, thay vì viết các trò chơi trong C hầu hết các game “chuyên nghiệp” được viết trên nền tảng C++ (game engine). Sự khác biệt cơ bản giữa C và C++ là C++ là một ngôn ngữ “hướng đối tượng”. Lập trình hướng đối tượng (OOP) là một chủ đề rất rộng vượt ra ngoài phạm vi của bài viết này, nhưng đơn giản là không giống một ngôn ngữ thủ tục như C, C++ là nơi tất cả các hành động có thể thực hiện và xử lý được tổ chức thành một danh sách lớn gọi là các “hàm”, lập trình hướng đối tượng cung cấp một cách để cấu trúc tất cả những hành động và quá trình thành một hệ thống các”classes” với các dữ liệu và các hàm liên quan chặt chẽ với nhau.
Trong khi OOP là thứ tốt nhất để các lập trình viên tiếp cận, nhưng có một điều bạn phải cẩn thận với C++. Có rất nhiều thứ đang xảy ra ở đằng sau scene và đôi khi ứng dụng của bạn có thể hành xử khác nhau, và việc gỡ lỗi làm cho bạn như đang sống trong địa ngục. C++ cũng là một ngôn ngữ rất phức tạp. Một khi bạn biết được multiple inheritance, templates, operator overloading… bạn sẽ nhanh chóng hiểu ra lý do tại sao một số người không thích C++ và muốn sử dụng C. Nhưng nếu bạn không cần phải sử dụng tất cả các tính năng này thì bạn có thể chìm trong sự “ngọt ngào” của C ++.
Objective-C / Objective-C ++
Objective-C là những gì được sử dụng khi bạn phát triển ứng dụng Cocoa cho Mac OS X và iOS. Objective-C cũng có khả năng hướng đối tượng. Nó là một ngôn ngữ rất “sạch sẽ” và thường được sử dụng bởi người mới bắt đầu kể từ khi Cocoa và Objective-C cung cấp những cách đơn giản để làm những điều phức tạp, hoặc những thứ đó sẽ là phức tạp nếu làm bằng ngôn ngữ khác. Bạn có thể nói rằng ngôn ngữ này cũng giống như một phiên bản của OOP C, mà không có sự nguy hiểm của C++.
Objective-C++ là một superset của Objective-C có thể tương tác hoàn hảo với C++ code. Điều này có nghĩa là khi bạn sử dụng Objective-C++, bạn có thể sử dụng C, C++, và cú pháp Objective-C trong cùng một chương trình. Điều này có lợi thế rất lớn, cho phép bạn kết hợp một cross-platform C++ hiện có với một Objective-C để tương tác với Cocoa trong Mac OS X hay iOS. Đó là một tính năng rất mạnh mẽ.
Java
Java một ngôn ngữ phổ biến vì cho phép các nhà phát triển viết một chương trình dựa trên Java (gọi là applet) và nhúng nó vào một trang web. Kể từ đó Java đã trưởng thành và lan rộng để trở thành một ngôn ngữ phổ biến để viết các ứng dụng trên cở sở sever, đối với các trò chơi hiện nay, có cũng không phổ biến lắm. Đặc điểm lớn nhất của Java là khả năng nền tảng chéo, để bạn có thể viết một chương trình một lần, và nó sẽ làm việc trên nhiều nền tảng. Đây là một ngôn ngữ thú vị để tạo ra những trò chơi đa nền tảng mà không cần phải đối phó với porting. Nhưng nếu bạn muốn tạo ra một trò chơi 3D phức tạp, thì đừng sử dụng Java. Một lý do đơn giản là vì không có nhiều người thực hiện, có nghĩa là bạn sẽ có ít sự trợ giúp cũng như những code cho bạn tham khảo. (Java có thể được sử dụng cho các trò chơi 3D đơn giản. Runescape là một ví dụ về điều này.)
Python với pygame hoặc Pyglet
Một ngôn ngữ cũng khá tốt đối với newbie hiện nay là Python và các thư viện trò chơi Pygame và Pyglet. Python là một ngôn ngữ khá đơn giản và nó đủ mạnh mẽ để viết các trò chơi thực có chất lượng. Khi bạn bắt đầu với một ngôn ngữ như Python, nó sẽ là một bước đệm tốt cho bạn khi chuyển sang C / C ++ / v.v.. sau này. Hãy tìm kiếm trên Google về Python và Pygame hoặc hướng dẫn Pyglet, nó sẽ khá hữu ích trên con đường phát triển của bạn.
3. Engines Game / Frameworks / Creators
Đối với các thông tin mới nhất về những công cụ này, bạn có thể xem thêm tại đây.
Các công cụ
Để xây dựng và test trò chơi của bạn, bạn sẽ cần một số loại công cụ. Nếu bạn đang sử dụng một ngôn ngữ biên dịch như C, C++, C#, Java, vv.., bạn sẽ cần một trình biên dịch để biên dịch code của bạn và tạo ra các ứng dụng. Bạn cũng sẽ cần một phần mêm soạn thảo văn bản “của lập trình viên” với “màu cú pháp” và các tính năng khác khi viết code của bạn. Có hàng tá các trình biên dịch và soạn thảo văn bản, nhưng thường chỉ có hai loại được sử dụng để phát triển trên nền tảng của Apple.
Xcode
Được tạo bởi Apple, Xcode là IDE (Integrated Development Environment) để phát triển các ứng dụng cho Mac OS X và iOS. Xcode biên dịch nhiều ngôn ngữ, bao gồm cả các đại gia lớn như C, C ++, Objective-C, và Objective-C ++, và thậm chí là các ngôn ngữ khác như AppleScript và Ruby. Nếu bạn đang dự định viết game trên một máy Mac, bạn sẽ cần phải làm quen với Xcode.
Make
Make là một lệnh UNIX sử dụng để biên dịch các ứng dụng trên command line. Xcode là về cơ bản chỉ là một phiên bản đồ họa của Mark và một trình soạn thảo văn bản đơn giản. Một số nhà phát triển thích Xcode IDE, trong khi những người khác lại thích Mark. Nếu bạn là một người mới, tôi nghĩ bạn nên chọn Xcode.
Libraries
Với ý tưởng, ngôn ngữ, và các công cụ, bước cuối cùng là chọn một số thư viện thích hợp để giúp bạn tạo ra trò chơi của mình. Một trong những lĩnh vực mà các thư viện có thể giúp bạn là sound, graphics, và physics. Nhu cầu phải bổ sung thêm các yếu tố khác cho trò chơi rất cao và nếu bạn không có thời gian cũng như khả năng để tạo ra chúng, bạn có thể “tận dụng” các công việc của những người khác.
4. Bạn sẽ đi đến đâu?
Một khi bạn đã chọn và học một ngôn ngữ lập trình để sử dụng trong các công cụ mà bạn lựa chọn, bạn có thể bắt đầu xây dựng trò chơi của bạn. Tôi cung cấp khá nhiều thông tin ở đây, nhưng có rất nhiều thứ khác mà tôi đã không nói đến. Lập trình game là một chủ đề lớn, chứng minh là có đến hàng trăm đầu sách viết về chủ đề này!
Để tìm hiểu thêm về làm thế nào để bạn có thể tự viết một trò chơi cho mình, có bốn con đường bạn có thể theo. Đó là:
– Tự thực nghiệm
– Nhìn vào những trò chơi mã nguồn mở như một ví dụ
– Đọc hướng dẫn trên web và các diễn đàn
– Đọc các cuốn sách lập trình game
Đó là những con đường tốt nhất. Bạn cũng có thể kết hợp tất cả chúng. Sách là một cách tuyệt vời để bạn có những bước đi chắc chắn trong lập trình một trò chơi. Hãy đến những hiệu sách gần nhất và chọn cho mình những quyển mà bạn thích nhất. Một cách tuyệt khác là nhìn vào code của trò chơi hiện có. Khi bạn lần đầu tiên mở ra, bạn sẽ bị choáng. Nhưng trong vòng một giờ bạn sẽ có thễ hiểu được chúng.
Và một điều hiển nhiên, đó chính là khi bạn bị “mắc kẹt” trong một vấn đề nào đó, lúc này, tìm kiếm các hướng dẫn trên internet, các bài trên diễn đàn, và các ví dụ về chủ đề này sẽ là một nguồn lực lớn giúp bạn giải quyết vấn đề. Các diễn đàn đều rất năng động và thân thiện, vì vậy đừng ngại đặt câu hỏi khi bạn đang đứng trước một bức tường.
Sau khi có được trò chơi của mình, hãy thử làm một cái gì đó mới hơn, cao cấp hơn. Một khi bạn đã vượt qua những trở ngại trong trò chơi đầu tiên của mình, bạn đã có thể học nhanh hơn và nhanh hơn nữa. Chẳng bao lâu bạn sẽ chỉ bị giới hạn bởi chính trí tưởng tượng của bạn mà thôi.

Thursday, June 30, 2016

Tối ưu load scene bằng SSsystem.

Chào các bạn, hè năm ngoái mình có tham gia chương trình Bluebird Award và có quen mấy anh trong team hoppi (team làm game Bucha Adventure) và được chia sẻ về cách sử dụng SSsystem tối ưu việc load scene trong game khá là hay. Hôm nay mình sẽ chia sẻ lại với các bạn.
Đầu tiên, các bạn tải packet SSsystem về tại đây.
Giải nén ra bạn sẽ được thư mục SSSystems, hãy import thư mục này vào các project của bạn. Thông thường, nếu muốn load một scene, chúng ta hay dùng Application.loadlevel() với Unity 5.0 trở về trước và Scenemanager.loadscene với Unity 5.0 trở đi. Tuy nhiên, sau khi import thư mục SSSystems, chúng ta sẽ tạo một script chuyên để load scene như sau:

using UnityEngine;
using System.Collections;
using SS;
using System;

public class load : Controller {

    public override string SceneName()
    {
        return "Scene1";
    }

   public void loadScene(String sceneName)
    {
        SceneManager.Scene(sceneName, false); 
    }

}
//(tham số false tức là các đối tượng của scene này sẽ không bị destroy khi load scene mới).

Chú ý là chúng ta phải khai báo using SS; using System; kế thừa Controller và ghi đè SceneName() . Giờ chỉ cần gọi loadScene() và truyền vào tên scene cần load. Ở những scene khác, ta cần tạo một script tương tự như trên, gắn vào một gameobject và để tất cả những đối tượng khác trong scene là đối tượng con của gameobject đó.

Tạo một script kế thừa Controller và ghi đè return vào SceneName().


Gắn script vừa tạo vào một gameobject chứa tất cả các đối tượng có trong Scene.
Bây giờ, khi chúng ta gọi loadScene() , scene mới sẽ được load kèm theo đó là gameoject có chứa tất cả các đối tượng. Trong khi đó những đối tượng của scene cũ cũng không bị destroy đi mà chỉ bị disable và sẽ được active khi chúng ta gọi lại scene đó. 
Điều này sẽ giảm đáng kể thời gian load scene vì không phải khởi tạo thêm những đối tượng mới trong game nữa. Tất nhiên, nó mới chỉ giảm được phần nào, quan trọng vẫn là ở việc bạn tối ưu các tài nguyên game và cơ chế như thế nào. Chúc thành công và sớm cho ra đời những sản phẩm game tuyệt vời nhất. 
Hãy share nếu thấy bài viết của mình hữu ích!

Friday, June 17, 2016

Mấy ông Dev Unity ơi, đừng dùng GameObject.Find nữa đê!


(Quan điểm cá nhân)
Tại sao?
 Unity cung cấp một số phương pháp để tiếp cận và tham chiếu đến một đối tượng (GameObject) trong một Scene, một trong số các phương pháp đó là duyệt qua tất cả các GameObject và các đối tượng con có trong scene và tìm ra đối tượng cần tham chiếu nhờ tên của nó. Lúc đầu mình thường xuyên sử dụng cách này và thấy nó thật là fucking awesome. Nhưng giờ, mình biết được tốt nhất là không nên sử dụng nó. Tại sao? hãy nhìn vào ví dụ sau. Đây là mộn script đếm và hiển thị ra có bao nhiêu đối tượng trong Canvas của scene:

using UnityEngine;
using UnityEngine.UI;

public class ShowNumberOfCanvasChildren : MonoBehaviour

{
    private GameObject _canvas;
    private Text _childText;

    private void Start()

    {
        // grab an object in the scene called Canvas
        _canvas = GameObject.Find("Canvas");

        // and grab some text in a child of the object

        // that this script is attached to
        _childText = this.transform.FindChild("ChildText").GetComponent<Text>();
    }

    private void Update()

    {
        // on every frame, modify that text
        _childText.text = "Canvas child count: " + _canvas.transform.childCount;
    }
}

Mình có thể liệt kê ra những vấn đề như sau:
   1.Mình thực sự không biết cái tên đó có tồn tại hay không? Dĩ nhiên là cả 2 đều do mình đặt, nhưng nếu mình gõ nhầm "Canvas" thành "Camvas" hoặc quên mất và đặt tên "ChildText" thành "ChildTextObject". Tất nhiên là chương trình vẫn chạy, tất nhiên là biên dịch không thể  phát hiện ra lỗi đặt tên sai của mình được, và mình cũng thế, cho đến khi game chạy không như những gì mình muốn và mình phải xem lại code, đối chiếu với tên đối tượng trong scene. Đấy là trong trường hợp một Project nhỏ, thử tưởng tượng một Project với hàng trăm đối tượng trong scene và hàng trăm dòng code. Thôi mình không muốn tưởng tượng nữa đâu :v
   2.Với cách code như trên, mình không thể thay đổi thứ tự của các GameObject trong scene. Mình không thể cho một đối tượng con ra ngoài hoặc đặt đối tượng cha cho một GameObject. Đơn giản là khi mình làm thế, đoạn code kia sẽ bỏ qua, không tìm đến GameObject đó nữa và tất nhiên, game sẽ chạy không như ý mình.
   3.Mình không thể đổi tên đối tượng một cách tự do. Như vấn đề 1, nếu mình muốn đổi tên một GameObject, mình phải tìm nó trong scene, đổi tên, mở Script, tìm đoạn code, sửa lại đoạn text trong đó cho giống với tên mới. Và tất nhiên, với một Project to thì mình sẽ bỏ cuộc trước khi bắt đầu (y).
Đó là tất cả những vấn đề mà đoạn code trên gặp phải. Nếu bạn áp dụng phương pháp tương tự như này vào trong code của mình thì. Đơn giản là mỗi script chỉ có thể áp dụng trong một trường hợp đặc biệt và không thể tái sử dụng. Điều này làm lãng phí tài nguyên không đáng có và tất nhiên là cũng gây khó khăn trong việc quản lí hơn rất nhiều.
Vậy, cách tốt hơn là gì?
Thay vì khai báo biến private trong script, cách tốt hơn là khai báo chúng public. Bằng cách đó, ta có thể biết chính xác script đó dùng để làm gì và cần những gì, như sau:

using UnityEngine;
using UnityEngine.UI;

public class ShowNumberOfCanvasChildren : MonoBehaviour

{
    public GameObject Canvas;
    public Text NumChildrenText;

    private void Update()

    {
        NumChildrenText.text = "Canvas child count: " + Canvas.transform.childCount;
    }
}

Ngoài ra, nếu bạn không thích dùng public thì có thể dùng SerializeField. Tất nhiên, mình thuộc phần thích dùng public nên mình sẽ chẳng thèm quan tâm đến cái SerializeField kia :v
Tóm lại là dù dùng cách nào thì sau đó, bạn cũng trông thấy nó như thế này

Tốt hơn rồi đấy, bây giờ bạn có thể thấy code của mình phụ thuộc vào đối tượng Canvas và Text. Giờ chỉ việc kéo thả đối tượng vào đúng vị trí của nó.

Đỡ hơn chưa, giờ mình có thể đổi tên và thay đổi cha con thoải mái mà chẳng cần phải dò code để sửa từng tí một, hãy nhớ và áp dụng vào những dự án của các bạn nhé. Chúc thành công!

Lặt vặt về Sprite

          Chào các bạn, như đã nói trong các bài viết trước, trong bài này mình sẽ cung cấp cho các bạn một số vấn đề mấu chốt của SpriteRenderer. Có tham khảo trên trang Unityviet.com
1/ Lấy kích thước của spriterenderer:
Khi kéo thả một hình ảnh vào scene, trong Inspector sẽ có 2 thành phần mặc định đó là Transform và Sprite Renderer.Ở đây, để lấy được kích thước của hình chúng ta chỉ cần truy cập đến thành phần Sprite Renderer như sau:

      GetComponent<SpriteRenderer>().sprite.texture

Bằng cách này chúng ta đã tham chiếu đến mục sprite trong thành phần Sprite Renderer của đối tượng hình ảnh trong scene, và để lấy kích thước (chiều cao, chiều rộng) hình ảnh, ta chỉ cần gọi:

      GetComponent<SpriteRenderer>().sprite.texture.width

      GetComponent<SpriteRenderer>().sprite.texture.height

Ở đây, các bạn cần lưu ý là nó sẽ trả về kích thước thực của hình ảnh mà bạn đưa vào. Còn trong scene (ta gọi la không gian game) sử dụng kích thước khác. Ta có thể tham chiếu đến bằng cách gọi:

GetComponent<SpriteRenderer>().bounds

Ví dụ ở đây, mình kéo một hình ảnh vào scene, thêm script C# cho nó, sử dụng "Debug.Log(GetComponent<SpriteRenderer>().bounds); " trong hàm Update và đây là kết quả trong cửa sổ Console:


2/ Thay đổi size của sprite:
Ở đây, mình khuyên các bạn nếu muốn resize lại một hình ảnh trong scene thì nên thay đổi local scale của hình ảnh đó ở tranform như sau:
transform.localScale = new Vector3(0,0,0);
rất đơn giản đúng không?


3./Đổi Sprite:
Như ở trên, chúng ta khai báo một biến public Sprite t;
sau khi gán script vào một object, ta có thể kéo thả một sprite bất kì vào chỗ trống, sau đó nếu muốn thay đổi Sprite, ta chỉ việc gọi:
 GetComponent<SpriteRenderer>().sprite = t;

Ngoài ra, bằng việc gọi đến thành phần Sprite Renderer còn cho phép bạn thay đổi những thông số khác như:
Material (chất liệu): GetComponent<SpriteRenderer>().material
Flip (lật ảnh):
GetComponent<SpriteRenderer>().flipX = true;
GetComponent<SpriteRenderer>().flipY = true;
(việc lật ảnh trong game 2D giúp Dev không cần phải quay game object một góc 180 theo trục Y hoặc X nữa, tuy nhiên nó chỉ có từ phiên bản Unity 5.4 trở lên)
Order Layer:  GetComponent<SpriteRenderer>().sortingOrder = 1;
Như mình đã nói trong bài viết trước, việc đặt layer cho hình sẽ quyết định hình nào ở trên và hình nào ở dưới trong game khi render, rõ ràng sử dụng layer thuận tiện hơn xét vị trí theo trục Z rất nhiều, đặc biệt là trong game 2D.
 Chúc các bạn thành công!

Thursday, June 16, 2016

2D EXPERIMENTAL PREVIEW


Hôm nay, chúng ta sẽ cùng tìm hiểu về "2D experimental", mình cũng chẳng biết dịch như nào cho đúng lên để nguyên như của Unity :) Còn chúng ta có thể tạm hiểu là hình ảnh 2D hay Sprite.
Vậy Sprite trong unity có những đặc điểm gì?
Đầu tiên là 9-Slice Sprites:
Unity định nghĩa đó là công nghê cho phép bạn sử dụng một hình ảnh theo nhiều kích cỡ mà không phải chuhaarn bị nhiều tài nguyên. Đừng nhầm lẫn với việc scale hình ảnh, ở đây chúng ta đang nói đến việc bạn có thể import một hình ảnh và cắt nhỏ nó thành nhiều phần trong Editer của Unity để sử dụng từng phần đó, bạn có thể dễ dàng nhìn thấy lựa chọn này bằng cách đặt hình ảnh về Multiple ở Prite mode, sau đó chọn Sprites Editor để cắt.

Thứ 2 là Sorting Group:
Đây là chức năng cho phép bạn nhóm hình ảnh của mình theo từng layer trong Sence. Từ đó quyết định thứ tự hiển thị khi được render. Cũng tương tự như các phần mềm chuyên về đồ họa, đây là một chức năng rất hữu ích giúp developer có thể quyết định ảnh nào ở lớp trên và ảnh nào hiển thị ở lớp dưới mà không phải quan tâm đến tọa độ trục Z trong game 2D.
Cuối cùng đó là Sprite Mask:
Nó cho phép hiển thị hoặc ẩn một phần của hình ảnh theo một hình dạng tro trước và (tất nhiên) do developer quyết định. Có 2 loại đó là Global Mask dùng trong scene và Scoped Mask dùng cho GameObject. Cái này thường sử dụng rất nhiều trong UI, các bạn có thể tham khảo tại đây hoặc đợi bài  viết tiếp theo của mình sẽ nói chi tiết hơn :
UI mask tutorial
Các bài viết tiếp theo mình sẽ đề cập chi tiết từng chức năng, cảm ơn đã theo dõi!

Wednesday, June 8, 2016

Căn chỉnh sprite nền vừa khít màn hình

Script canh chỉnh sprite nền vừa khít màn hình

·
Mặc dù từ bản Unity 5.0 trở đi, chúng ta đã có UI hỗ trợ việc căn chỉnh hình ảnh, button, text phù hợp với mọi kích cỡ màn hình, tuy nhiên có trường hợp như bạn có 1 sprite nền (background) và muốn nó vừa khít với tất cả tỉ lệ màn hình (4:3, 16:9, …), lúc này bạn cần viết một script nhỏ để làm việc này.
Để demo, bạn tạo 1 scene, thêm vào 1 sprite là tấm hình background




lúc này bạn chưa cần quan tâm tới vị trí hay kích thước tấm hình

Sau đó bạn viết  script như sau (tôi có comment đầy đủ chi tiết từng câu lệnh):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using UnityEngine;
using System.Collections;
//phải using UnityEditor để có thể dùng TextureImporter
using UnityEditor;

public class resizeSpriteFullScreen : MonoBehaviour {
                //tham chiếu tới camera
                public Camera cam;
                // Use this for initialization
                void Start () {
                                //lấy component Sprite Renderer
                                SpriteRenderer sr = GetComponent<SpriteRenderer>();
                                //lấy hình cần đặt fullscreen
                                TextureImporter ti = AssetImporter.GetAtPath("Assets/image1.png") as TextureImporter;
                                //lấy giá trị Pixels To Units của tấm hình sprite đó
                                float PixelsToUnits = ti.spritePixelsToUnits;
                                //Khai báo vector3 mới
                                Vector3 sc = new Vector3(1f, 1f, 1f);
                                //tính toán chiều cao và chiều rộng của sprite cho khít với màn hình
                                sc.y = cam.orthographicSize*2f*PixelsToUnits/sr.sprite.rect.height;
                                sc.x = (cam.orthographicSize*(float)Screen.width/(float)Screen.height)*2f*PixelsToUnits/sr.sprite.rect.width;
                                //gán giá trị tính được vào local Scale của sprite
                                transform.localScale = sc;
                                //cho sprite vào vị trí chính giữa màn hình
                                transform.position = cam.transform.position;
                }
}
Bạn đưa script đó bỏ vào object background và kéo object Main camera vào biến tương ứng trong script
Bạn nhớ để ý scale lúc này là 1:1:1


Bây giờ bạn Play game, sẽ thấy ngay kết quả, sprite đã vừa khít màn hình, cho dù bạn thay đổi màn hình tỉ lệ hay kích thước nào chăng nữa. Ở những bài viết sau mình sẽ nói chi tiết hơn Sprite Renderer để các bạn hiểu rõ và có thể tự mình tìm ra cách scale Sprite theo tỉ lệ màn hình phù hợp nhất.


Like, share nếu bạn thấy bài viết của mình có ích! :)