利用unity制作背包系統
首先介紹一下我自己,本人是個在讀大學生,正在學習unity,為加深自己印象,所以在CSDN上寫寫博客,歡迎大家來討論探討,也歡迎大佬指教,爭取大家都能獲得進步!
搭建UI
在網上找了點圖片并裁剪,搭建好了UI背包系統的界面
UI如下,注意設定好tag和父子物件關系以及布局,例如背包欄中需加入Grid Layout Group,

代碼部分
- 首先對每個格子添加tag:cell,并規定裝備欄中的cellltype分別為TouJia,Weapon,Shoes,Gloves,FangJu,ShiPin,背包欄中的格子celltype均為None,(利用列舉類)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public enum CellType
{
TouJia,
Weapon,
Shoes,
Gloves,
FangJu,
ShiPin,
None
}
public class Cell : MonoBehaviour
{
public CellType celltype;
}
將代碼掛載到每一個格子物件中
- 每一個裝備都需要設定tag為equip,掛載的代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class Equip : Cell, IBeginDragHandler, IDragHandler, IEndDragHandler
{
private GameObject Panel;
private Transform PreviousCell;
private GameObject Role;
public int Attack;
public int Defense;
public int Health;
public int Agile;
public int Lucky;
private void Awake()
{
Panel = GameObject.FindGameObjectWithTag("panel");
Role = GameObject.FindGameObjectWithTag("role");
}
public void OnBeginDrag(PointerEventData eventData)
{
//先暫時關閉拖動裝備的射線檢測,可以檢測到后方是格子,裝備還是其他
GetComponent<Image>().raycastTarget = false;
//標記拖動前的父物體,以便拖動不符合條件,回到原父物件
PreviousCell = transform.parent;
//將裝備的父物件設定為畫板,這樣就不會被其他東西壓住
transform.SetParent(Panel.transform);
}
public void OnDrag(PointerEventData eventData)
{
//裝備的位置隨滑鼠的位置而移動,實作拖拽效果
transform.position = Input.mousePosition;
}
/// <summary>
/// 只有兩種情況,從裝備欄中拖拽裝備和從背包欄中拖拽裝備,其他物件不支持拖拽
/// </summary>
/// <param name="裝備拖拽至什么地方"></param>
public void OnEndDrag(PointerEventData eventData)
{
//從背包欄中拖拽裝備
if (PreviousCell.parent.tag == "bag")
{
//裝備拖動后放入的是格子的情況,則格子接收裝備
if (eventData.pointerEnter.tag == "cell")
{
//放入的格子在背包中,則直接接收裝備
if (eventData.pointerEnter.transform.parent.tag == "bag")
{
Receive(eventData.pointerEnter.transform, this);
}
//放入的格子在裝備中,且裝備型別匹配,則接收裝備并更新屬性
else if (eventData.pointerEnter.transform.parent.tag == "currentequip" &&
eventData.pointerEnter.GetComponent<Cell>().celltype == GetComponent<Equip>().celltype)
{
Receive(eventData.pointerEnter.transform, this);
UpdateProperties1(this);
}
//其他情況,回到原位置
else
{
Receive(PreviousCell, this);
}
}
//裝備拖動后放入的是裝備的情況下,則裝備交換
else if (eventData.pointerEnter.tag == "equip")
{
//放入背包中的裝備上,則直接交換
if (eventData.pointerEnter.transform.parent.parent.tag == "bag")
{
Receive(eventData.pointerEnter.transform.parent, this);
Receive(PreviousCell, eventData.pointerEnter.GetComponent<Equip>());
}
//放入的是裝備中的裝備上,則交換并更新屬性
else if (eventData.pointerEnter.transform.parent.parent.tag == "currentequip" &&
eventData.pointerEnter.GetComponent<Equip>().celltype == GetComponent<Equip>().celltype)
{
Receive(eventData.pointerEnter.transform.parent, this);
Receive(PreviousCell, eventData.pointerEnter.GetComponent<Equip>());
UpdateProperties3(eventData.pointerEnter.GetComponent<Equip>(), this);
}
//其他情況,回到原位置
else
{
Receive(PreviousCell, this);
}
}
// 其他情況,則回到原位置
else
{
Receive(PreviousCell, this);
}
//將射線檢測重新設定為true,以便下次拖動
GetComponent<Image>().raycastTarget = true;
}
//從裝備欄中拖拽裝備
else if(PreviousCell.parent.tag == "currentequip")
{
//將裝備拖動至背包欄的格子中,則格子接收裝備,屬性減少
if (eventData.pointerEnter.tag == "cell" && eventData.pointerEnter.transform.parent.tag == "bag")
{
Receive(eventData.pointerEnter.transform, this);
UpdateProperties2(this);
}
//將裝備拖動至背包欄的裝備上,則交換裝備,先減去原裝備屬性,再加上新裝備屬性
else if(eventData.pointerEnter.tag == "equip" &&
GetComponent<Equip>().celltype == eventData.pointerEnter.GetComponent<Equip>().celltype)
{
Receive(eventData.pointerEnter.transform.parent, this);
Receive(PreviousCell, eventData.pointerEnter.GetComponent<Equip>());
UpdateProperties3(this, eventData.pointerEnter.GetComponent<Equip>());
}
//其他情況下,均回傳原來位置
else
{
Receive(PreviousCell, this);
}
//將射線檢測重新設定為true,以便下次拖動
GetComponent<Image>().raycastTarget = true;
}
}
//格子接收裝備
public void Receive(Transform cell, Equip equip)
{
equip.transform.SetParent(cell);
equip.transform.localPosition = Vector3.zero;
}
//穿上裝備屬性更新
private void UpdateProperties1(Equip equip)
{
Role.GetComponent<Properties>().EquipBonus(equip);
}
//卸載裝備屬性更新
private void UpdateProperties2(Equip equip)
{
Role.GetComponent<Properties>().EquipReduction(equip);
}
//更換裝備屬性更新
private void UpdateProperties3(Equip equip1, Equip equip2)
{
Role.GetComponent<Properties>().EquipReduction(equip1);
UpdateProperties1(equip2);
}
}
創建Equip類繼承Cell類,以便于裝備型別是否匹配,不然會出現頭甲裝備上武器這種混亂的情況,
裝備的屬性面板中的各個屬性設定為了public,可以自己來設定裝備的屬性了,

- 關于屬性的更新:既然要分別更新五個屬性,不如將屬性面板全部放在一個物件的子物件中,這里我選擇的是這張圖片,將其tag設定為role,以便更新屬性面板,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Properties : MonoBehaviour
{
private GameObject Attack;
private GameObject Defense;
private GameObject Health;
private GameObject Agile;
private GameObject Lucky;
private int attack;
private int defense;
private int health;
private int agile;
private int lucky;
private void Awake()
{
Attack = GameObject.FindGameObjectWithTag("attack");
Defense = GameObject.FindGameObjectWithTag("defense");
Health = GameObject.FindGameObjectWithTag("health");
Agile = GameObject.FindGameObjectWithTag("agile");
Lucky = GameObject.FindGameObjectWithTag("lucky");
attack =int.Parse(Attack.GetComponent<Text>().text);
defense = int.Parse(Defense.GetComponent<Text>().text);
health = int.Parse(Health.GetComponent<Text>().text);
agile = int.Parse(Agile.GetComponent<Text>().text);
lucky = int.Parse(Lucky.GetComponent<Text>().text);
}
/// <summary>
/// 穿上裝備的屬性增益
/// </summary>
/// <param name="帶裝備的裝備"></param>
public void EquipBonus(Equip equip)
{
attack += equip.GetComponent<Equip>().Attack;
defense += equip.GetComponent<Equip>().Defense;
health += equip.GetComponent<Equip>().Health;
agile += equip.GetComponent<Equip>().Agile;
lucky += equip.GetComponent<Equip>().Lucky;
//更新面板屬性
Attack.GetComponent<Text>().text = attack.ToString();
Defense.GetComponent<Text>().text = defense.ToString();
Health.GetComponent<Text>().text = health.ToString();
Agile.GetComponent<Text>().text = agile.ToString();
Lucky.GetComponent<Text>().text = lucky.ToString();
}
/// <summary>
/// 卸載裝備的屬性減少
/// </summary>
/// <param name="待卸載的裝備"></param>
public void EquipReduction(Equip equip)
{
attack -= equip.GetComponent<Equip>().Attack;
defense -= equip.GetComponent<Equip>().Defense;
health -= equip.GetComponent<Equip>().Health;
agile -= equip.GetComponent<Equip>().Agile;
lucky -= equip.GetComponent<Equip>().Lucky;
//更新面板屬性
Attack.GetComponent<Text>().text = attack.ToString();
Defense.GetComponent<Text>().text = defense.ToString();
Health.GetComponent<Text>().text = health.ToString();
Agile.GetComponent<Text>().text = agile.ToString();
Lucky.GetComponent<Text>().text = lucky.ToString();
}
}
總結
- 本來想用繼承來重寫方法,還是用了virtual虛方法,override重寫方法來顯示多型性的,結果寫了好幾次都不對,只能暫時放棄了,
- C#語言本身是哥面向物件的語言,而我寫的第二個裝備上的代碼有點過于面向程序了,導致判斷過多,還有很多重復代碼,這點還需要改進!
- 后期role需要一個3D建模,而不止是張圖片,應該穿上裝備要有顯示出穿上裝備的樣子,而不止是面板屬性的更新,這樣就需要改變畫布顯示的模式,讓2D面板和3D人物并存,以及利用鍵盤輸入或者easytouch實作人物旋轉效果,后期學習后會有添加的!
最后放幾張效果圖吧


歡迎各位大佬批評指正!!!謝謝!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/295029.html
標籤:其他
