Thứ Năm, 8 tháng 5, 2014

Project RPG BÀI 16. HIỂN THỊ TÊN KHI XÁC ĐỊNH MỤC TIÊU



Ở bài viết Project RPG BÀI 4. Xác định mục tiêu, chúng ta đã tạo ra script Targetting để chọn đối tượng trong phạm vi của nhân vật bằng phím Tab và thay đổi mục tiêu qua lại giữa các đối tượng. Ở bài viết này, chúng ta sẽ tạo ra một script mới dựa theo script Targetting nhưng có thêm phần hiển thị tên mục tiêu cùng thanh máu thay vì chỉ thay đổi màu sắc như ở bài trước.


B1. Double click vào scene Level1 ở thẻ Project để tiếp tục làm việc với scene này.

B2. Vào Edit | Project Settings | Tags and Layers và qua thẻ Inspector, mục Tags nhập vào Element 0 là Enemy.


B3. Tại thẻ Project, nhấp chọn mob_Slug ở thư mục Prefabs và qua thẻ Inspector, điều chỉnh tag là Enemy.

B4. Tại thẻ Hierarchy, đổi tên 3 đối tượng mob_Slug thành mob_Slug 1, mob_Slug 2, mob_Slug 3 và chỉnh tag cho cả 3 là Enemy. (Lưu ý: không nên chọn tất cả rồi đặt tag trong một lần vì có thể dính tag cho đối tượng con là Armateur)

 

B5. Tại thẻ Hierarchy, nhấp chọn Create | 3D Text và đặt tên là Name.


B6. Nhấp chọn Name ở thẻ Hierarchy vừa tạo ở bước trên và qua thẻ Inspector, điều chỉnh như sau:


B7. Kéo thả Name vào mob_Slug 1 rồi qua thẻ Inspector, điều chỉnh tọa độ và Mesh Render của Name như sau:


B8. Tại thẻ Hierarchy, nhấp chọn mob_Slug 1 và qua thẻ Inspector, bấm chọn nút Apply để các mob_slug còn lại đều có thêm Name giống như mob_Slug 1 vừa điều chỉnh.

 


B9. Nhấp phải vào thư mục Script và chọn Create | C# Script và đặt tên là TargetMob. Double click vào file này và xóa tất cả đi, chèn lại đoạn code sau vào:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class TargetMob : MonoBehaviour {
    public List<Transform> targets;
    public Transform selectedTarget;
   
    private Transform myTransform;
    // Use this for initialization
    void Start () {
        targets = new List<Transform>();
        selectedTarget = null;
        myTransform = transform;
        AddAllEnemies();
    }
   
    public void AddAllEnemies(){
        GameObject[] go = GameObject.FindGameObjectsWithTag("Enemy");
       
        foreach(GameObject enemy in go)
            AddTarget(enemy.transform);
    }
   
    public void AddTarget(Transform enemy){
        targets.Add (enemy);
    }
   
    private void SortTargetsByDistance(){
        targets.Sort(delegate(Transform t1, Transform t2){
            return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
        });
       
    }
   
    private void TargetEnemy(){
        if(selectedTarget == null){
            SortTargetsByDistance();
            selectedTarget = targets[0];
        }
        else{
            int index = targets.IndexOf (selectedTarget);
           
            if(index < targets.Count - 1){
                index++;
            }
            else{
                index = 0;
            }
            DeselectTarget();
            selectedTarget = targets[index];
        }
        SelectTarget();
    }
   
    private void SelectTarget(){
        Transform name = selectedTarget.FindChild ("Name");

        if (name == null) {
            Debug.LogError("Could not find the Name on " + selectedTarget.name);
            return;
        }

        name.GetComponent<TextMesh>().text = selectedTarget.GetComponent<Mob>().Name;
        name.GetComponent<MeshRenderer>().enabled = true;
        selectedTarget.GetComponent<Mob>().DisplayHealth();

        Messenger<bool>.Broadcast("show mob vitalbars", true);
    }

    private void DeselectTarget(){
        selectedTarget.FindChild ("Name").GetComponent<MeshRenderer> ().enabled = false;
       
        selectedTarget = null;
        Messenger<bool>.Broadcast("show mob vitalbars", false);
    }

    // Update is called once per frame
    void Update () {
        if(Input.GetKeyDown(KeyCode.Tab)){
            TargetEnemy();
        }
    }
}

B10. Kéo thả file C# TargetMob vào Game Master ở thẻ Hierarchy.


B11. Double click vào file C# Mob và xóa tất cả đi chèn lại đoạn code bên dưới vào:

 using UnityEngine;
using System.Collections;

public class Mob : BaseCharacter {
    public int curHealth;
    public int maxHealth;
  
    // Use this for initialization
    void Start () {
    //    GetPrimaryAttribute ((int)AttributeName.Constituion).BaseValue = 100;
    //    GetVital((int)VitalName.Health).Update ();

        Name = "Slug Mob";
    }
  
    // Update is called once per frame
    void Update () {

    }

    public void DisplayHealth(){
        Messenger<int, int>.Broadcast("mob health update", curHealth, maxHealth);

    }
}


B12. Tại thẻ Project, nhấp chọn mob_Slug 1 rồi qua thẻ Inspector, điều chỉnh Cur Health và Max Health như sau:


B13. Thực hiện tương tự với các mob_Slug còn lại nhưng nhập vào các giá trị Cur Health khác nhau còn Max Health giống bước trên.


B14. Double click vào file C# VitarBar nằm trong thư mục HUDClasses, xóa tất cả đi và chèn lại đoạn code sau vào:

/// <summary>
/// VitalBar.cs
///
/// This class is responsble for displaying a vita for the player character or a mob...
/// </summary>
using UnityEngine;
using System.Collections;

public class VitalBar : MonoBehaviour {
    public bool _isPlayerHealthBar;
   
    private int _maxBarLength;
    private int _curBarLength;
    private GUITexture _display;

    void Awake(){
        _display = gameObject.GetComponent<GUITexture>();
    }

    // Use this for initialization
    void Start () {

        _maxBarLength = (int)_display.pixelInset.width;

        _curBarLength = _maxBarLength;
        _display.pixelInset = CalculatePosition ();
        OnEnable();
    }
   

    //This method is called when the gameobject is enabled
    public void OnEnable(){
        if(_isPlayerHealthBar)
            Messenger<int, int>.AddListener("player health update", OnChangeHealthBarSize);
        else{
            ToggleDisplay(false);
            Messenger<int, int>.AddListener("mob health update", OnChangeHealthBarSize);
            Messenger<bool>.AddListener("show mob vitalbars", ToggleDisplay);
        }
    }
   
    //this method is called when the gameobject is disabled
    public void OnDisable(){
        if(_isPlayerHealthBar)
            Messenger<int, int>.RemoveListener("player health update", OnChangeHealthBarSize);
        else{
            Messenger<int, int>.RemoveListener("mob health update", OnChangeHealthBarSize);
            Messenger<bool>.RemoveListener("show mob vitalbars", ToggleDisplay);
        }
    }
   
    //This method will calculate the total size of the healthbar in relation to the % of health the target has left
    public void OnChangeHealthBarSize(int curHealth, int maxHealth){
        //Debug.Log("We heard an event: curHealth = " + curHealth + " - maxHealth = " + maxHealth);
        _curBarLength = (int)((curHealth / (float)maxHealth) * _maxBarLength);    //this calculate the current bar length based on the player health %

        //_display.pixelInset = new Rect(_display.pixelInset.x, _display.pixelInset.y, _curBarLength, _display.pixelInset.height);
        _display.pixelInset = CalculatePosition();
    }
   
    //setting the health bar to the player or mob
    public void SetPlayerHealth(bool b){
        _isPlayerHealthBar = b;
    }

    private Rect CalculatePosition(){
        float yPos = _display.pixelInset.y / 2 - 10;

        if(!_isPlayerHealthBar){
            float xPos = (_maxBarLength - _curBarLength) - (_maxBarLength / 4 + 10);
            return new Rect(xPos, yPos, _curBarLength, _display.pixelInset.height);
        }

        return new Rect(_display.pixelInset.x, yPos, _curBarLength, _display.pixelInset.height);

    }

    private void ToggleDisplay (bool show){
        _display.enabled = show;

    }
}


B15. Save scene và ấn nút Play để kiểm tra thành quả. Ấn Tab để thay đổi qua lại giữa các mục tiêu.

Thứ Ba, 6 tháng 5, 2014

DEVGAME 1.7 - IN THÔNG BÁO LÊN CONSOLE



Một cách cơ bản nhất để kiểm tra hàm có thực hiện hay không là in thông báo lên console để kiểm tra.


Trở lại cửa sổ web Script Reference, gõ vào khung search dòng chữ "print to console". Khi đó bạn sẽ thấy trong kết quả tìm kiếm có dòng "Debug.Log - Logs message to the Unity Console" ( Thông báo ghi chú lên Console ). Nhấp chọn vào kết quả này để xem cách thức sử dụng của hàm này. Ngoài ra, lần sau, bạn cũng có thể giành chút thời gian để xem qua hàm MonoBehaviour.print cũng tương tự như Debug.Log và dễ nhớ hơn.

B1. Chèn dòng code tô đỏ dưới đây vào hàm OnMouseDown( ) như sau:

#pragma strict

function OnMouseDown ( ) {

    Debug.Log("This object was picked");

}


B2. Lưu file script lại.

Phần hướng dẫn trên web có để là "Hàm được gọi mỗi khi nhấp chuột lên button của GUI Element hoặc Collider". Ở đây chúng ta không sử dụng GUI nên chúng ta phải tạo collider.

B3. Trở lại Unity Editor, nhấp chọn Cube ở thẻ Hierarchy và qua thẻ Inspector bạn sẽ thấy nó đã có collider sẵn:



B4. Để dễ nhấp trúng khối hợp hơn bạn nên tắt phần dịch chuyển đi. Tại thẻ Hierarchy, nhấp chọn Cube Parent và qua thẻ Inspector điều chỉnh như sau:


B5. Kéo thả file Js (JavaScript) MousePick vào Cube ở thẻ Hierarchy như sau:
 

B6. Nhấn nút Play và thử nhấp vào Cube.

B7. Nhấn Ctrl + Shift + C để xem thông báo trong hộp thoại Console.
 

Lưu ý: Nếu không thấy thông báo xuất hiện, chắc rằng bạn đã kéo thả file Js PickUp vào Cube, không phải Cube Parent nhé. Vì Cube Parent không có collider.

Vật thể không cần phải hiện hình hoặc được render mới có thể nhấp chọn. Điều này giúp tăng tính sáng tạo thêm trong các môi trường game.

B8. Nhấp chọn Cube ở thẻ Hierarchy và nhớ vị trí của nó.

B9. Qua thẻ Inspector, bỏ chọn Mesh Render để ẩn khối hộp đi.


Khối hộp đã được ẩn khỏi khung nhìn Game. Trong khung nhìn Scene, mặc dù nó vẫn còn thấy các cạnh màu xanh của khối hộp khi nhấp vào Box Collider ở thẻ Inspector.


B10. Nhấp nút Play và rà chuột nhấp chọn vào chỗ của khối hộp đã được ẩn.

Bạn sẽ thấy dù khối hộp không hiển thị lên màn hình nhưng khi nhấp chuột thông báo vẫn xuất hiện trên Console.

B11. Nhấp nút Play để thoát khỏi quá trình chạy game. Nhấp chọn Cube ở thẻ Hierarchy và qua thẻ Inspector mở Mesh Render lên lại và tắt nút kế bên tên Cube đi như sau:


Khi đó bạn sẽ thấy khối hộp không còn thấy nữa trên khung nhìn Scene kể cả khi bấm vào Box Collider, còn trên thẻ Hierarchy bạn sẽ thấy Cube chuyển sang màu tối hơn


B12. Hãy nhấn nút Play và nhấp chuột vào vùng mà bạn đã nhớ vị trí của khối hộp, lúc này sẽ không có thông báo xuất hiện khi nhấp trúng vào khối hộp nữa.

Trường hợp tương tự sẽ xuất hiện nếu bạn bật trở lại và tắt Box Collider đi vì lúc đó không có collider để kiểm tra va chạm nữa. Nên thông báo sẽ không hiện lên hộp thoại Console.

Thứ Năm, 1 tháng 5, 2014

ProjectGame 1.3 - Tạo class CharacterController và SpriteManager



Trong bài viết này, chúng ta tạo file Javascript mới để điều khiển việc di chuyển của nhân vật và các ảnh chuyển động cho từng động tác của nhân vật. Chúng ta có thể code bằng Unitron (Mac), UniSciTE (Windows), hoặc MonoDevelop. MonoDevelop là công cụ biên tập chính được thiết kế cho code C# và môi trường .NET, vì vậy nếu bạn quen C# hơn bạn có thể yêu thích nó. Tuy nhiên, chúng ta sẽ code bằng JavaScript bởi vì nó có nhiều hàm nhanh hơn và debug tốt hơn, như tìm hoặc thay thế từ trong toàn bộ project bằng cách nhấn tổ hợp phím Command + Shift + Fin (Mac) hoặc Control + Shift + Fin (Windows) và tự động hoàn thành từ tìm kiếm. Nếu bạn đã biết JavaScript thì việc chuyển sang C# khá dễ dàng.


Mục tiêu

1.1 - Tạo Camera và Level
1.2 - Tạo nhân vật 2D
>> 1.3 - Tạo class (lớp) CharacterController và SpriteManager
1.4 - Nhảy và yếu tố vật lý
1.5 - Tạo chìa khóa và mở cửa
1.6 - Chèn âm thanh và nút Replay


Chuẩn bị

Bây giờ, chúng ta sẽ bắt tay vào code, nhưng trước tiên, chúng ta phải thiết lập lại đôi chút.

B1. Tại thẻ Project, vào thư mục Scripts và xóa tất cả các file đi.

B2. Tiếp theo, chúng ta phải thiết lập lại Unity để sử dụng MonoDevelop như trình biên tập code mặc định. Bằng cách vào Edit | Preferences.

B3. Chúng ta sẽ thấy các mục thiết lập cho Unity trong cửa sổ vừa hiện lên. Trong tab General, vào External Script Editor và thay đổi Use build-in editor thành MonoDevelop bằng cách nhấp chọn nút Browse và chọn tìm đến thư mục cài đặt Unity và chọn Unity | MonoDevelop | MonoDevelop.exe.


MonoDevelop là một "Môi trường phát triển tích hợp" (IDE) cơ bản được thêm vào từ Unity 3.X, nó có môi trường code và debug tốt hơn. Chúng ta có thể tìm hiểu thêm về cách điều chỉnh qua trang web của Unity:

http://unity3d.com/support/documentation/Manual/HOWTO-MonoDevelop.html


Bắt tay vào làm việc

B1. Tại thẻ Project, nhấp phải vào thư mục Scripts và chọn Create | JavaScript và đặt tên là CharacterController2D.



B2. Double click vào file JavaScript CharacterController2D để mở file này lên và bắt đầu code.

B3. Trước tiên chúng ta sẽ tiến hành khai báo các biến cần thiết như sau:

public var f_speed : float = 5.0;
public var loopSprites : SpriteManager[];
private var in_direction : int;

Ở đây, biến f_speed biểu thị cho tốc độ của nhân vật và chúng ta thiết lập nó là public vì vậy chúng ta co thể tùy chỉnh nó trong thẻ Inspector ở Unity Editor. Mãng loopSprite của lớp SpriteManager sẽ kiểm soát quá trình cập nhật texture của sprite khi chuyển động, chúng ta sẽ tạo ra lớp này sau. Biến in_direction lưu hướng của nhân vật, biến này chỉ mang 2 giá trị là 1 (sprite kế tiếp bên phải) và -1 (sprite kế tiếp bên trái).

B4. Tiếp theo, chúng ta sẽ bổ sung code sau vào hàm Start( ) đã mặc định được tạo sẵn.

public function Start() : void {
       in_direction = 1;
       //Initialization Sprite Manager
       for (var i : int = 0; i<loopSprites.length; i++) {
              loopSprites[i].init();
       }
       //Update Main Camera to the character position
       Camera.main.transform.position = new Vector3(transform.position.x, transform.position.y,Camera.main.transform.position.z);
}

B5. Tiếp theo, chúng ta sẽ bổ sung đoạn code sau vào hàm Update( ) cũng đã được mặc định tạo sẵn:

// Update is called once per frame
public function Update () : void {
       if (Input.GetButton("Horizontal")) {
              //Walking
              in_direction = Input.GetAxis("Horizontal") < 0 ? -1: 1;
              rigidbody.velocity = new Vector3((in_direction*f_speed), rigidbody.velocity.y, 0);
              //Reset Stay animation frame back to the first frame
              loopSprites[0].resetFrame();

              //Update Walking animation while the character is walking
              loopSprites[1].updateAnimation(in_direction, renderer.material);
       } else {
              //Stay
              //Reset Walking animation frame back to the first frame
              loopSprites[1].resetFrame();
              //Update Stay animation while the character is not walking
              loopSprites[0].updateAnimation(in_direction, renderer.material);
       }
}

B6. Sau đó chúng ta sẽ tạo thêm hàm LateUpdate( ) phía bên dưới hàm Update( ). Chúng ta sẽ sử dụng hàm này để cập nhật vị trí camera sau khi nhân vật di chuyển bằng cách điều chỉnh tọa độ để theo sau nhân vật.

public function LateUpdate() : void {
       //Update Main Camera
       Camera.main.transform.position = new Vector3(transform.position.x, transform.position.y, Camera.main.transform.position.z);
}


B7. Kế tiếp, chúng ta sẽ tạo lớp SpriteManager để quản lý các ảnh chuyển động của chúng ta trong file JavaScript CharacterController2D vừa tạo ở các bước trên. Tiếp tục bổ sung đoạn code sau vào bên dưới hàm LateUpdate( ) trong file script chúng ta đang làm.
class SpriteManager {
       public var spriteTexture : Texture2D; //Set Texture use for a loop animation such as walking, stay, etc.
       public var in_framePerSec : int; //Get frame per sec to calculate time
       public var in_gridX : int; //Get max number of Horizontal images
       public var in_gridY : int; //Get max number of Vertical images
       private var f_timePercent : float;
       private var f_nextTime : float; //Update time by using frame persecond
       private var f_gridX : float;
       private var f_gridY : float;
       private var in_curFrame : int;
     
       public function init () : void {
              f_timePercent = 1.0/in_framePerSec;
              f_nextTime = f_timePercent; //Update time by using frame persecond
              f_gridX = 1.0/in_gridX;
              f_gridY = 1.0/in_gridY;
              in_curFrame = 1;
       }

       public function updateAnimation (_direction : int, _material : Material) : void {
              //Update material
              _material.mainTexture = spriteTexture;
              //Update frame by time
              if (Time.time>f_nextTime) {
                     f_nextTime = Time.time + f_timePercent;
                     in_curFrame++;
                     if (in_curFrame>in_framePerSec) {
                            in_curFrame = 1;
                     }
              }
              _material.mainTextureScale = new Vector2 (_direction * f_gridX, f_gridY);
              var in_col : int = 0;
              if (in_gridY>1) {
                     //If there is more than one grid on the y-axis update the texture
                     in_col= Mathf.Ceil(in_curFrame/in_gridX);
              }
              if (_direction == 1) { //Right
                     _material.mainTextureOffset = new Vector2(((in_curFrame)%in_gridX) * f_gridX, in_col*f_gridY);
              } else { //Left
                     //Flip Texture
                     _material.mainTextureOffset = new Vector2(((in_gridX + (in_curFrame)%in_gridX)) * f_gridX, in_col*f_gridY);
              }
       }

       public function resetFrame () :void {
              in_curFrame = 1;
       }
}

B8. Bây giờ, ấn Ctrl + S để save file script này lại, kéo thả nó vào Player ở thẻ Hierarchy. Nhấp chọn Player và qua thẻ Inspector điều chỉnh Size = 2 trong Loop Sprites và các mục khác như sau:


B9. Save scene lại, và ấn nút Play để kiểm tra thành quả. Bạn hãy ấn phím mũi tên qua trái / qua phải hoặc nút A / D để di chuyển qua trái hoặc qua phải.


Hoàn thành mục tiêu 1.3

Chúng ta vừa tạo một đoạn script để kiểm soát chuyển động của và xử lý các động tác của nhân vật. Trước tiên chúng ta thiết lập biết in_direction là 1 bởi vì chúng ta muốn nhân vật lúc bắt đầu sẽ quay mặt sang bên phải. Khi đó, mảng hình ảnh sẽ được lặp và khởi tạo trong lớp SpriteManager tùy theo độ dài mà chúng ta đặt. Chúng ta sẽ sử dụng main camera từ scene hiện tại thông qua cú pháp Camera.main. Cú pháp này cho phép ta truy cập đến đối tượng Main Camera từ bất kì đâu chúng ta muốn và khi đó chúng ta hướng vị trí của camera theo nhân vật. Tiếp theo, chúng ta sẽ đặt đoạn code vào hàm Update( ) đã được mặc định tạo sẵn, tương tự như hàm Start( ). Hàm này sẽ điều khiển quá trình chuyển động khi nhân vật từ bước đi sang nhảy và cập nhật các ảnh chuyển động.

Sau đó, chung ta sử dụng lớp Input để phát hiện khi người chơi nhấn phím bấm từ bàn phím. Chúng ta làm tất cả việc điều khiển nhân vật trong hàm Update( ). Đầu tiên, chúng ta sử dụng if (Input.GetButton("Horizontal")) { } để kiểm tra việc người chơi đã nhấn phím Horizontal (mặc định trong Unity là A, D, ←, →) và chúng ta di chuyển nhân vật nếu phím được nhấn. Dòng đầu tiên của hàm if kiểm tra hướng của nhân vật in_direction =Input.GetAxis("Horizontal") < 0 ? -1: 1; có nghĩa là nếu nhấn nút Horizontal, chúng ta sẽ lấy giá trị tọa độ từ hàm Input.GetAxis("Horizontal"). Hàm Input.GetAxis sẽ trả về giá trị từ -1 đến 1 biểu thị cho việc người chơi đang nhấn nút. Sau đó, chúng ta kiểm tra giá trị có nhỏ hơn 0 hay không. Nếu có thì hàm trả về -1 (di chuyển qua trái), nếu không thì trả về 1 (di chuyển qua phải). Khi đó dòng rigidbody.velocity = new Vector3((in_direction*f_speed), rigidbody.velocity.y, 0); chúng ta đã gán hướng và tốc độ vào rigidbodyvelocity. Chúng ta không gán giá trị cho trục Z bởi vì nhân vật của chúng ta không di chuyển theo hướng đó.

Cuối cùng, chúng ta tạo lớp SpriteManager cho file Javascript của chúng ta để điều khiển việc xử lý các vật liệu gán cho sprite bằng cách sử dụng tối đa số bức ảnh chúng ta đã tính với thời gian khi chạy mỗi bức ảnh. Hãy nhìn qua lớp SpriteManager. spriteTexture cơ bản dùng để thiết lập vật liệu của các sprite được lấy từ class. Những texture này sẽ được gọi và gán vào vật liệu chính khi nhân vật thay đổi di chuyển, như từ bước đi sang đứng yên, bước đi sang nhảy và vân vân.... in_framePerSec là tổng số ảnh texture của sprite, sẽ được tính để hiển thị trong khung hình kế tiếp. in_gridX là số dòng của sprite texture, và in_gridY là số cột, để tính toán Tiling và Offset của texture như chúng ta đã tìm hiểu ở bài viết trước. Chúng ta thiết lập private cho các biến f_timePercent, f_nextTime, f_gridX, f_gridY, và in_curFrame, mà chúng ta sử dụng để tính toán trong hàm updateAnimation( ). Tiếp theo, chúng ta có hàm init( ). Hàm này cơ bản là thiết lập các biến. Sau đó, hàm updateAnimation( ) sẽ lấy vật liệu và hướng nhìn của nhân vật để xử lý và cập nhật các ảnh chuyển động. Cuối cùng, chúng ta có hàm resetFrame( ) để thiết lập lại số khung hình chuyển động về 1.


Kiến thức bổ sung

Input Manager


Trong Unity, chúng ta có thể tùy chỉnh thiết lập Input Manager bằng cách vào Edit | Project Settings | Input. Trong thẻ Inspector, nhấp chọn Axes và bạn sẽ thấy Size: 17, là độ dài mảng của tất cả các input. Nếu có hơn 17 input, chúng ta có thể nhập số vào đây (mặc định là 17). Tiếp theo chúng ta sẽ thấy có 17 tên từ Horizontal đến Jump như thiết lập mặc định. Mỗi cái sẽ có các biến riêng chúng ta có thể điều chỉnh.

Chúng ta có thể thông tin thêm tại website của Unity:

http://unity3d.com/support/documentation/Components/classInputManager.html

Trong file script của chúng ta, chúng ta sử dụng hàm Input.GetButton("Horizontal"). GetButton dùng để kiểm tra nếu các nút Horizontal được nhấn hay không. Horizontal là tên của input đầu tiên như chúng ta đã thấy ở ảnh minh họa bên trên. Chúng ta cũng có thể dùng Input.GetKey("left") để làm việc đó. Nó cũng có kết quả tương tự với Input.GetButton, nhưng khác nhau là GetKey chỉ phát hiện khi phím chỉ định được nhấn. Vì vậy GetButton dễ cho việc người dùng thay đổi phím trong suốt quá trình chơi. 2 nút Negative Button và Positive Button sẽ gửi giá trị âm và dương, thích hợp cho việc điều hướng như lên, xuống, trái, phải. Ngoài ra còn có biến Dead, biến này sẽ thiết lập bất kì số nào nhỏ hơn từ giá trị của biến này đến 0, rất thích hợp cho việc sử dụng joystick. Cũng có thể điều chỉnh Type thành key/mouse và bật biến Snap để khi nhận được giá trị đối nghịch tọa độ sẽ trả về 0.