1. 程式人生 > >即時戰略遊戲Unity實現(一)單位選擇

即時戰略遊戲Unity實現(一)單位選擇

本人非常喜歡各種遊戲,尤其是即時戰略遊戲(如星際爭霸,war3等)以及仙俠類的單機遊戲,現在自學遊戲製作,希望有一天能製作出一款自己心中的遊戲。

今天突然想寫點東西,把自己的學習過程記錄下來。

從即時戰略遊戲的研究開始吧- -

我們從單位的選擇上開始,即時戰略遊戲裡單位的選擇通常有以下幾個特點:

1. 滑鼠左鍵點選單選;

2. Shift加選;

3. 框選多個單位;

4. 雙擊一個單位,同類型單位會被全部選中;

5. 被選中的單位會出現選擇圈;

下面讓我們先試著實現這幾個功能吧!

感覺鄙人功力有些不夠,先實現前兩個吧~~

首先,我們要有一張選擇圈的圖片,如圖:

用ps就能完成

將這張圖片(PNG或PSD格式,必需有透明通道)匯入到unity中,設定為圖片精靈(Sprite)。

然後我們利用UGUI開始製作選擇圈。

在場景中建立一個UI→slider,只保留slider的背景,其他的全刪掉(其實就是一張image- -,有點多此一舉),並將選擇圈sprite賦值給backGround的SourceImage,如圖:

將Canvas作為sphere(我們準備選擇的單位)的子物體。

將canvas的isActive選框勾選掉,即預設不顯示;可以將球體做成預製體並在場景中多放幾個

下面開始程式碼部分:

我們首先給sphere新增一個標籤(Unit),並給Sphere新增指令碼,名為WasSelected,該指令碼非常簡單,只有一個公有bool變數

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

public class WasSelected : MonoBehaviour
{
    public bool wasSelected = false;
}

該變數ch初始設定為false;

在場景中建立一個空物體,名為ChooseUnit,同時新增一個同名的指令碼(指令碼名自定義);

using UnityEngine;


public class ChooseUnit : MonoBehaviour
{

    public static ChooseUnit _instance;//做成單例
    private void Awake()
    {
        _instance = this;
    }


    private Transform curSelectedOne;//單選變數

    /// <summary>
    /// 顯示選擇圈
    /// </summary>
    /// <param name="go"></param>
    void Active(Transform go)
    {
        go.gameObject.SetActive(true);
    }
    /// <summary>
    /// 隱藏選擇圈
    /// </summary>
    /// <param name="go"></param>
    void DeActive(Transform go)
    {
        go.gameObject.SetActive(false);
    }
    /// <summary>
    /// 檢測點選事件
    /// </summary>
    private void Update()
    {

        if (Input.GetMouseButtonDown(0) && Input.GetKey(KeyCode.LeftShift))
        {
            ShiftMultiSelect();//呼叫shift連選
        }
        else if (Input.GetMouseButtonDown(0))
        {
            SelectOne();//單選
        }
    }
    /// <summary>
    /// 單擊滑鼠左鍵點選一個單位
    /// </summary>
    void SelectOne()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;//發射射線檢測與物體的碰撞
        if (Physics.Raycast(ray, out hitInfo))
        {
            //Debug.Log("2");
            if (hitInfo.collider.gameObject.tag == "Unit")//物體必須有Unit標籤才能被選中
            {
                Transform circle = hitInfo.collider.transform.Find("Canvas");//選擇圈臨時變數
                if (curSelectedOne != null)//如果當前選擇單位
                {
                    if (circle != curSelectedOne)//如果當前選擇單位!=前一個單位
                    {
                        DeActive(curSelectedOne);//關閉前一個單位的顯示
                        Active(circle);//顯示當前單位
                        curSelectedOne = circle;
                    }
                }
                else
                {
                    curSelectedOne = circle;
                    Active(circle);
                }
                //Debug.Log("3");
                //Debug.Log(circle.name.ToString());
            }
        }
    }

    /// <summary>
    /// shift+滑鼠點選加選單位
    /// </summary>
    void ShiftMultiSelect()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;
        if (Physics.Raycast(ray, out hitInfo))
        {
            if (hitInfo.collider.gameObject.tag == "Unit")
            {
                hitInfo.collider.GetComponent<WasSelected>().wasSelected = !hitInfo.collider.GetComponent<WasSelected>().wasSelected;//對被選擇單位的wasSelected變數取反
                if (hitInfo.collider.GetComponent<WasSelected>().wasSelected == true)//若是true則顯示,else關閉顯示;
                {
                    Transform circle = hitInfo.collider.transform.Find("Canvas");
                    Active(circle);
                }
                else
                {
                    Transform circle = hitInfo.collider.transform.Find("Canvas");
                    DeActive(circle);
                }
            }

        }
    }



}

這樣就完成了單選和shift加選顯示選擇圈的功能了。

實際上,在單選的方法裡使用單位本身的bool變數判斷更好。

歡迎各位大佬批評指正!