Thứ Sáu, 29 tháng 11, 2013

Project RPG BÀI 4. XÁC ĐỊNH MỤC TIÊU

Tiếp tục cho phần tạo chức năng chiến đấu cho nhân vật, bài viết này mình sẽ hướng dẫn cách để tạo ra mục tiêu cho người chơi tấn công, nếu mục tiêu không được chọn thì sẽ không thể tấn công và ngược lại.



B1. Tại thẻ Project, nhấp chuột chọn Evil Cube, qua thẻ Inspector, bỏ dấu stick ở file Enemy AI (Script).


B2. Vẫn đang chọn Evil Cube, tại thẻ Inspector, nhấp vào nút Untagged và chọn Add Tag và gõ vào Element 0 từ Enemy. Nhấp chuột chọn lại Evil Cube và chọn Tag là Enemy



B3. Tại thẻ Hierarchy, nhấp chọn Evil Cube và ấn Ctrl + D 2 lần để tạo ra thêm 2 Evil Cube giống như lúc đầu. Đổi tên 3 Evil Cube này lại thành Evil Cubie 1, Evil Cubie 2 và Evil Cubie 3.


B4.Nhấp phải vào thư mục Script và chọn Creat | C# Script và đặt tên file là Targetting.


B5. Double click vào file C# vừa tạo và chèn đoạn code sau vào:

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

public class Targetting : 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 DeselectTarget(){
        selectedTarget.renderer.material.color = Color.blue;
        selectedTarget = null;
    }

    private void SelectTarget(){
        selectedTarget.renderer.material.color = Color.red;
        PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
        pa.target = selectedTarget.gameObject;
    }

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


B6. Kéo thả file C# vừa tạo ở bước trên vào Player ở thẻ Hierarchy.

B7. Sử dụng công cụ Tranform tool và di chuyển 3 Evil Cubie ra 3 nơi khác nhau như sau:


B8. Nhấn nút Play để kiểm tra thành quả. Trong khi chơi, bạn có thể ấn Tab để chọn mục tiêu (màu đỏ) mới có thể tấn công được.

Thứ Tư, 27 tháng 11, 2013

Cookbook - PHÓNG TO GÓC NHÌN CỦA CAMERA


  - Phóng to góc nhìn của camera -

Bài viết này mình sẽ hướng dẫn các bạn tạo chức năng phóng to góc nhìn của camera bằng một cú click chuột. Chức năng này rất hữu dụng cho các sniper (xạ thủ) trong các game bắn súng sử dụng súng nhắm từ xa.

Chuẩn bị
Terrain

Cách để làm

B1. Nhấp phải vào thẻ Project và chọn Import Package | Custom Package rồi Open file Terrain vừa tải. Double click vào scene Demo mình đã tạo sẵn các đối tượng phụ để tiện sử dụng.


B2. Tiếp tục nhấp phải vào thẻ Project và chọn Creat | C# Script và đặt tên là TelescopicView.


B3. Double click vào file C# vừa tạo và chèn đoạn code sau vào:

 

B4. Kéo thả file C# Script vừa tạo vào Main Camera ở thẻ Hierarchy.

 

B5. Nhấn nút Play để kiểm tra thành quả. Bạn có thể nhấp và giữ chuột trái để phóng to góc nhìn.

 

B6 (Pro only). Nếu bạn đang sử dụng Unity3D phiên bản pro bạn có thể dừng game bằng cách ấn tiếp vào nút play để hủy bỏ chế độ đang chơi và tiếp tục thực hiện các bước tiếp theo.

B7 (Pro only). Nhấp phải vào thẻ Project và chọn Import Package | Image Effects (Pro only).

 

B8 (Pro only). Nhấp chuột chọn Main Camera và vào Component | Image Effects | Camera | Vignette.

B9 (Pro only). Mở lại file C# Telescopic View và nhấp chuột vào các dòng comment (những dòng có // ở đầu) và ấn tổ hợp phím Ctrl + Alt + C để xóa dấu comment nên chương trình mới có thể thực hiện các lệnh này được.

 

B10 (Pro only). Nhấp nút Play để kiểm tra thành quả. Lúc này, bạn sẽ có thêm hiệu ứng độ tối ở góc ảnh khi phóng to góc nhìn.

Thứ Hai, 25 tháng 11, 2013

Project RPG BÀI 3. CHIẾN ĐẤU CẬN CHIẾN


Ở 2 bài viết trước mình đã thực hiện xong các tính năng thanh máu (Hp) và chức năng đuổi theo người chơi của Enemy (Enemy AI). Bài viết này mình sẽ tạo tính năng chiến đấu cận chiến cho người chơi và enemy. Người chơi có thể tấn công enemy và khiến Hp của enemy giảm dần nếu khoảng cách tấn công đủ gần hay đúng góc độ để khiến enemy bị trúng đòn. Thời gian ra đòn người chơi / enemy có thể nhanh hoặc chậm tùy thuộc vào thời gian cooldown (hồi chiêu) của bản thân. Khi thời gian cooldown chưa kết thúc thì không được tấn công. Tương tự với khoảng cách tấn công cũng vậy, người chơi phải đứng ở vị trí đủ gần để có thể đánh trúng enemy. Bài viết này mình sẽ tạo những chức năng như đã nêu ở trên.


B1. Nhấp phải vào thư mục Script trong thẻ Project và chọn Creat | C# Script và đặt tên file vừa tạo là PlayerAttack.


B2. Double click vào file PlayerAttack và nhập đoạn code sau vào:

using UnityEngine;
using System.Collections;

public class PlayerAttack : MonoBehaviour
{

    public GameObject target;
    public float attackTimer;
    public float coolDown;

// Use this for initialization

    void Start(){
        attackTimer = 0;
        coolDown = 2.0f;
    }

// Update is called once per frame

    void Update(){
        if (attackTimer > 0)
            attackTimer -= Time.deltaTime;
       
        if (attackTimer < 0)
            attackTimer = 0;
       
        if (Input.GetKeyUp (KeyCode.F)) {
            if (attackTimer == 0){
                Attack();
                attackTimer = coolDown;
            }
        }

    }

    private void Attack(){

        float distance = Vector3.Distance(target.transform.position, transform.position);
       
        Vector3 dir = (target.transform.position - transform.position).normalized;
       
        float direction = Vector3.Dot(dir, transform.forward);

        Debug.Log(direction);

        if (distance < 2.5f) {
            if(direction > 0){
                EnemyHealth eh = (EnemyHealth)target.GetComponent("EnemyHealth");
                eh.AddjustCurrentHealth(-10);
            }
           
        }

    }

}


B3. Tại thẻ Project, kéo thả file PlayerAttack vào Player trong thẻ Hierarchy.


B4. Nhấp chọn Player trong thẻ Project và kéo thả Evil Cube cũng trong thẻ Project vào Target của PlayerAttack (Script) trong thẻ Inspector như sau:

 

B5.Vẫn trong PlayerAttack (Script) ở thẻ Inspector, điều chỉnh AttackTimer = 0 và Cool Down = 2.


B6. Nhấp phải vào thẻ Project và chọn Creat | C# Script và đặt tên là EnemyAttack.

 
B7. Double click vào file vừa tạo và chèn đoạn code sau vào:

using UnityEngine;
using System.Collections;

public class EnemyAttack : MonoBehaviour
{

    public GameObject target;
    public float attackTimer;
    public float coolDown;

// Use this for initialization

    void Start(){
        attackTimer = 0;
        coolDown = 2.0f;
    }

// Update is called once per frame

    void Update(){
        if (attackTimer > 0)
            attackTimer -= Time.deltaTime;
       
        if (attackTimer < 0)
            attackTimer = 0;
       
        if (attackTimer == 0){
            Attack();
            attackTimer = coolDown;
        }
       

    }

    private void Attack(){

        float distance = Vector3.Distance(target.transform.position, transform.position);
       
        Vector3 dir = (target.transform.position - transform.position).normalized;
       
        float direction = Vector3.Dot(dir, transform.forward);

        Debug.Log (direction);

        if (distance < 2.5f) {
            if(direction > 0){
           
                PlayerHealth eh = (PlayerHealth)target.GetComponent("PlayerHealth");
                eh.AddjustCurrentHealth(-10);
            }
        }

    }

}


B8. Kéo thả file C# EnemyAttack vào Evil Cube ở thẻ Hierarchy. Nhấp chọn Evil Cube trong thẻ Hierarchy, kéo thả Player trong thẻ Hierarchy vào Target của EnemyAttack (Script) như hình sau:


B9. Tại thẻ Project, Double click vào file EnemyAI, xóa những dòng code cũ đi và chèn lại code sau vào:

using UnityEngine;
using System.Collections;

public class EnemyAI : MonoBehaviour{

    public Transform target;
    public int moveSpeed;
    public int rotationSpeed;
    public int maxDistance;
   
    private Transform myTransform;


    void Awake(){
       
        myTransform = transform;

    }

    // Use this for initialization

    void Start(){
        maxDistance = 2;
        GameObject go = GameObject.FindGameObjectWithTag("Player");
        target = go.transform;
       

    }
   
    // Update is called once per frame
    void Update(){
        Debug.DrawLine (target.position, myTransform.position, Color.yellow);

        //Look at the target
        myTransform.rotation = Quaternion.Slerp (myTransform.rotation, Quaternion.LookRotation (target.position - myTransform.position), rotationSpeed * Time.deltaTime);

        if(Vector3.Distance(target.position, myTransform.position) > maxDistance){
            // Move towards target
            myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
       
        }
       
    }

}

B10. Nhấp chuột chọn Evil Cube ở thẻ Project, qua thẻ Inspector, thay đổi giá trị Max Distance = 3, Attack Timer = 0 và Cool Down = 1.5 như hình sau:

 

B11. Save và ấn nút Play để kiểm tra thành quả. Ấn nút F để có thể tấn công enemy.


Thứ Hai, 18 tháng 11, 2013

Cookbook - Tạo texture từ ảnh chụp màn hình


  - Tạo texture từ ảnh chụp màn hình -
Nếu bạn muốn game hay người chơi của bạn chụp nhanh ảnh trong game và sử dụng nó như là một texture, bài này sẽ chỉ bạn cách làm thế nào. Bài này có thể rất hữu ích nếu bạn dự định  thực hiện trưng bày những bức ảnh trong game hay hiển thị một bức ảnh trong thời khắc then chốt vào phút cuối (đại loại trong game đua xe, tốc độ...).


Cách để làm

B1.  Nhấp phải vào thẻ Project và chọn Import Package | Skyboxes rồi nhấn Import để sử dụng gói giả lập bầu trời.


B2. Nhấp chuột chọn Main Camera trong thẻ Hierarchy và qua thẻ Inspector, kéo thanh trượt xuống dưới cùng và chọn Add component. Gõ vào khung search vừa hiện lên từ Skybox và click chuột chọn component vừa search để thêm chức năng này cho Main Camera.


B3. Vẫn trong thẻ Inspector, tại component Skybox vừa thêm, click chọn hình tròn phía sau Custom Skybox và chọn Eerie Skybox trong hộp thoại Select Material vừa hiện lên.


B4. Nhấp phải vào thẻ Project và chọn Import Package | Character Controller.

B5. Nhấp chọn Main Camera, sau đó vào Component | Camera Control | Mouse Look.


B6.  Tại thẻ Project, bấm nút Creat | C# Script và đổi tên thành ScreenTexture.

 

B7.  Double click vào file C# vừa tạo và chèn đoạn code sau vào:

using UnityEngine;
using System.Collections;

public class ScreenTexture : MonoBehaviour
{
    public int photoWidth = 50;
    public int photoHeight = 50;
    public int thumbProportion = 25;
    public Color borderColor = Color.white;
    public int borderWidth = 2;
    private Texture2D texture;
    private Texture2D border;
    private int screenWidth;
    private int screenHeight;
    private int frameWidth;
    private int frameHeight;
    private bool  shoot = false;

    void  Start ()
    {
        screenWidth = Screen.width;
        screenHeight = Screen.height;
        frameWidth = Mathf.RoundToInt (screenWidth * photoWidth * 0.01f);
        frameHeight = Mathf.RoundToInt (screenHeight * photoHeight * 0.01f);
        texture = new Texture2D (frameWidth, frameHeight, TextureFormat.RGB24, false);
        border = new Texture2D (1, 1, TextureFormat.ARGB32, false);
        border.SetPixel (0, 0, borderColor);
        border.Apply ();
    }

    void  Update ()
    {
        if (Input.GetKeyUp (KeyCode.Mouse0))
            StartCoroutine (CaptureScreen ());
    }

    void  OnGUI ()
    {
        GUI.DrawTexture (new Rect ((screenWidth * 0.5f) - (frameWidth * 0.5f) - borderWidth * 2, ((screenHeight * 0.5f) - (frameHeight * 0.5f)) - borderWidth, frameWidth + borderWidth * 2, borderWidth), border, ScaleMode.StretchToFill);
        GUI.DrawTexture (new Rect ((screenWidth * 0.5f) - (frameWidth * 0.5f) - borderWidth * 2, (screenHeight * 0.5f) + (frameHeight * 0.5f), frameWidth + borderWidth * 2, borderWidth), border, ScaleMode.StretchToFill);
        GUI.DrawTexture (new Rect ((screenWidth * 0.5f) - (frameWidth * 0.5f) - borderWidth * 2, (screenHeight * 0.5f) - (frameHeight * 0.5f), borderWidth, frameHeight), border, ScaleMode.StretchToFill);
        GUI.DrawTexture (new Rect ((screenWidth * 0.5f) + (frameWidth * 0.5f), (screenHeight * 0.5f) - (frameHeight * 0.5f), borderWidth, frameHeight), border, ScaleMode.StretchToFill);
        if (shoot) {
            GUI.DrawTexture (new Rect (10, 10, frameWidth * thumbProportion * 0.01f, frameHeight * thumbProportion * 0.01f), texture, ScaleMode.StretchToFill);
        }
    }

    IEnumerator  CaptureScreen ()
    {
        yield return new WaitForEndOfFrame();
        texture.ReadPixels (new Rect ((screenWidth * 0.5f) - (frameWidth * 0.5f), (screenHeight * 0.5f) - (frameHeight * 0.5f), frameWidth, frameHeight), 0, 0);
        texture.Apply ();
        shoot = true;
    }
}

B8.  Lưu đoạn script bạn vừa nhập lại và kéo thả nó vào Main Camera ở thẻ Hierarchy.

B9.  Tại thẻ Inspector, trong component Screen Capture, đổi giá trị
         Photo Width và Photo Height = 25 và Thumb Proportion = 75, như hình dưới đây:


B10.  Nhấp nút Play để kiểm tra thành quả. Bạn có thể chụp bất kì ảnh gì chỉ bằng cú click chuột.



Cách hoạt động

Với 1 cú click chuột, hàm lưu các điểm ảnh sẽ khởi động theo một hình chữ nhật và gán nó vào texture được vẽ nên bằng GUI.

Còn nữa

Bạn còn có thể sử dụng nó để:

1. Gán chất liệu cho vật thể:
Bạn có thể gán texture của bạn vào bất kì chất liệu nào cho các đối tượng khác bằng cách thêm dòng code tương tự vào cuối function (hàm) CaptureScreen:
GameObject.Find("MyObject").renderer.material.mainTexture = texture;


2. Sử dụng như một ảnh chụp màn hình:
Bạn có thể xuất nó thành định dạng PNG và lưu trữ nó. Tham khảo tài liệu dưới đây:
http://docs.unity3d.com/Documentation/ScriptReference/Texture2D.EncodeToPNG.html.

Thứ Hai, 11 tháng 11, 2013

AI 1.2 - Xác suất ngẫu nhiên trong AI


  1.2 - Xác suất ngẫu nhiên trong AI

Giả sử rằng kẻ địch thực vật trong một trò chơi FPS, lúc nào cũng giết chết người chơi bằng một cú bắn, một địch thủ trong một trò đua xe lúc nào cũng chọn cho mình đường đua tốt nhất, và vượt mặt không có bất kỳ sự va chạm nào với bất kỳ chướng ngại nào. Chẳng hạn như ở một mức độ quá thông minh sẽ làm cho anh ta khó chơi đến nỗi hầu như không thể nào có thể thắng nỗi. Mặc khác, tưởng tượng một kẻ địch AI lúc nào cũng chọn cùng một con đường để đi, hoặc là cố gắng để trốn khỏi người chơi. AI điều khiển những hành động của những thực thể cùng một cách, mỗi lần người chơi gặp chúng, như thế sẽ làm cho trò chơi dễ đoán ra và dễ dàng thắng.

http://halo4nation.com/wp-content/uploads/2012/06/Screen-shot-2012-06-04-at-1.36.32-PM.png
Enemy AI trong game Halo 4

Cả hai tình huống trước đó hiển nhiên ảnh hưởng đến mặt thú vị của game, và làm cho người chơi cảm thấy game không có thách thức hoặc không còn công bằng nữa. Một cách để sửa cái kiểu AI hoàn hảo và AI ngốc nghếch này, chính là gây ra vài lỗi trong sự thông minh của chúng. Trong game, tính ngẫu nhiên và xác suất được áp dụng trong việc đưa ra quyết định lúc tiến hành các phép toán của AI. Dưới đây là các tình huống chính khi chúng ta muốn để cho các thực thể AI thay đổi một quyết định ngẫu nhiên :

- Vô tình : tình huống này đôi khi trong một game trinh thám, hoặc có lẽ một game NPC, mà có thể cần đưa ra một quyết định ngẫu nhiên, chỉ vì nó không có đủ thông tin để đưa ra một quyết định hoàn hảo, và/hoặc nó thật sự không có vấn đề gì với quyết định đưa ra. Đơn giản chỉ đưa ra quyết định một cách ngẫu nhiên và hi vọng vào việc có kết quả tốt nhất, là cách để bước vào trong một tình huống như thế này.


http://img1.lln.crunchyroll.com/i/spire3/d3b2d143aaf071ab62ab6c46e74a0c311281668978_full.jpg
Ảnh chụp từ game Personal 4
- Cố ý : tình huống này dành cho dạng AI hoàn hảoAI ngốc nghếch. Như chúng ta đã nói đến trong các ví dụ trước, chúng ta sẽ cần thêm vài tính ngẫu nhiên một cách có chủ ý, chỉ để làm cho chúng thêm hiện thực, và cũng để phù hợp mức độ khó với trình độ người chơi.

http://media.pcgamer.com/files/2012/05/Diablo-3-Lost-Head.jpg
Trò chuyện với NPC để thực hiện nhiệm vụ trong game Diablo III
Chẳng hạn tính ngẫu nhiên và xác suất có thể được dùng cho những thứ chẳng hạn như khả năng bấm nút, cộng hoặc trừ tính thiệt hại ngẫu nhiên ở trên các thiệt hại cơ bản. Việc dùng ngẫu nhiên và xác suất, chúng ta có thể thêm vào một chiều hướng không chắc chắn thực tế cho game của chúng ta và làm cho hệ thống AI có phần khó đoán.

Chúng ta cũng có thể dùng xác suất để định nghĩa các lớp nhân vật AI khác nhau. Chúng ta nhìn đến những nhân vật anh hùng trong Defense of the Ancient (DotA), là một dạng game chiến thuật RTS (real-time stategy) nổi tiếng dạng Warcraft III. Có ba kiểu hero dựa trên ba thuộc tính chính : sức mạnh (Strength), thông minh (Intelligence), và nhanh nhẹn (Agility). Các nhân vật thuộc lớp Strength là các hero mạnh về tính chất vật lý, trong khi các nhân vật Intelligence phải giỏi về cách điều khiển cấc bùa phép và ma thuật. Agility định nghĩa sự lanh lẹ của một hero để tránh những cuộc tấn công và tấn công một cách nhanh nhẹn. Một AI hero Strength sẽ có khả năng để gây nhiều sát thương trong các cuộc cận chiến, trong khi hero Intelligence sẽ có nhiều cơ hội để gây sát thương cao hơn bằng việc dùng bùa và phép. Cẩn thận trong việc cân bằng tính ngẫu nhiên và xác suất giữa các lớp và các anh hùng khác nhau, sẽ làm cho game có nhiều thách thức hơn, và làm cho DotA thú vị để chơi.

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9ouo6fROhgKlIaAWWMqxs7K1MGjjXDS8OImVjrqmZ09VPIoy92VNDq8lfLMhfBIFq_z38yoAMtiOPFDJaMswPrQjGgpuGS6uij_MNAuxW8fp5DC_bBKC82L_O6ShMUSfHr3zqGN_AgSY/s1600/6.75_Loadscreen.jpg
Loadscreen từ map DotA 6.75


Hệ thống cảm biến

Nhân vật AI của chúng ta cần biết về những việc quanh chúng ta, và thế giới họ đang tương tác đến, để đưa ra một quyết định riêng biệt. Chẳng hạn thông tin có thể là như sau :

- Vị trí của người chơi : thông tin này dùng để quyết định tấn công hoặc săn, hoặc tiếp tục tuần tra.
- Công trường và những vật thể gần đó : thông tin này được dùng để trốn hoặc ẩn núp.
- Máu của người chơi và của chính nhân vật AI : thông tin còn lại được dùng để quyết định có hay không rút lui hoặc tiến tới.
- Vị trí của những tài nguyên trên bản đồ ở game RTS : thông tin này được dùng để chiếm đóng và thu thập tài nguyên, cần cho việc xây dựng và tạo ra các đơn vị khác.

http://insertcredit.com/wp-content/uploads/2011/12/sc2.jpg
Ảnh chụp trong game chiến thuật hay nhất mọi thời đại Starcraft 2
Như bạn có thể thấy, nó có thể thay đổi nhiều, phụ thuộc vào hình thức của game chúng ta đang cố gắng xây dựng. Vì thế, làm sao để chúng ta thu thập thông tin đó ?


http://store.haynhucnhoi.com/data/2013/10/11/d61df2f03f6c4ae056388e7aa8adc928.gif
Hệ thống cảm biến của thiết bị game
Bỏ phiếu

Một phương thức để thu thập thông tin là việc bỏ phiếu. Chúng ta có thể đơn giản làm if/else hoặc chuyển đổi phương thức FixedUpdate nhân vật AI của chúng ta. Nhân vật AI chỉ là thăm dò thông tin chúng ta quan tâm đến thế giới game, làm những kiểm tra, và hành động dựa vào đó. Những cách thức bỏ phiếu hoạt động tuyệt vời, nếu không có nhiều thứ để kiểm tra. Tuy nhiên, vài nhân vật có thể không cần thăm dò tình trạng thế giới mỗi hệ thống. Những nhân vật khác có thể cần những tỷ lệ phiếu bầu khác nhau. Vì thế, thông thường trong những game lớn, hệ thống AI phức tạp hơn, chúng ta cần sắp xếp một cách thức điều khiển theo sự kiện bằng cách dùng một hệ thống thông điệp tổng thể.

Hệ thống thông điệp

https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhILIq0PPLd-bvAvV-GBJkBrns546kzwDNQndWLtpF4IH8UY7d25UZ0ZJsV9fIxfqF3vm2uOf5qUwxPNw9_m92ZfNUrJxmuqz5_FKO6dRMn1WyXo5ksAVHcfOFKimlM-USv6RbU7YGA2p96/s1600/J1RG_130-1.pngAI đưa ra quyết định hồi đáp cho những sự kiện trong thế giới. Những sự kiện được kết nối giữa thực thể AI và người chơi, thế giới, hoặc những thực thể AI khác thông qua một hệ thống thông điệp. Chẳng hạn, khi người chơi tấn công một đơn vị kẻ địch từ một nhóm lính tuần tra, những đơn vị AI khác cần biết về tai nạn này, để mà chúng có thể bắt đầu tìm kiếm và tấn công người chơi. Nếu chúng ta dùng phương thức bỏ phiếu, những thực thể AI của chúng ta sẽ cần kiểm tra tình trạng của tất cả các thực thể AI khác, để biết về tai nạn này. Nhưng với một hệ thống thông điệp điều khiển theo sự kiện, chúng ta có thể bổ sung điều này vào một cách có thể quản lý và phát triển. Những nhân vật AI quan tâm một sự kiện riêng có thể được đăng ký như những thính giả. Những thực thể AI có thể tiếp tục để có những hành động thích hợp, hoặc thực hiện kiểm tra xa hơn.


Hệ thống điều khiển sự kiện không cung cấp máy móc nhanh hơn việc bỏ phiếu. Nhưng nó cung cấp một hệ thống kiểm tra thuận tiện, trung tâm, mà cảm nhận thế giới và thông tin cho các đặc vụ AI quan tâm, đỡ hơn mỗi cá nhân đặc vụ phải kiểm tra cùng một sự kiện trong mỗi hệ thống. Trong thực tế, cả hai việc bỏ phiếu và hệ thống thông điệp được dùng cùng với nhau hầu hết. Chẳng hạn, AI có thể bỏ phiếu để có nhiều thông tin khi nó nhận một sự kiện từ hệ thống thông điệp.

Thứ Ba, 5 tháng 11, 2013

Cookbook - Tùy biến hiệu ứng lens flare


  - Tùy biến hiệu ứng lens flare -

Với bất kì ai đã từng chơi các game có các cảnh quay ngoài trời đều có thể nói với bạn biết rằng hiệu ứng lens flare dùng để mô phỏng lại một chùm sáng trong góc nhìn của người chơi. Ngoài ra, nó còn được sử dụng rất nhiều trong các thể loại game khác nhau. Bài viết này sẽ hướng dẫn các bạn tùy chỉnh hiệu ứng sẵn có này trong Unity.

Chuẩn bị
my50mmflare.psd

Cách để làm
    B1. Nhấp chuột phải vào thẻ Project và chọn Import Package | Character Controller. Tiếp tục vào Import Package | Light Flares.

      B2. Tại thẻ Hierarchy, click chọn Creat | Directional Light.

        B3. Click chọn Main Camera trong thẻ Hierarchy và vào Component | Camera-Control | Mouse Look
          B4. Tại thẻ Project, truy cập vào Standard Assets | Light Flares | Sources, nhấp chuột chọn Sun và ấn Ctrl + D để nhân đôi đối tượng này lên rồi đặt tên thành mySun.


            B5. Nhấp chuột chọn mySun, tại thẻ Inspector click chuột vào texture có tên 50mmflare để hiển thị thư mục chứa file texture này.

              B6. Nhân đôi đối tượng này lên bằng cách ấn Ctrl + D, đổi tên thành My50mmflare và double click vào nó rồi dùng Photoshop để tùy biến hiệu ứng. Hoặc nếu không có Photoshop, bạn có thể load file đã down ở trên vào và sử dụng.

                B7. Tại thẻ Inspector, click chọn mySun và kéo thả file My50mmflare vào Flare Texture để điều chỉnh Flare Texture thành My50mmflare.

                  B8. Tại thẻ Hierarchy, click chọn Directional light và qua thẻ Inspector điều chỉnh Flare thành mySun.

                    B9. Nhấn nút Play để kiểm tra thành quả.