3/11/2014

COOKBOOK - HIỂN THỊ RADAR


 

Radar hiển thị các đối tượng khác liên quan đến người chơi, thông thường radar sẽ là hình tròn và tâm của nó là nơi player đang đứng, và mỗi chấm tròn trên radar tượng trưng cho các đối tượng khác. Radar tinh vi sẽ hiển thị các chấm tròn khác nhau với từng loại đối tượng.


Chuẩn bị
Radar.rar

Cách để làm

B1. Tại thẻ Hierarchy, nhấp chọn nút Create | Directional Light. Qua thẻ Inspector, điều chỉnh như sau:



B2. Tiếp tục nhấp chọn nút Create | Terrain và điều chỉnh ở thẻ Inspector như sau:


B3. Vào Assets | Import Package | Character Controller và nhấp nút Import. Tại thẻ Project, kéo thả 3rd Person Controller vào thẻ Hierarchy. Qua thẻ Inspector, điều chỉnh Position thành X = 0, Y = 1, Z = 0.

 

B4.  Tại thẻ Hierarchy, nhấp chọn nút Create | Cube. Qua thẻ Inspector, điều chỉnh Position thành X = 0, Y = 1, Z = 5.


B5. Vẫn đang chọn Cube, ở thẻ Inspector, bấm chọn thanh sổ phía sau Tag và chọn Add Tag. Nhập vào Size Element 0 là cube.



B6. Nhấp chọn cube ở thẻ Hierarchy, qua thẻ Inspector, đặt tag là cube.


B7. Tại thẻ Hierarchy, nhấp chọn Create | Cube. Qua thẻ Inspector, điều chỉnh Position thành X = -5, Y = 1, Z = 0. Và đặt tag là cube.


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

using UnityEngine;
using System.Collections;

public class Radar : MonoBehaviour
{
    const float MAX_DISTANCE = 20f;
    const int RADAR_SIZE = 128;
   
    public Transform playerController;
    public Texture radarBackground;
    public Texture targetBlip;
   
    private void OnGUI()
    {
        // background displaying top left in square of 128 pixels
        Rect radarBackgroundRect = new Rect(0,0, RADAR_SIZE, RADAR_SIZE);
        GUI.DrawTexture(radarBackgroundRect,radarBackground);
       
        // find all 'cube' tagged objects
        GameObject[] cubeGOArray = GameObject.FindGameObjectsWithTag("cube");
       
        // draw blips for all within distance
        Vector3 playerPos = playerController.transform.position;
        foreach (GameObject cubeGO in cubeGOArray) 
        {
            Vector3 targetPos = cubeGO.transform.position;
            float distanceToTarget = Vector3.Distance(targetPos,playerPos);
            if( (distanceToTarget <= MAX_DISTANCE) )
                DrawBlip(playerPos, targetPos, distanceToTarget);
        }
    }
   
    private void DrawBlip(Vector3 playerPos, Vector3 targetPos, float distanceToTarget)
    {
        // distance from target to player
        float dx =  targetPos.x - playerPos.x;
        float dz =  targetPos.z - playerPos.z;
       
        // find angle from player to target
        float angleToTarget = Mathf.Atan2(dx,dz) * Mathf.Rad2Deg;
       
        // direction player facing
        float anglePlayer = playerController.eulerAngles.y;
       
        // subtract player angle, to get relative angle to object
        // subtract 90
        // (so 0 degrees (same direction as player) is UP)
        float angleRadarDegrees =  angleToTarget - anglePlayer - 90;
       
        // calculate (x,y) position given angle and distance
        float normalisedDistance = distanceToTarget / MAX_DISTANCE;   
        float angleRadians = angleRadarDegrees * Mathf.Deg2Rad;
        float blipX = normalisedDistance * Mathf.Cos(angleRadians);
        float blipY = normalisedDistance * Mathf.Sin(angleRadians);   
       
        // scale blip position according to radar size
        blipX *= RADAR_SIZE/2;
        blipY *= RADAR_SIZE/2;
       
        // offset blip position relative to radar center (64,64)
        blipX += RADAR_SIZE/2;
        blipY += RADAR_SIZE/2;
       
        // draw target texture at calculated location
        Rect blipRect = new Rect(blipX - 5, blipY - 5, 10, 10);
        GUI.DrawTexture(blipRect, targetBlip);       
    }
}


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

B10. Nhấp chọn Main Camera, qua thẻ Inspector, điều chỉnh các mục trong Radar (Script) như hình sau:



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


Nguyên lí làm việc

Hai hằng số được định nghĩa trong đoạn code:
  • MAX_DISTANCE: Khoảng cách xa nhất mà radar có thể phát hiện được đối tượng và hiển thị lên màn hình radar.
  • RADAR_SIZE: Kích thước (Đơn vị là px) của radar sẽ hiển thị lên màn hình.

Class Radar (file C# Radar) có 3 biến public:
  • Biến đầu tiên là để chỉ tâm của radar sẽ được đặt, ở đây là hiển thị tâm tại chỗ đứng của người chơi.
  • 2 biến còn lại là hình ảnh của màn hình radar và điểm nút chỉ đối tượng khác trong game sẽ được hiển thị trên màn hình radar.

Trong hàm onGUI( ), sẽ hiển thị hình nền của màn hình radar. Một mảng GameObject với các đối tượng được đặt tag sẽ được duyệt qua. Với mỗi phần tử trong mảng, nếu khoảng cách của chúng nằm trong khoảng nhỏ hơn MAX_DISTANCE thì hàm DrawBlip( ) sẽ được gọi.

Hàm DrawBlip( ) sẽ tìm tọa độ x và z của đối tượng và người chơi để tính toán khoảng cách từ tâm đến đối tượng thông qua hàm lượng giác Atan2( ) của Unity. Hướng nhìn của người chơi được xác định bởi trục Y và việc phải trừ góc quay đi 90 đều tương tự như ở bài viết Hiển thị la bàn.


Còn nữa

Hiển thị các đối tượng với màu khác nhau trên radar.
Chèn thêm các biến Texture vào trong hàm DrawBlip( ) với mỗi biểu tượng khác nhau cho từng đối tượng khác nhau. Các biến này sẽ sử dụng trong hàm GUI.DrawTexture. Điều này cho phép hàm DrawBlip( ) sẽ được gọi với các vòng lặp khác nhau cho từng đối tượng được gắn tag khác nhau.

No comments:

Post a Comment