此次任務是模仿上圖的樣子,製做一個相似的揹包系統。html
上面的連接爲:http://www.tasharen.com/ngui/exampleX.htmlcanvas
咱們的目標是:網絡
1.實現揹包系統的UI界面框架
2.實現物品的移動ui
最後的效果:this
界面沒有網頁上的效果好啦,可是基本實現了揹包系統。3d
下面是步驟:component
首先構建如上所示的揹包的基礎結構。orm
參考課程的例子,利用canvas實現揹包系統的框架,包含canvas,camera。 htm
首先新建一張canvas,設置render mode,render camera, UI scale mode,match。
新建一個camera 並設置 render camera。
而後在canvas裏面新建一個canvas,用於存儲裝備欄與揹包欄。
而後咱們在作具體實現揹包的格子。
再剛纔新建的canvas下,建立兩個panel,而且命名爲backpack與wear。分別用於存放裝備與揹包物品。而後分別添加Grid Layout Group的component, 以實現添加元素的自動對齊。
揹包中的格子我所有使用image實現。而後能夠添加一些text。
下面咱們須要添加一個背景和人物。
背景直接在百度上找了一張圖,人物在asset store上下載了一個卡通戰士的model。
添加背景咱們首先建立一個空對象,將main camera添加進去,而後再裏面添加一個空對象,並命名爲background,給他添加sprite render 的 component。
而後將咱們的想要的背景圖片直接拖入asset中,unity會將他自動生成sprite格式,素材的右邊會多出一個小的播放按鈕同樣的圖示就能夠了。
而後將其拖入sprite render中的sprite,material選擇sprite default。我以前沒有改爲default會有錯誤產生。
這樣子再修改修改圖片大小什麼的就差很少了。
而後是人物,就在asset store上下載了一我的物,而後拖入。調整一個位置與大小。
這裏還要注意咱們須要調整一下攝像機。一個負責看UI,一個看背景等其餘。
咱們只須要調整culling mask這個參數,裏面能夠勾選顯示的部分。而後就是這樣子了。
接着實現揹包拖放的功能。在subcanvas裏面新建一個對象樹,而後新建image來表示物品,存放咱們須要的物品。source image中放的是從網絡上找來的圖片素材來表示裝備。
最後一步,實現物品的拖放咱們主要是依靠代碼實現的,這裏咱們須要繼承IBeginDragHandler, IDragHandler, IEndDragHandler這三個接口,使用Unity自帶的Event Trigger檢測物品拖放的操做。
using UnityEngine; using System.Collections; using UnityEngine.EventSystems; using UnityEngine.UI; public class drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { private Transform transform_; private RectTransform rectTransform_; private CanvasGroup canvasG_; public Vector3 rootPosition; private GameObject lastE = null; private Color lastEcolor; private Color hcolor = Color.cyan; void Start() { transform_ = this.transform; rectTransform_ = this.transform as RectTransform; canvasG_ = GetComponent<CanvasGroup>(); rootPosition = transform_.position; //originalPosition = new Vector3(0, 0, 0); } void Update() { } public void OnBeginDrag(PointerEventData eventData) { canvasG_.blocksRaycasts = false;//event trigger忽略自身 lastE = eventData.pointerEnter; lastEcolor = lastE.GetComponent<Image>().color; rootPosition = transform_.position;//拖拽前記錄起始位置 gameObject.transform.SetAsLastSibling();//保證當前操做的對象可以優先渲染,即不會被其它對象遮擋住 } public void OnDrag(PointerEventData eventData) { Vector3 globalMousePos; if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform_, eventData.position, eventData.pressEventCamera, out globalMousePos)) { rectTransform_.position = globalMousePos; } GameObject curEnter = eventData.pointerEnter; bool inItemGrid = EnterItemGrid(curEnter); if (inItemGrid) { Image img = curEnter.GetComponent<Image>(); lastE.GetComponent<Image>().color = lastEcolor; if (lastE != curEnter) { lastE.GetComponent<Image>().color = lastEcolor; lastE = curEnter;//記錄當前物品格子以供下一幀調用 } //當前格子設置高亮 img.color = hcolor; } } public void OnEndDrag(PointerEventData eventData) { GameObject curEnter = eventData.pointerEnter; //拖拽到的空區域中(如包裹外),恢復原位 if (curEnter == null) { transform_.position = rootPosition; } else { //移動至物品格子上 if (curEnter.name == "Image") { transform_.position = curEnter.transform.position; rootPosition = transform_.position; curEnter.GetComponent<Image>().color = lastEcolor;//當前格子恢復正常顏色 } else { //移動至包裹中的其它物品上 if (curEnter.name == eventData.pointerDrag.name && curEnter != eventData.pointerDrag) { Vector3 targetPostion = curEnter.transform.position; curEnter.transform.position = rootPosition; transform_.position = targetPostion; rootPosition = transform_.position; } else//拖拽至其它對象上面(包裹上的其它區域) { transform_.position = rootPosition; } } } lastE.GetComponent<Image>().color = lastEcolor;//上一幀的格子恢復正常顏色 canvasG_.blocksRaycasts = true;//確保event trigger下次能檢測到當前對象 } bool EnterItemGrid(GameObject Obj) { if (Obj == null) { return false; } return Obj.name == "Image"; } }