【菜菜丸的菜鸟教程】做一个简单的游戏截图相册(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);
}
}
更多推荐
所有评论(0)