這一次背包系統很大程度上是參考這個博客進行制作,這篇博客寫得很詳盡很好,我相對來說增添了一些這里面沒有貼出來的細節,大家可以參照着這一篇一起把游戲背包制作出來
http://blog.csdn.net/qq_20496459/article/details/51421360
任務
參考 http://www.tasharen.com/ngui/exampleX.html ,使用 UI 制作背包系統(武器裝備系統)
看這個參考需要使用到unity web player,在舊版瀏覽器或者IE瀏覽器上可以下載unity web player使用查看
前提學習
這一次作業與前面學習到的知識:camera的使用、多camera的場景、newUI使用息息相關,所以需要先將這些基礎知識了解,這里就貼一個camera的unity官方文檔,其他的大家可以自己去查詢;
http://wiki.ceeger.com/script/unityengine/classes/camera/camera?s[]=camera
制作效果
我的制作效果就沒有參考的那么炫酷厲害了,不過基本的要求基本上都達到了~
制作過程
UI層的制作
可以看到,Scene是我的UI層,利用UI Camera渲染呈現,而UI層中存在的東西有:一張畫布(UI panel)即scene,然后下面再有一張子畫布,畫布下有裝備欄還有背包欄,也是UI panel;
而在Bag和Equipment畫布下是一個一個UI button,能夠得到想要的效果,其中Mouse_Image是用以展示貼到鼠標上的圖片,這個在后面還會進行解釋;
其中,裝備欄和背包欄使用了Grid Layout Group組件,便於分格:
上圖是Bag的組件設置,Equipment的類似;
其中注意所有的UI Camera渲染的都是UI層的,並且深度設置為介於Main Camera的層和Hero Camera的層之間,主要是因為我的UI層是起着遮擋Main Camera顯示以及在其表面加上兩個欄的作用,然后我們要先渲染Hero,防止Hero被遮擋;
UI Camera的組件設置如下:
將UI層布置好之后就緊接着開始布置SF Scene Element了;
SF Scene Element
這一層很簡單,主要就是來放背景圖片,然后再加一個粒子系統:
從Main Camera的預覽圖可以看到這就是我們這一層所要達到的效果;
我們只要把圖片放在Background里面,然后加一個Particle System制造出一個神秘的背景即可;
這里需要注意的是,圖片需要設置為Sprite才能夠放入image組件中:
在這里MainCamera的組件設置如下,它的深度為最低的一個,因為它需要放在其他的后面,制造出一種虛幻的效果:
粒子系統,自然簡單一點就好,不需要修改太多;
主角
主角我是從Asset Store中下載來的,從Asset Store中一搜人物模型,竟然就搜到跟參考博客一樣的模型,提供一下鏈接給大家:
https://www.assetstore.unity3d.com/cn/#!/content/44041
其實還有很多很不錯的資源,比如我看到有骷顱人、小野人等等;
是不是感覺這人物怎么放的這么奇怪,對的,人物是放在了圖片和UI的背后,然后相機也在這背后,因為這一層只是需要渲染出人物這一個模型即可,其他的層放在那兒都是干擾,所以就直接放在這里,便於Hero Camera的渲染;
其中,大家可以通過切換成3D來看到這個視圖,前面兩個我都是用2D視圖的;
Hero Camera的組件設置如下:
這樣,通過三個camera就將最終需要的場景給渲染出來了,是不是很不錯~!
接下來,就應該讓那些裝備欄里面的物體能夠被移動,以及畫布隨着鼠標的變化而變化了~!
代碼編寫
首先利用了上課給的一個scripts,能夠讓畫布跟隨着鼠標變化:
1 using UnityEngine; 2 3 public class TiltWindows : MonoBehaviour 4 { 5 public Vector2 range = new Vector2(5f, 3f); 6 7 Transform mTrans; 8 Quaternion mStart; 9 Vector2 mRot = Vector2.zero; 10 11 void Start () 12 { 13 mTrans = transform; 14 mStart = mTrans.localRotation; 15 } 16 17 void Update () 18 { 19 Vector3 pos = Input.mousePosition; 20 21 float halfWidth = Screen.width * 0.5f; 22 float halfHeight = Screen.height * 0.5f; 23 float x = Mathf.Clamp((pos.x - halfWidth) / halfWidth, -1f, 1f); 24 float y = Mathf.Clamp((pos.y - halfHeight) / halfHeight, -1f, 1f); 25 mRot = Vector2.Lerp(mRot, new Vector2(x, y), Time.deltaTime * 5f); 26 27 mTrans.localRotation = mStart * Quaternion.Euler(-mRot.y * range.y, mRot.x * range.x, 0f); 28 } 29 }
接着,創建一個空對象並命名為Manager,在其下掛載Game_Manager代碼,Game manager利用實例化,可用來聯系各個類,並且能夠讓其他類很方便地使用它里面的函數:
1 using UnityEngine; 2 using System.Collections; 3 using Game_Manager; 4 5 namespace Game_Manager { 6 7 public class Game_Scene_Manager : System.Object { 8 private static Game_Scene_Manager _instance; 9 private static Mouse_Image _Mouse; 10 private int IsHair = 0; // 是否頭部有裝備 11 private int IsWeapon = 0; // 是否有武器裝備 12 private int IsFoot = 0; // 是否有腳部裝備 13 14 public static Game_Scene_Manager GetInstance() { 15 if (_instance == null) { 16 _instance = new Game_Scene_Manager(); 17 } 18 return _instance; 19 } 20 21 public void SetMouse(Mouse_Image _mouse) { 22 if (_Mouse == null) { 23 _Mouse = _mouse; 24 } 25 } 26 27 public Mouse_Image GetMouse() { 28 return _Mouse; 29 } 30 31 public void GenAll() { 32 IsFoot = 1; 33 IsHair = 1; 34 IsWeapon = 1; 35 } 36 37 public int GetHair() { return IsHair; } 38 public int GetWeapon() { return IsWeapon; } 39 public int GetFoot() { return IsFoot; } 40 41 public void SetHair(int a) { IsHair = a; } 42 public void SetWeapon(int a) { IsWeapon = a; } 43 public void SetFoot(int a) { IsFoot = a; } 44 } 45 46 } 47 48 public class Mouse : MonoBehaviour { 49 // Use this for initialization 50 void Start () { 51 52 } 53 54 // Update is called once per frame 55 void Update () { 56 57 } 58 }
還記得我們在UI層里面創建了一個Mouse_Image嗎?它就是為了實現點擊圖片時,圖片跟隨鼠標移動的效果的,當鼠標點擊一個背包欄,進行判定能夠將圖片移動后,圖片會放入Mouse_Image中,Mouse_Image跟隨着鼠標移動,因此就實現了這樣的效果,其中Mouse_Image是UI Image類,需要在Mouse_Image下掛上這一個代碼:
1 using UnityEngine; 2 using System.Collections; 3 using Game_Manager; 4 using UnityEngine.UI; 5 6 public class Mouse_Image : MonoBehaviour { 7 8 private Game_Scene_Manager gsm; 9 private Image mouse_image; 10 private int mouse_type = 0; 11 public Sprite none; 12 public Sprite hair; // 保存相應的裝備 13 public Sprite weapon; // 保存相應的裝備 14 public Sprite foot; // 保存相應的裝備 15 public Color None; 16 public Color NotNone; 17 public Camera cam; 18 19 void Awake() { 20 gsm = Game_Scene_Manager.GetInstance(); 21 gsm.SetMouse(this); 22 mouse_image = GetComponent<Image>(); 23 } 24 25 public int GetMouseType() { 26 return mouse_type; 27 } 28 29 public void SetMouseType(int Mouse_type) { 30 mouse_type = Mouse_type; 31 } 32 33 void Update () { 34 if (mouse_type == 0) // 每一幀進行更新,檢查鼠標上是否需要有裝備,根據mousetype更新,如果mousetype為0則裝備無 35 { 36 mouse_image.sprite = none; 37 mouse_image.color = None; 38 } 39 else 40 { // mousetype不為零,根據mousetype加上相應裝備 41 //Debug.Log("I am mouse image"); 42 //Debug.Log(mouse_type); 43 44 mouse_image.color = new Color(1F, 1F, 1F, 1F); 45 //Debug.Log(mouse_image.color); 46 if (mouse_type == 1) mouse_image.sprite = hair; 47 else if (mouse_type == 2) mouse_image.sprite = weapon; 48 else if (mouse_type == 3) mouse_image.sprite = foot; 49 } 50 transform.position = new Vector3 (Input.mousePosition.x-600, Input.mousePosition.y-230, 0); 51 } 52 }
接下來就是背包欄的每一格點擊會發生的事件了,若有裝備在背包欄中,要么能夠讓裝備轉移到鼠標上,要么鼠標上已經有了圖片,不能移動;若沒有裝備在此格中,則點擊此格,如果鼠標上有裝備,那么裝備會放入背包欄中,如果鼠標上沒有,那么什么也不發生,因此我們可以給背包欄的每一個格即UI Button添加一個script,裝備欄也類似,不過裝備欄中的每個格確定了裝備應該是什么類型的;
using UnityEngine; using System.Collections; using UnityEngine.UI; using Game_Manager; public class MyBag : MonoBehaviour { private Game_Scene_Manager gsm; private Image bag_image; public int mouse_type = 0; // 0->沒有裝備,1...有不同裝備 public Sprite hair; public Sprite weapon; public Sprite foot; public Sprite UISprite; public Color weapon_color; public Color UISprite_color; void Awake() { gsm = Game_Scene_Manager.GetInstance(); bag_image = GetComponent<Image>(); } public void On_equip_Button() { Debug.Log("my bag click!"); int MouseType = gsm.GetMouse().GetMouseType(); // 得到鼠標目前的mousetype if (bag_image.sprite != UISprite && MouseType == 0) // 若鼠標沒有圖片在上面,並且bag的image不為空有裝備,則取走bag_image的裝備 { Debug.Log(mouse_type); bag_image.sprite = UISprite; bag_image.color = UISprite_color; gsm.GetMouse().SetMouseType(mouse_type); // 將當前裝備的type給鼠標 mouse_type = 0; // 此背包的mousetype變為0,則當前背包啥都沒有 } else { // 若鼠標上有裝備,則改背包的image sprite改變,根據type變為不同裝備圖片 Debug.Log("my bag equipped!"); if (MouseType == 1) bag_image.sprite = hair; else if (MouseType == 2) bag_image.sprite = weapon; else if (MouseType == 3) bag_image.sprite = foot; mouse_type = MouseType; // mousetype變為鼠標的mousetype bag_image.color = weapon_color; // 有裝備了 gsm.GetMouse().SetMouseType(0); // 鼠標裝備消失 } } }
上面是掛在bag的每一個Button上面的,其中bag中的組件設置,以及對這個script的變量設置要注意,我在這里就遇到了幾個問題,其中weapon_color不要設置成為透明了,否則我們將裝備移動的效果就看不到了,由於我的button是有顏色的,所以我的UISprite_color也不能夠透明,需要跟原本的顏色一致;
然后hair,weapon,foot這些記得依次根據自己的賦值,這些是當mouse_type改變時,這個格子中會放入的裝備,以一個bag button設置為示例,其他都類似:
其中,點擊事件不要忘記添加,每一個需要將自己函數里面寫的點擊事件添加進去;
然后裝備欄的代碼如下:
1 using UnityEngine; 2 using System.Collections; 3 using UnityEngine.UI; 4 using Game_Manager; 5 6 public class equip : MonoBehaviour { 7 8 private Game_Scene_Manager gsm; 9 private Image equip_image; 10 public int mouse_type; 11 public Sprite weapon; // 為此背包中相應的裝備 12 public Sprite UISprite; 13 public Color weapon_color; 14 public Color UISprite_color; 15 16 void Awake() 17 { 18 gsm = Game_Scene_Manager.GetInstance(); 19 equip_image = GetComponent<Image>(); 20 } 21 22 public void On_equip_Button() { 23 Debug.Log("equip click"); 24 int MouseType = gsm.GetMouse().GetMouseType(); // 得到鼠標上的mousetype 25 if (equip_image.sprite == weapon && MouseType == 0) // 取走裝備區裝備,當裝備區含有裝備並且mousetype=0鼠標上沒有裝備 26 { 27 equip_image.sprite = UISprite; 28 equip_image.color = UISprite_color; 29 gsm.GetMouse().SetMouseType(mouse_type); 30 } 31 else 32 { 33 // 只有相同各類型的裝備能夠放到相應的裝備區,並且不能夠重復裝備 34 if (mouse_type == MouseType && equip_image.sprite != weapon) { 35 // 將裝備佩戴到裝備區中 36 equip_image.sprite = weapon; 37 equip_image.color = weapon_color; 38 mouse_type = MouseType; 39 gsm.GetMouse().SetMouseType(0); 40 } 41 } 42 } 43 44 // Use this for initialization 45 void Start () { 46 47 } 48 49 // Update is called once per frame 50 void Update () { 51 // 防止重復裝備 52 if (mouse_type == 1 && gsm.GetHair() == 1) 53 { 54 Debug.Log("mouse_type"); 55 gsm.SetHair(0); // 已裝備頭部不能夠再裝備頭部 56 equip_image.sprite = weapon; 57 equip_image.color = weapon_color; 58 } else if (mouse_type == 2 && gsm.GetWeapon() == 1) 59 { 60 gsm.SetWeapon(0); // 已裝備武器不能夠再裝備武器 61 equip_image.sprite = weapon; 62 equip_image.color = weapon_color; 63 } else if (mouse_type == 3 && gsm.GetFoot() == 1) 64 { 65 gsm.SetFoot(0); // 已裝備腳部 66 equip_image.sprite = weapon; 67 equip_image.color = weapon_color; 68 } 69 } 70 }
基本上和背包欄類似,但是由於裝備欄每一個格只會裝一個類型的,並且不能夠重復裝,所以多了一些判斷,又少了一些變量;
其中以一個裝備欄設置為例,其他類似:
最后,所有的代碼完成,掛上去,最終就得到了想要的效果啦~
還有,在裝備欄裝上裝備后,自己可以做一個動畫,人物穿上某一個盔甲,或者拿上一把劍等等,並且將動畫按照裝備分類分別添加,就能夠展現出簡單的穿戴裝備的效果了~!
總結
這一次通過制作游戲背包發現之前的很多知識都沒有掌握透徹,比如多camera如何渲染場景,其實這些也不是什么難的知識,只是自己沒有用心,以后一定要多用心去學習!
然后還是有一些自己想要完成的沒有完成,比如穿戴劍、刀、弓箭、衣服、戰靴等等,由於現在的代碼寫的有限制,每種類型的裝備就只產生一個穿戴的效果,不過應該實現起來也不會很難,以后有時間再去實現~