5/08/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.

2 comments:

  1. anh nên giải thích chỗ này dùng cái này để làm gì để cho ng học có thể dễ hiểu hơn ạ. em chỉ góp ý thế thôi

    ReplyDelete
  2. em thấy toàn code nhưng không hiểu, anh nên giải thích luôn sau phần code ạ

    ReplyDelete