Thứ Tư, 12 tháng 2, 2014

COOKBOOK - TÔ SÁNG VẬT THỂ KHI NHẤP CHUỘT VỚI COLLIDER


  - Tô sáng vật thể khi nhấp chuột với collider -

Tô sáng (highlight) là một hiệu ứng rất hữu dụng để người chơi có thể biết rằng có thể tương tác với vật thể. Điều này rất hữu dụng trong các thể loại game như xếp hình và phiêu lưu theo kiểu nhấp chuột, và nó còn có thể được sử dụng vào việc tạo giao diện người dùng bằng 3D.



Chuẩn bị
HighLight.unitypackage

Cách để làm

B1. Nhấp phải vào thẻ Project và chọn Import Package | Custom Package và mở file HightLight vừa tải ở trên.


B2. Double click vào highlightScene trong thẻ Project để mở scene này lên.


B3. Tại thẻ Hierarchy, nhấp chọn highlightCube, qua thẻ Inspector, thay đổi Shader cho vật thể này từ Diffuse thành VertexLit.


B4. Vẫn ở thẻ Inspector, thay đổi Base Texture của vật thể bằng cách nhấp chọn nút Select và chọn baseBox như hình sau:


B5. Tại thẻ Project, nhấp chọn nút Create | C# Script và đặt tên là HighlightObject. Double click vào file C# này và chèn đoạn code sau vào:

using UnityEngine;
using System.Collections;

public class HighlightObject : MonoBehaviour
{
    public Color initialColor;
    public Color highlightColor;
    public Color mousedownColor;
    private bool mouseon = false;
    void OnMouseEnter()
    {
        mouseon = true;
        renderer.material.SetColor("_Emission", highlightColor);
    }
    void OnMouseExit()
    {
        mouseon = false;
        renderer.material.SetColor("_Emission", initialColor);
    }
    void OnMouseDown()
    {
        renderer.material.SetColor("_Emission", mousedownColor);
    }
    void OnMouseUp()
    {
        if (mouseon)
            renderer.material.SetColor("_Emission", highlightColor);
        else
            renderer.material.SetColor("_Emission", initialColor);
    }
}


B6. Kéo thả file C# vừa tạo vào highlightCube ở thẻ Hierarchy.


B7. Nhấp chọn highlightCube ở thẻ Hierarchy và qua thẻ Inspector điều chỉnh Initial Color thành màu xanh đậm (R: 0, G: 100, B: 0) và Mousedown Color thành xanh nhạt (R: 0, G: 255, B: 0).


B8. Gán box collider cho highlightCube bằng cách vào Component | Physics | Box Collider.


B9. Nhấp nút Play để kiểm tra thành quả. Khối hộp sẽ đổi màu mỗi khi bạn rê chuột hoặc nhấp chuột vào nó.

Nguyên lý làm việc
Box collider sẽ kiểm tra con trỏ chuột có đặt trên vật thể hay không, nó làm việc như một trigger để thay đổi màu Emissiver Color trong Shader VertexLit. Biến mouseon dùng để kiểm tra con trỏ có đang nhấp hay nằm ngoài box collider để thay đổi màu sắc phụ thuộc vào con trỏ.

Còn nữa...
Bạn có thể sử dụng các shader khác tùy ý, nhưng nhớ phải thay đổi giá trị biến màu cho phù hợp với thông số của vật liệu nhé.

Tô sáng bằng shader self-illuminated
Hãy đổi Shader của highlightCube thành Self-illumianted và thay thế _Emission thành _Color trong file C#.

Sử dụng shader Transparent.
Shader Transparent sẽ tạo hiệu ứng trong suốt khá thú vị. Bạn hãy nhớ điều chỉnh độ trong suốt của vật thể bằng giá trị Alpha khi chọn màu cho vật thể nhé. Nhớ thay thế _Emission thành _Color.

Thứ Sáu, 7 tháng 2, 2014

DEVGAME 1.2 - CẤU TRÚC CỦA MỘT TỆP MÃ - CẤU TRÚC HÀM


Hàm là một khối các câu lệnh có thể có các đối số và thường được đặt tên để thực hiện, để thực hiện thao tác hoặc trả về một giá trị nào đó. Hãy cùng tìm hiểu rõ về cấu trúc cũng như công dụng của hàm dựa theo file javascript đã tạo ở bài viết trước.

Cấu trúc của một hàm

Khi vừa tạo file javascript mới, Unity sẽ mặc định thiết lập 2 hàm code rỗng là Start Update trong tệp mã.
  • Kiểu khai báo: function - màu xanh dương được ghi thường, dùng để khai báo chức năng của dòng lệnh. Ở đây là để khai báo sử dụng hàm.
  • Tên hàm: Start, Update -  trong javascript, tên hàm luôn được viết hoa chữ đầu.
  • Đối số: ( ) - các biến giá trị để chương trình gán vào câu lệnh khi thực hiện. Các đối số ngăn cách nhau bởi dấu phẩy, trong một hàm có thể có hoặc không có đối số.
  • Câu lệnh: { } - nơi để chứa các dòng lệnh thực thi hoặc chú thích, cả hai phải nằm trong dấu ngoặc { }.

 Hàm Update là một trong những hàm quan trọng nhất được dùng nhiều trong bất kỳ game engine (phần mềm làm game). Hàm này sẽ kiểm tra mỗi frame (khung hình) suốt quá trình game đang chạy. Nó có thể làm chuyển động đối tượng như vòng lặp xoay tròn, kiểm tra xem có điều kiện va chạm nào xảy ra không và nhiều thứ khác nữa. Hàm Start chỉ được thực thi một lần khi scene bắt đầu, thuận tiện cho việc khởi tạo và thiết lập các giá trị mà trong game không xuất hiện cho đến khi game đã được load xong. Cả hai hàm này đều không bắt buộc phải có. Bạn có thể thoải mái xóa các hàm này đi nếu nó không cần thiết.

1. Xóa hàm Start đi bằng cách tô đen và ấn nút Delete.


2. Đặt con trỏ phía sau dấu mở ngoặc nhọn { và ấn Enter vài cái để chừa chỗ gõ code mới.


3. Ở phía trong dấu ngoặc nhọn { }, ấn tab 1 cái để thục dòng vào phía trong rồi gõ dòng code sau vào:


Việc thục dòng đoạn code thật ra không bắt buộc nhưng nó giúp bạn dễ biết được cấp độ của các đoạn code thuộc lớp nào, tránh nhầm lẫn trong việc đọc code.

Trong đó: 
  • transform - dùng để điều khiển chuyển động của đối tượng.
  • Rotate - là hàm dùng để xoay tròn (Tên hàm ghi hoa chữ đầu) là một chức năng đặc trưng của class (lớp) transform.
  • (0, 5, 0) - là đối số của góc quay vật thể dựa theo trục tọa độ X, Y, Z. Hàm Rotate sử dụng 3 đối số đại diện cho 3 trục tọa độ.
  • ; - kết thúc một câu lệnh.

Dấu chấm . trong câu lệnh trên dùng để truy cập các hàm (function) và các tham số (parameter) hiện có khi  có nhiều đối tượng hoặc chức năng.

Ảnh: Kí hiệu dấu chấm

File code của bạn sẽ được gắn trực tiếp vào vật thể nên bạn không cần phải khai báo vật thể đó làm gì. File code của bạn giờ đây sẽ làm cho vật thể xoay 5 độ theo trục Y mỗi khung hình.

4. Ấn Ctrl + S để lưu đoạn code của bạn lại.

File code của bạn sẽ được cập nhật trong thẻ Inspector khi bạn chuyển qua cửa sổ Unity Editor.

 

5. Thu nhỏ cửa sổ biên tập code MonoDevelop xuống thanh hệ thống. Trở lại cửa sổ Unity Editor.


6. Tại thẻ Hierarchy, nhấp chọn nút Create | Cube, kéo thả file javascript ở thẻ Project (đã tạo ở các bước trên) vào Cube ở thẻ Hierarchy.

 

7. Nhấp nút Play để kiểm tra thành quả. Bạn sẽ thấy khối hộp xoay vòng theo chiều ngang (vì trục Y là trục đứng từ trên xuống). Và quay nhanh, chậm tùy thuộc vào góc độ ta đặt khi viết code và tốc độ khung hình của máy tính mà ta thiết lập cho game chạy.

Thứ Năm, 6 tháng 2, 2014

DEVGAME 1.1 - CẤU TRÚC CỦA MỘT TỆP MÃ - HÀM



Cấu trúc của một đoạn mã (script) bao gồm 3 thành phần chính: Biến (variable), Hàm (function) và Chú Thích (comment). Biến chứa bất kì giá trị kiểu số hoặc kiểu kí tự. Hàm dùng để thực thi một việc gì đó thông thường thực thi cùng biến và các biểu thức toán học. Chú thích sẽ bị chương trình dịch bỏ qua khi chạy chương trình, nó chỉ cho phép người dùng ghi chú lại những gì người dùng cần nhớ hoặc để vô hiệu hóa dòng mã lệnh nào đó. Hãy bắt đầu khám phá dòng mã lệnh mặc định của Unity và cùng tìm hiểu về Hàm.


Function - Hàm

Các function trong Unity được phân thành 3 nhóm: liên quan đến game - game relate (như system, input, network), đối tượng đặc trưng - object specific, người dùng định nghĩa - user defined.

Nếu bạn đang khởi động Unity, bạn có thể tạo một file Javascript mới theo các bước sau:

1. Tại thẻ Project, nhấp chọn nút Create | New Folder và đặt tên là My Scripts.

 

2. Nhấp phải vào thư mục My Scripts và chọn Create | Javascript


Một tệp mã mới được thêm vào thư mục với tên là NewBehaviourScript. Bạn có thể nhìn thấy nội dung của tệp mã này ở thẻ Inspector nhưng bạn không thể chỉnh sửa ở thẻ này được.

 

3. Nhấp chuột trái vào file java vừa tạo rồi ấn F2 và sửa tên thành SimpleRotate.


4. Để mở trình soạn thảo mã lệnh MonoDevelop bạn nhấp đúp chuột vào file javascript hoặc nhấp chuột chọn file java và bấm nút Open ở thẻ Inspector.


Như bạn thấy, tệp mã mới có vài dòng code sẵn trong đó như sau:



Hãy bỏ nó qua một bên, mình sẽ quay lại nói về phần này ở các bài viết về biến. Hẹn gặp lại ở bài viết sau!

Thứ Hai, 3 tháng 2, 2014

COOKBOOK - THAY ĐỔI VẬT LIỆU CHO VẬT THỂ BẰNG GUI


  - Thay đổi vật liệu cho vật thể  bằng GUI -

Tùy biến ảnh giao đại diện thường dùng một hoặc nhiều ảnh/vật liệu mẫu đã có và gắn nó vào ảnh đại diện. Bài viết này, sẽ sử dụng GUI để kết hợp 2 vật liệu (texture) để tạo nên ảnh đại diện do người dùng lựa chọn.



 Chuẩn bị
SelectTexture.unitypackage

Cách để làm

B1. Nhấp phải vào thẻ Project và chọn Import Package | Custom Package và mở file SelectTexture vừa tải ở trên.


B2. Tại thẻ Project, double click vào selTexScene.


B3. Vẫn tại thẻ Project, nhấp nút Create | Material và đặt tên là selectableMaterial. Ở thẻ Inspector, đổi Shader thành Decal.


B4. Kéo thả material vừa tạo ở thẻ Project vào Avatar ở thẻ Hierarchy.


B5. Tại thẻ Project, nhấp chọn nút Create | C# Script và đặt tên là SelectTexture. Chèn đoạn code sau vào:

using UnityEngine;
using System.Collections;

public class SelectTexture : MonoBehaviour
{
    public Texture2D[] faces;
    public Texture2D[] props;
   
    void OnGUI()    {
        for (int i = 0; i < faces.Length; i++)
            if (GUI.Button(new Rect(0, i * 64, 128, 64), faces[i])) ChangeMaterial("faces", i);
       
        for (int j = 0; j < props.Length; j++)
            if (GUI.Button(new Rect(128, j * 64, 128, 64), props[j])) ChangeMaterial("props", j);
    }
    void ChangeMaterial(string category, int index)
    {
        if (category == "faces")
            renderer.material.mainTexture = faces[index];
       
        if (category == "props")
            renderer.material.SetTexture("_DecalTex", props[index]);
    }
}


B6. Lưu đoạn code lại và kéo thả vào Avatar ở thẻ Hierarchy.


B7. Nhấp chọn Avatar, qua thẻ Inspector, đổi giá trị Size của Faces và Props thành 2 và kéo thả các file ảnh face1, face2, prop1, prop2 ở thẻ Project vào thẻ Inspetor ở các vị trí như sau:

 

B8. Ấn nút Play để kiểm tra thành quả.

Chủ Nhật, 2 tháng 2, 2014

Project RPG BÀI 10B. DỌN DẸP FILE ATTRIBUTE





Chuỗi bài viết dọn dẹp nhà cửa vì lo ăn tết nên post muộn :D


Double click vào file C# Attribute và xóa tất cả đi, chèn lại đoạn code sau vào:

 /// <summary>
/// This is the class for all of the chacracter attributes in-game
/// </summary>
public class Attribute : BaseStat {
    new public const int STARTING_EXP_COST = 50;    //this is the starting cost for all of the attributes
                  
    private string _name;                            //this is the name of the attribute

    /// <summary>
    /// Initializes a new instance of the <see cref="Attribute"/> class.
    /// </summary>
    public Attribute(){
        _name = "";                                  
        ExpToLevel = STARTING_EXP_COST;      
        LevelModifier = 1.05f;
    }

    /// <summary>
    /// Gets or sets the _name.
    /// </summary>
    /// <value>The name.</value>
    public string Name{
        get{return _name;}
        set{_name = value;}
    }
}

/// <summary>
/// A list of all attributes that we will have in-game for chacracters
/// </summary>
public enum AttributeName{
    Might,
    Constituion,
    Nimbleness,
    Speed,
    Concentration,
    Willpower,
    Charisma
}

Thứ Bảy, 1 tháng 2, 2014

COOKBOOK - THAY ĐỔI MÀU SẮC CHO VẬT THỂ

  - Thay đổi màu sắc cho vật thể -

Trong các phần thiết lập giao diện hoặc các phần tùy chỉnh dành cho người dùng. Ví dụ điển hình là thay đổi màu sắc diện mạo của nhân vật. Trong bài viết này, sẽ hướng dẫn cách dùng các thanh trượt (slider) để điều chỉnh màu sắc vật liệu (material) được gán vào nhân vật dựa trên các giá trị của bảng màu RGB (Red Green Blue).

Chuẩn bị...

ColorSelector.unitypackage


Cách để làm

B1. Nhấp phải vào thẻ Project và chọn Import | Custom Package và mở file ColorSelector vừa tải ở trên.
 
B2. Double click vào scene colorSelection ở thẻ Project | ColorSelect.


B3. Nhấp phải vào thẻ Project và chọn Create | C# Script và đặt tên là ColorSelector rồi chèn đoạn code sau vào:


using UnityEngine;
using System.Collections;

public class ColorSelector : MonoBehaviour
{
    public float redValue = 1.0f;
    public float greenValue = 1.0f;
    public float blueValue = 1.0f;
    bool selectorOn = false;
    private float redReset = 1.0f;
    private float greenReset = 1.0f;
    private float blueReset = 1.0f;

    void OnMouseUp()
    {
        selectorOn = true;
    }
   
    void OnGUI()
    {
        if (selectorOn)
        {
            GUI.Label(new Rect(10, 30, 90, 20), "Red: " + Mathf.RoundToInt(redValue * 255));
            redValue = GUI.HorizontalSlider(new Rect(80, 30, 256, 20), redValue, 0.0f, 1.0f);
            GUI.Label(new Rect(10, 50, 90, 20), "Green: " + Mathf.RoundToInt(greenValue * 255));
            greenValue = GUI.HorizontalSlider(new Rect(80, 50, 256, 20), greenValue, 0.0f, 1.0f);
            GUI.Label(new Rect(10, 70, 90, 20), "Blue: " + Mathf.RoundToInt(blueValue * 255));
            blueValue = GUI.HorizontalSlider(new Rect(80, 70, 256, 20), blueValue, 0.0f, 1.0f);
            if (GUI.Button(new Rect(10, 110, 50, 20), "Ok"))
            {
                selectorOn = false;
                redReset = redValue;
                greenReset = greenValue;
                blueReset = blueValue;
            }
            if (GUI.Button(new Rect(70, 110, 80, 20), "Reset"))
            {
                redValue = redReset;
                greenValue = greenReset;
                blueValue = blueReset;
            }
            renderer.material.SetColor("_Color", new Color(redValue, greenValue, blueValue, 1));
        }
        else
        {
            GUI.Label(new Rect(10, 10, 500, 20), "========================================");
            GUI.Label(new Rect(10, 25, 500, 20), "Nhấp chọn phần thân tàu vũ trụ để chỉnh màu!");
            GUI.Label(new Rect(10, 40, 500, 20), "========================================");
        }
    }


B4. Tại thẻ Hierarchy, bấm vào hình tam giác kế bên spaceshipColor và kéo thả file C# vừa tạo ở bước trên vào ship như hình sau:


B5. Nhấp chọn ship ở thẻ Hierarchy, vào Component | Physics | Mesh Collider.


B6. Ấn nút Play để kiểm tra thành quả.

Project RPG BÀI 10A. DỌN DẸP FILE BASESTAT


Chuỗi bài viết dọn dẹp nhà cửa vì lo ăn tết nên post muộn :D



B1. Double click vào file C# BaseStat và xóa tất cả đi, chèn lại đoạn code sau vào:

public class BaseStat {
    public const int STARTING_EXP_COST = 100;    //value of all stats to start

    private int _baseValue;                        //the base value of this stat
    private int _buffValue;                        //the amount of the buff to this stat
    private int _expToLevel;                    //the total amount of exp needed to raise this skill
    private float _levelModifier;                //the modifier applied to the exp needed to raise this skill


    /// <summary>
    /// Initializes a new instance of the <see cref="BaseStat"/> class.
    /// </summary>
    public BaseStat(){
        _baseValue = 0;
        _buffValue = 0;
        _levelModifier = 1.1f;
        _expToLevel = STARTING_EXP_COST;
    }

#region Basic Setters and Getters
    //Basic Setters and Getters
    /// <summary>
    /// Gets or sets the _baseValue.
    /// </summary>
    /// <value>The _baseValue.</value>
    public int BaseValue{
        get{ return _baseValue;}
        set{ _baseValue = value;}

    }

    /// <summary>
    /// Gets or sets the _buffValue.
    /// </summary>
    /// <value>The _buffValue.</value>
    public int BuffValue{
        get{ return _buffValue;}
        set{ _buffValue = value;}
       
    }

    /// <summary>
    /// Gets or sets the _expToLevel.
    /// </summary>
    /// <value>The _expToLevel.</value>
    public int ExpToLevel{
        get{ return _expToLevel;}
        set{ _expToLevel = value;}
       
    }

    /// <summary>
    /// Gets or sets the _levelModifier.
    /// </summary>
    /// <value>The _levelModifier.</value>
    public float LevelModifier{
        get{ return _levelModifier;}
        set{ _levelModifier = value;}
       
    }
#endregion
    /// <summary>
    /// Calculates the exp to level.
    /// </summary>
    /// <returns>The exp to level.</returns>
    private int CalculateExpToLevel(){
        return (int)(_expToLevel * _levelModifier);
    }

    /// <summary>
    /// Assign the new level to _expToLevel and then increase the _baseValue by one.
    /// </summary>
    public void LevelUp(){
        _expToLevel = CalculateExpToLevel();
        _baseValue++;
    }

    /// <summary>
    /// Recalculate the adjust base value ans return it
    /// </summary>
    /// <value>The adjusted base value.</value>
    public int AdjustedBaseValue{
        get{ return _baseValue + _buffValue; }
    }
}


B2. Double click vào file C# GameSettings và sửa lại dòng code tô đỏ dưới đây:

public void LoadCharacterData(){
        GameObject pc = GameObject.Find("pc");
      
        PlayerCharacter pcClass = pc.GetComponent<PlayerCharacter>();

        pcClass.Name = PlayerPrefs.GetString("Player Name", "Name me");

        for(int cnt = 0; cnt < Enum.GetValues(typeof(AttributeName)).Length; cnt++){
            pcClass.GetPrimaryAttribute(cnt).BaseValue = PlayerPrefs.GetInt (((AttributeName)cnt).ToString() + " - Base Value", 0);
            pcClass.GetPrimaryAttribute(cnt).ExpToLevel = PlayerPrefs.GetInt (((AttributeName)cnt).ToString() + " - EXP To Level", 1);
        }



Sửa thành như đã tô đỏ dưới đây:

            pcClass.GetPrimaryAttribute(cnt).ExpToLevel = PlayerPrefs.GetInt (((AttributeName)cnt).ToString() + " - EXP To Level", Attribute.STARTING_EXP_COST);