【菜菜丸的菜鸟教程】做一个简单的游戏截图相册(5)
五、删除相册中的图片(1)制作删除图片窗口的UI在Popup Window Canvas下新建UI>Panel,命名为Confirm,按照之前介绍的方法设置大小、位置、背景图等。(参考大小:长550宽320)在Confirm下新建UI>Text,放到Confirm偏上居中的位置,调整大小。(参考大小:长450宽150)在Text的Text组件中输入以下文字并调整字体、字号等:是否确定删
·
五、删除相册中的图片
(1)制作删除图片窗口的UI
在Popup Window Canvas下新建UI>Panel,命名为Confirm,按照之前介绍的方法设置大小、位置、背景图等。(参考大小:长550宽320)
在Confirm下新建UI>Text,放到Confirm偏上居中的位置,调整大小。(参考大小:长450宽150)在Text的Text组件中输入以下文字并调整字体、字号等:
是否确定删除这张图片?
在Confirm下新建UI>Button,并复制一个,分别放到Confirm偏下左右两侧,分别命名为Yes Btn和No Btn,调整大小。在Yes Btn的子物体Text的Text组件中,输入文字“是”,在No Btn的子物体Text的Text组件中,输入文字“否”,并调整字体、字号等。
完成后的删除图片窗口UI将类似于下图:
(2)创建字典
为什么要创建字典呢?这是因为当我们点击一张图片删除它时,能直接获取到的只有这张图片的Sprite或它所在格子的信息,而我们要删除的图片是保存在本地文件夹里的png文件,我们要建立这两者之间的联系。而字典恰好有一个很棒的功能,就是它能通过Key-Value的写法将两组变量一一对应。下面就让我们一起来写一下吧!
Dictionary
<
String
,
String
>
dic
=
new
Dictionary
<
String
,
String
>
(
)
;
//生成相册的字典(将截图文件夹中的文件名和Sprite文件名一一对应)
public
void
ImagesDic
(
)
{
dic
.
Clear
(
)
;
for
(
int
i
=
0
;
i
<
sprites
.
Length
;
i
++
)
{
dic
.
Add
(
screenshotNames
[
i
]
,
sprites
[
i
]
.
name
)
;
}
}
public
void
CreateSprites
(
)
{
ImagesDic
(
)
;
}
可以看到,截图名称和Sprite名称是成对写入字典的,它们就是字典的Key和Value,我们将在删除文件时用Value(Sprite名称)来调取Key(截图名称)。ImagesDic()这个方法要在CreateSprites()结尾来调用。
(3)获得要删除的图片所在格子
通过鼠标点击检测,我们可以拿到要删除的格子名称。之前的所有脚本都是在AlbumManager这个脚本中写的,不过这个功能和相册格子的关系非常密切,所以我们在Scripts文件夹中新建一个脚本,命名为SlotHolder。然后,将它挂在所有Slot Holder上(可以先选中所有Slot Holder,然后统一添加该脚本)。将Confirm拖入Confirm Panel栏位,将Album Manger拖入Album Manager栏位,将Yes Btn拖入Confirm Button栏位,将No Btn拖入Cancel Button栏位。
下面我们来写SlotHolder脚本。
using
System
.
Collections
;
using
System
.
Collections
.
Generic
;
using
UnityEngine
;
using
UnityEngine
.
EventSystems
;
using
UnityEngine
.
UI
;
using
System
;
public
class
SlotHolder
:
MonoBehaviour
,
IPointerClickHandler
{
public
GameObject
confirmPanel
;
public
GameObject
albumManager
;
GameObject
selectedSlot
;
String
selectedSlotName
;
public
Button
confirmButton
;
public
Button
cancelButton
;
void
Start
(
)
{
//给确认窗口的删除按钮(是)加上监听事件(关闭窗口)
confirmButton
.
onClick
.
AddListener
(
CloseConfirmWindow
)
;
//给确认窗口的关闭按钮(否)加上监听事件
cancelButton
.
onClick
.
AddListener
(
CloseConfirmWindow
)
;
}
public
void
OnPointerClick
(
PointerEventData
eventData
)
{
//单击右键呼出删除图片的确认窗口
if
(
eventData
.
button
==
PointerEventData
.
InputButton
.
Right
&&
this
.
transform
.
GetChild
(
0
)
.
gameObject
.
activeInHierarchy
==
true
)
{
selectedSlotName
=
name
;
albumManager
.
GetComponent
<
AlbumManager
>
(
)
.
slotname
=
name
;
selectedSlot
=
GameObject
.
Find
(
selectedSlotName
)
;
OpenConfirmWindow
(
)
;
}
}
void
OpenConfirmWindow
(
)
{
confirmPanel
.
SetActive
(
true
)
;
}
void
CloseConfirmWindow
(
)
{
confirmPanel
.
SetActive
(
false
)
;
}
}
注意,脚本前面要添加using UnityEngine.EventSystems的命名空间和IPointerClickHandler的接口,否则就无法使用检测所点击格子的重要功能。
这里,我们设为单击右键呼出删除图片的窗口,如果按“是”且所点击的格子中有显示的图片,则删除该格子中的图片,如果按“否”则关闭该窗口。
拿到格子信息的关键在于,OnPointerClick这个方法里有一个名为name的参数,它可以直接返回给我们所点击物体的名称。我们用这个name可以查找到格子本身,并把它赋给AlbumManager脚本中的slotname,让AlbumManager脚本也知道要删除的是哪个格子中的图片。这样,删除图片的工作就准备就绪啦。
(4)删除图片
接下来,我们再回到AlbumManager,在这个脚本中执行删除图片的操作。
GameObject
slot
;
public
string
slotname
;
public
Button
deleteBtn
;
void
Start
(
)
{
//给确认窗口的删除按钮(是)加上监听事件(删除图片)
deleteBtn
.
onClick
.
AddListener
(
DeleteTextures
)
;
}
public
void
DeleteTextures
(
)
{
//获得当前点击删除的格子
slot
=
GameObject
.
Find
(
slotname
)
;
//获得该格子的Sprite名称
string
slotspritename
=
slot
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
.
name
;
//从字典中获得Sprite对应的Key(截图文件名)
string
key
=
dic
.
FirstOrDefault
(
item
=>
item
.
Value
==
slotspritename
)
.
Key
;
string
texturepath
=
folderPath
+
key
;
//Debug.Log(texturepath);
//关闭该格子的显示和Sprite,删除截图文件夹中的相应图片文件
slot
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
=
null
;
slot
.
transform
.
GetChild
(
0
)
.
gameObject
.
SetActive
(
false
)
;
File
.
Delete
(
texturepath
)
;
#
if
UNITY_EDITOR
UnityEditor
.
AssetDatabase
.
Refresh
(
)
;
#
endif
//刷新相册图片
ReplaceImages
(
)
;
}
之前,我们已经拿到了slotname,所以很轻松地就能找到它对应的slotspritename。利用之前我们做的字典,就可以从Sprite名称(value)拿到我们的key,也就是图片名称!然后再生成图片的完整路径以便删除。这里,你可以Debug一下路径名称,看看是否有误。最后,当然就是痛快地执行File.Delete了~不要忘了,最后还要刷新一下AssetDatabase和相册图片。
注意,SlotHolder脚本里给删除图片按钮“是”加的监听事件是关闭窗口,AlbumManger脚本里给删除图片按钮“是”加的监听事件才是删除图片。
另外,再给大家留一道简单的思考题。我们的脚本中,用了一句简写方法获得key,如果用foreach语句,要怎么获得这个key呢?希望看到大家的答案哦~
到这步为止的脚本如下:
AlbumManger.cs
using
System
.
Collections
;
using
System
.
Collections
.
Generic
;
using
UnityEngine
;
using
System
;
using
UnityEngine
.
UI
;
using
System
.
IO
;
using
UnityEditor
;
using
System
.
Linq
;
public
class
AlbumManager
:
MonoBehaviour
{
public
GameObject
album
;
public
GameObject
alertWindow
;
GameObject
slot
;
public
Button
albumCloseBtn
;
public
Button
alertBtn
;
public
Button
deleteBtn
;
bool
isOpen
=
false
;
private
int
screenshotCount
=
0
;
private
int
fileCount
=
0
;
private
string
screenshotFileName
;
public
string
slotname
;
private
string
folderPath
;
DirectoryInfo
screenshotDir
;
Sprite
[
]
sprites
;
Texture2D
[
]
textures
;
String
[
]
screenshotNames
;
String
[
]
screenshotPaths
;
static
List
<
int
>
screenshotlist
=
new
List
<
int
>
(
)
;
Dictionary
<
String
,
String
>
dic
=
new
Dictionary
<
String
,
String
>
(
)
;
public
List
<
GameObject
>
slots
=
new
List
<
GameObject
>
(
)
;
void
Start
(
)
{
folderPath
=
Application
.
persistentDataPath
+
"/Textures/"
;
screenshotDir
=
new
DirectoryInfo
(
folderPath
)
;
if
(
!
Directory
.
Exists
(
folderPath
)
)
Directory
.
CreateDirectory
(
folderPath
)
;
albumCloseBtn
.
onClick
.
AddListener
(
ShowOrHideAlbum
)
;
alertBtn
.
onClick
.
AddListener
(
CloseAlertWindow
)
;
deleteBtn
.
onClick
.
AddListener
(
DeleteTextures
)
;
screenshotlist
.
Add
(
screenshotCount
)
;
screenshotCount
=
PlayerPrefs
.
GetInt
(
"MaxNumber"
)
;
ReplaceImages
(
)
;
}
void
Update
(
)
{
if
(
Input
.
GetKeyDown
(
KeyCode
.
A
)
)
{
ShowOrHideAlbum
(
)
;
}
if
(
Input
.
GetKeyDown
(
KeyCode
.
S
)
)
{
if
(
fileCount
<
slots
.
Count
)
{
StartCoroutine
(
CaptureScreenshot
(
)
)
;
}
else
{
this
.
GetComponent
<
AlbumManager
>
(
)
.
alertWindow
.
SetActive
(
true
)
;
}
}
}
private
IEnumerator
CaptureScreenshot
(
)
{
screenshotCount
++
;
screenshotlist
.
Add
(
screenshotCount
)
;
PlayerPrefs
.
SetInt
(
"MaxNumber"
,
screenshotlist
.
Max
(
)
)
;
screenshotFileName
=
"Screenshot_"
+
screenshotCount
+
".png"
;
ScreenCapture
.
CaptureScreenshot
(
folderPath
+
screenshotFileName
)
;
yield
return
new
WaitForSeconds
(
0.5f
)
;
#
if
UNITY_EDITOR
AssetDatabase
.
Refresh
(
)
;
#
endif
ReplaceImages
(
)
;
}
public
void
CreateSprites
(
)
{
FileInfo
[
]
screenshotFiles
=
screenshotDir
.
GetFiles
(
"*.png"
)
;
fileCount
=
screenshotDir
.
GetFiles
(
"*.png"
)
.
Length
;
Array
.
Resize
(
ref
textures
,
fileCount
)
;
Array
.
Resize
(
ref
sprites
,
fileCount
)
;
Array
.
Resize
(
ref
screenshotNames
,
fileCount
)
;
Array
.
Resize
(
ref
screenshotPaths
,
fileCount
)
;
for
(
int
i
=
0
;
i
<
fileCount
;
i
++
)
{
textures
[
i
]
=
new
Texture2D
(
256
,
256
)
;
screenshotPaths
[
i
]
=
screenshotFiles
[
i
]
.
FullName
;
screenshotNames
[
i
]
=
screenshotFiles
[
i
]
.
Name
;
byte
[
]
rawPNG
=
File
.
ReadAllBytes
(
screenshotPaths
[
i
]
)
;
textures
[
i
]
.
LoadImage
(
rawPNG
)
;
sprites
[
i
]
=
Sprite
.
Create
(
textures
[
i
]
,
new
Rect
(
0f
,
0f
,
textures
[
i
]
.
width
,
textures
[
i
]
.
height
)
,
Vector2
.
zero
,
100.0f
)
;
sprites
[
i
]
.
name
=
"Sprite"
+
i
;
}
ImagesDic
(
)
;
}
public
void
ReplaceImages
(
)
{
CreateSprites
(
)
;
for
(
int
j
=
0
;
j
<
slots
.
Count
;
j
++
)
{
slots
[
j
]
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
=
null
;
slots
[
j
]
.
transform
.
GetChild
(
0
)
.
gameObject
.
SetActive
(
false
)
;
}
for
(
int
i
=
0
;
i
<
sprites
.
Length
;
i
++
)
{
if
(
slots
[
i
]
.
transform
.
GetChild
(
0
)
.
gameObject
.
activeInHierarchy
==
false
)
{
slots
[
i
]
.
transform
.
GetChild
(
0
)
.
gameObject
.
SetActive
(
true
)
;
slots
[
i
]
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
=
sprites
[
i
]
;
}
}
}
public
void
ImagesDic
(
)
{
dic
.
Clear
(
)
;
for
(
int
i
=
0
;
i
<
sprites
.
Length
;
i
++
)
{
dic
.
Add
(
screenshotNames
[
i
]
,
sprites
[
i
]
.
name
)
;
}
}
public
void
DeleteTextures
(
)
{
slot
=
GameObject
.
Find
(
slotname
)
;
string
slotspritename
=
slot
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
.
name
;
string
key
=
dic
.
FirstOrDefault
(
item
=>
item
.
Value
==
slotspritename
)
.
Key
;
string
texturepath
=
folderPath
+
key
;
slot
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
=
null
;
slot
.
transform
.
GetChild
(
0
)
.
gameObject
.
SetActive
(
false
)
;
File
.
Delete
(
texturepath
)
;
#
if
UNITY_EDITOR
UnityEditor
.
AssetDatabase
.
Refresh
(
)
;
#
endif
ReplaceImages
(
)
;
}
public
void
ShowOrHideAlbum
(
)
{
isOpen
=
!
isOpen
;
album
.
SetActive
(
isOpen
)
;
}
public
void
CloseAlertWindow
(
)
{
alertWindow
.
SetActive
(
false
)
;
}
}
SlotHolder.cs
using
System
.
Collections
;
using
System
.
Collections
.
Generic
;
using
UnityEngine
;
using
UnityEngine
.
EventSystems
;
using
UnityEngine
.
UI
;
using
System
;
public
class
SlotHolder
:
MonoBehaviour
,
IPointerClickHandler
{
public
GameObject
confirmPanel
;
public
GameObject
albumManager
;
GameObject
selectedSlot
;
String
selectedSlotName
;
public
Button
confirmButton
;
public
Button
closePicture
;
void
Start
(
)
{
confirmButton
.
onClick
.
AddListener
(
CloseConfirmWindow
)
;
cancelButton
.
onClick
.
AddListener
(
CloseConfirmWindow
)
;
closePicture
.
onClick
.
AddListener
(
ClosePicture
)
;
}
public
void
OnPointerClick
(
PointerEventData
eventData
)
{
if
(
eventData
.
button
==
PointerEventData
.
InputButton
.
Right
&&
this
.
transform
.
GetChild
(
0
)
.
gameObject
.
activeInHierarchy
==
true
)
{
selectedSlotName
=
name
;
albumManager
.
GetComponent
<
AlbumManager
>
(
)
.
slotname
=
name
;
selectedSlot
=
GameObject
.
Find
(
selectedSlotName
)
;
OpenConfirmWindow
(
)
;
}
if
(
eventData
.
button
==
PointerEventData
.
InputButton
.
Left
&&
this
.
transform
.
GetChild
(
0
)
.
gameObject
.
activeInHierarchy
==
true
)
{
selectedSlotName
=
name
;
albumManager
.
GetComponent
<
AlbumManager
>
(
)
.
slotname
=
name
;
selectedSlot
=
GameObject
.
Find
(
selectedSlotName
)
;
albumManager
.
GetComponent
<
AlbumManager
>
(
)
.
ShowOrHideAlbum
(
)
;
largePicture
.
SetActive
(
true
)
;
largePicture
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
=
selectedSlot
.
transform
.
GetChild
(
0
)
.
gameObject
.
GetComponent
<
Image
>
(
)
.
sprite
;
}
}
void
OpenConfirmWindow
(
)
{
confirmPanel
.
SetActive
(
true
)
;
}
void
CloseConfirmWindow
(
)
{
confirmPanel
.
SetActive
(
false
)
;
}
void
ClosePicture
(
)
{
largePicture
.
SetActive
(
false
)
;
}
}
更多推荐
已为社区贡献712条内容
所有评论(0)