Unity進階技巧 - 動態創建UGUI


前言

項目中有功能需要在代碼中動態創建UGUI對象,但是在網上搜索了很久都沒有找到類似的教程,最后終於在官方文檔中找到了方法,趁着記憶猶新,寫下動態創建UGUI的方法,供需要的朋友參考

你將學到什么?

  • 如何設置UI的縮放模式和尺寸
  • 如何添加UI動畫效果
  • 如何使用Button的基本響應事件
  • 如何動態創建UGUI對象

一、新建一個Test項目

首先我們新建一個名為Test的項目來實踐我們這次的內容,項目創建成功后,我們新建一個Button對象,如下圖:


新建Button對象

新的UGUI全部都基於一個Canvas畫布,如果你的場景里面沒有Canvas,當你創建一個UI對象時,編輯器會自動幫你創建一個Canvas


編輯器自動創建的Canvas

然后我們設置一下Cavans的縮放模式和尺寸,本例中我們以iPhone6的尺寸大小為准,我們選中Canvas,然后在其Canvas Scaler組件中,修改Ui Scale ModeScale With Screen Size,然后將
分辨率設置為750*1334


設置Cavans的縮放模式和尺寸

二、設置Button屬性

然后我們將Button的位置調整至屏幕的右上方,然后將字體大小放大,文本內容修改為點我(這邊大小和文本內容可以根據自己的喜好來調整)


將Button調整到右上方

三、動態創建UGUI對象的原理說明

在開始下面的內容之前,先在這邊講解一下動態創建UGUI對象的原理,我們看看Unity官方文檔的介紹說明:(懶得看到大段文字的朋友可以直接跳過這段,看后面的簡單說明)

Creating UI elements from scripting
If you are creating a dynamic UI where UI elements appear, disappear, or change based on user actions or other actions in the game, you may need to make a script that instantiates new UI elements based on custom logic.
Creating a prefab of the UI element
In order to be able to easily instantiate UI elements dynamically, the first step is to create a prefab for the type of UI element that you want to be able to instantiate. Set up the UI element the way you want it to look in the Scene, and then drag the element into the Project View to make it into a prefab.
For example, a prefab for a button could be a Game Object with a Image component and a Button component, and a child Game Object with a Text component. Your setup might be different depending on your needs.
You might wonder why we don’t have a API methods to create the various types of controls, including visuals and everything. The reason is that there are an infinite number of way e.g. a button could be setup. Does it use an image, text, or both? Maybe even multiple images? What is the text font, color, font size, and alignment? What sprite or sprites should the image use? By letting you make a prefab and instantiate that, you can set it up exactly the way you want. And if you later want to change the look and feel of your UI you can just change the prefab and then it will be reflected in your UI, including the dynamically created UI.
Instantiating the UI element
Prefabs of UI elements are instantiated as normal using the Instantiate method. When setting the parent of the instantiated UI element, it’s recommended to do it using the Transform.SetParent method with the worldPositionStays parameter set to false.
Positioning the UI element
A UI Element is normally positioned using its Rect Transform. If the UI Element is a child of a Layout Group it will be automatically positioned and the positioning step can be skipped.
When positioning a Rect Transform it’s useful to first determine it has or should have any stretching behavior or not. Stretching behavior happens when the anchorMin and anchorMax properties are not identical.
For a non-stretching Rect Transform, the position is set most easily by setting the anchoredPosition and the sizeDelta properties. The anchoredPosition specifies the position of the pivot relative to the anchors. The sizeDelta is just the same as the size when there’s no stretching.
For a stretching Rect Transform, it can be simpler to set the position using the offsetMin and offsetMax properties. The offsetMin property specifies the corner of the lower left corner of the rect relative to the lower left anchor. The offsetMax property specifies the corner of the upper right corner of the rect relative to the upper right anchor.
Customizing the UI Element
If you are instantiating multiple UI elements dynamically, it’s unlikely that you’ll want them all to look the same and do the same. Whether it’s buttons in a menu, items in an inventory, or something else, you’ll likely want the individual items to have different text or images and to do different things when interacted with.
This is done by getting the various components and changing their properties. See the scripting reference for the Image and Text components, and for how to work with UnityEvents from scripting.

動態創建UGUI對象的方法,簡單來說就是將我們需要創建的UGUI對象制作成一個Prefab,然后使用Instantiate方法將其實例化,最后使用相關的API對其屬性進行動態設置

四、制作自定義的Text Prefab

接下來我們就來創建自定義的Text Prefab,為動態創建做准備,首先我們會自定義一個如下圖所示的Text:


Text效果圖

我們來看看這個自定義的Text有哪些內容:

  • 字體的顏色是紅色
  • Text穿創建后會播放一段放大動畫
  • 放大動畫播放結束后,Text會向上移動一段距離
  • 移動結束后,Text就會消失掉

1、設置MyText屬性

清楚了Text所需的內容后,我們首先來新建一個Text對象,並且命名為MyText


新建Text對象

然后我們重置MyText的Rect Transform,重置之后將其寬高分別設置為750和100,接着我們將MyText的字體大小設置為40,顏色設置為紅色,然后將對其方式設置為居中:


設置MyText寬高

設置MyText字體屬性

2、為Text添加放大動畫

MyText的位置和字體屬性我們已經設置好了,接下來我們就需要為MyText增加放大和上升兩個動畫效果了,首先我們選中MyText,然后打開Animation編輯器(Mac版可以使用⌘+6的快捷鍵打開)


打開 Animation編輯器

然后在Animation編輯器中,點擊Create按鈕,新建一個動畫


新建一個動畫

當我們點擊Create按鈕后,編輯器會彈出一個對話框,我們需要指定新建的Animation的文件名和存放路徑,這里我們第一個需要制作的動畫是字體出現是的放大效果,所以我們將其命名為Appear,然后為了使資源方便管理,我們將所有的動畫資源放入到_Animator的文件夾下面(需要大家自己創建文件夾,關於如何創建可以參見以前的教程)


新建Animation對話框

創建成功后,我們會發現除了我們自己創建的Appear文件,編輯器還自動創建了一個名為MyTextAnimator Controller文件,如下圖,根據文件類型名字就可以看出,這個文件是用來控制和管理我們Appear這類文件的,像我們需要實現的Text出現后播放放大動畫,然后再播放上升動畫,這一個過程和邏輯就是通過Animator Controller來實現的,后面我們會講到


Animator Controller文件

接下來我們回到Animation編輯器里面,在這個里面我們可以對MyText對象的一個屬性進行動態變化,從而形成動畫效果,Unity對每個對象可以操控的屬性變量都列舉出來了,這里我們以Text對象來舉例,我們點擊Add Property按鈕,會彈出下級菜單,我們在菜單中可以看到能夠操作的屬性變量有3大類:

  • Rect Transform:該類是針對Rect Transform組件的屬性進行變化,我們可以改變這些屬性來實現對象大小的變化,或者位置的移動等
  • Text:該類是針對Text組件的屬性進行變化,我們可以改變這些屬性來實現諸如字體顏色變化,字體顯示與否等變化
  • Animator:該類是對Animator組件的屬性進行變化

Add Property按鈕

為了實現MyText出現后放大的效果,我們添加Scale屬性的變化,由於我們的UI其實是一個平面,對其大小能夠產生視覺變化的只有X和Y軸的變化,然后我們在本例中,希望放大效果一共播放0.5秒,其中在0.25秒是MyText放大到1.5倍,所以我們在0.25秒的時候添加一個關鍵幀,然后將結束的關鍵幀拖拽至0.5秒處,如下圖:


添加關鍵幀

接着我們選中0.25秒的關鍵幀,將該幀的Scale.x和Scale.y都設置為1.5


設置縮放變化

接着我們就可以點擊Animation編輯器里面的播放按鈕,來測試一下動畫效果了


動畫效果

放大的動畫就做好了,接下里我們繼續制作上升的動畫效果

3、為Text添加上升動畫

首先我們點擊Appear按鈕,然后選擇Create New Clip...,為MyText添加一個新的動畫文件:


新建一個動畫文件

同樣的在彈出的新建對話框中,我們將動畫文件的名字命名為UpRight,存放在_Animator文件夾下面:


新建對話框

接着我們在UpRight動畫中添加Anchored Position變化:


添加 Anchored Position變化

上升動畫在本例中,我們希望他能持續1秒,並且上升100個像素,所以我們選中結束的關鍵幀,在將其Position.y的值設置為100:


Paste_Image.png

然后我們就可以測試一下動畫效果是否如我們所預期的:


測試動畫效果

好啦,到這一步,我們已經為MyText添加了兩個動畫,分別是放大效果上升效果,接下來我們就需要將兩個動畫銜接起來

4、編排兩個動畫播放順序

要編排動畫,就需要用到Animator Controller文件,我們雙擊打開MyText,會自動打開Animator編輯器:


打開 MyText文件

Animator編輯器

我們可以通過編輯器內容看到,現在的動畫編排狀態是MyText一開始就會進入Appear動作,所以要達到我們的預期效果,我們就只需要再添加一條銜接線,讓MyText播完Appear后就進入UpRight狀態,我們鼠標右鍵點擊Appear狀態,然后選擇Make Transition,然后連接UpRight狀態


鏈接UpRight狀態

接下里我們就可以運行游戲看看動畫效果的銜接是否正確了:


測試銜接效果

通過測試我們可以看到,現在MyText出現后會播放放大效果,然后再播放上升效果,但是有一個問題,他會一直循環播放上升效果,所以我們需要將動畫的循環播放給關掉


關閉循環播放

這里我們需要將AppearUpRight兩個動畫的循環都關掉,關掉之后我們再運行一下游戲,就會發現動畫不會循環播放了

5、添加移除腳本

現在我們還存在最后一步,就是MyText上升動畫播放完成后,我們需要將MyText刪除掉,所以一下我們需要給MyText添加一個腳本,腳本命名為DestroyByTime,由於我們兩個動畫播放的總時間為1.5秒,所以我添加腳本讓MyText生成后的1.5秒就自己銷毀掉,下面是腳本的代碼內容:


完整的代碼

6、制作成Prefab

做完上面這些工作后,我們便可將MyText制作成一個Prefab了,制作方法很簡單,直接將MyText拖入到Prefabs文件夾就可以了,這里就不做詳細介紹了

五、實現點擊Button動態創建一個MyText

首先我們選中最開始創建的Button對象,然后滑動Inspector看到Button (Script)組件的相關屬性,我們可以看到其中有一個On Click()屬性,這里就是實現Button點擊的響應事件的地方


On Click()屬性

我們點擊其中的+按鈕,來新建一個響應事件,我們會看到響應事件有兩個部分組成:

  • 響應對象
  • 執行動作

新建一個響應事件

上圖中我們可以看,左邊的Object就是我們需要指定響應的對象,這里的對象可以是我們場景中任意一個GameObject,然后左邊的Function就是該對象需要執行的動作,我試着將Button拖入到Object之中:


Button拖入到Object之中

拖入之后,我們就可以看到Function里面有很多動作可以供我們選擇,而且Unity還很溫馨的給我們按照組件類型來分類了,關於每個動作的含義和用法,感興趣的朋友可以自己去查閱官方文檔,本例中,我們需要的動作是沒有的,所以我們需要自己創建一個動作

1、創建我們自己的響應動作

首先我們給Button添加一個腳本,命名為MyButtonEvent,然后輸入一下代碼:


完整的代碼
  • 首先我們引入UnityEngine.UI命名空間
  • 然后我們聲明一個公共變量myText,用來存放我們的MyText Prefab
  • 然后我們定義一個私有的tempText,用來臨時保存生成的MyText實例
  • 然后我們定義了一個公共的方法createMyText,這里方法必須是Public的,這樣才能出現在Function選項中
  • 方法里面我們首先使用Instantiate方法動態創建了一個MyText的對象,然后我們將他賦值給tempText
  • 由於UGUI對象只能處於Cavans下面才能被顯示出來,所以我們需要將創建的MyText實例的父節點設置為Canvas,使用的是SetParent方法,該方法屬於Transform組件
  • 然后我們再動態修改Text的文本內容

寫完代碼,保存一下,然后回到編輯器

2、選擇響應動作

此時我們選中Button對象,我們可以在On Click()中找到我們剛剛創建的createMyText動作(或者叫方法),如下圖:


createMyText動作

我們選中它之后,我們可以設置傳遞給方法的參數,也就是我們MyText的文本內容,我們將內容設置為你好Unity!


設置傳遞參數

做完這個操作,然后我們再把創建中現有的MyText對象刪除掉,運行一下游戲,點擊Button就會彈出一個MyText對象了


最終效果



文/Zui(簡書作者)
原文鏈接:http://www.jianshu.com/p/99407ebc10c9
著作權歸作者所有,轉載請聯系作者獲得授權,並標注“簡書作者”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM