![v2-31f97db277a34b3b20d8827b6c307c71_1440w.jpg?source=172ae18b](http://img-02.proxy.5ce.com/view/image?&type=2&guid=32294b1c-8b2e-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-31f97db277a34b3b20d8827b6c307c71_1440w.jpg?source=172ae18b)
date: 2019-03-01 8:10:54
Unity中的不同场景由不同的Scene组成,而我们在不同的Scene之间切换的时候会丢失前一个Scene的数据,但某些数据比如积分、金币、还剩多少条命需要在游戏中一直记录和保留,这也是要实现商店关卡的关键,因为要读取之前所持有的金币,并在花费过后记录在系统中。可能的方法有三种:1.把需要的数据记录在外部文件中,按需读取;2.使用静态类;3.使用DontDestroyOnLoad
,标记不希望被销毁的对象。
信息储存的教程来自YouTube博主quill18creates,地址在此。
PlayerPrefs
这是Unity中可以用来储存数据的一个接口,我们不用管它是如何储存或是储存在哪里,甚至无关游戏运行在哪个平台,只要调用这个类下面的方法,我们就可以储存或读取数据。注意这个文件中保存的数据甚至不会因为退出程序而销毁。
背包
首先在制作背包的界面时一定要搞清楚层级划分,依次为:背包背景、背包(slot holder)、格子(slots)、物品(item),它们依次为包含关系,层层递进。
下面这个脚本实现拖拽,要注意鼠标位置坐标与世界坐标的转换,稍有不慎物品坐标的赋值就会飞出去。
using UnityEngine;
using UnityEngine.EventSystems;
public class DragHandler : MonoBehaviour, IDragHandler, IEndDragHandler {
public void OnDrag(PointerEventData eventData) {
Vector3 mousePos = Input.mousePosition;
mousePos.z = 10; // 有Vector2转为Vector3,并补全Z轴坐标
mousePos = Camera.main.ScreenToWorldPoint(mousePos); // 从Input获得的鼠标坐标是基于屏幕的,我们要将其转换成世界坐标
transform.position = mousePos;
}
public void OnEndDrag(PointerEventData eventData) {
transform.localPosition = Vector3.zero;
}
}
简单的拖拽实现后,就要实现不同格子间的拖放,以及拖放后的信息变更,这在后面一篇博客中具体介绍(UI)。
下面是背包系统的实现,为了让背包中的道具能跨越场景一直存在,我们需要一个不会在场景结束时被销毁的类,且将其实现为一个单例,具体请看Inventory
脚本中的Awake
方法。这样我们就可以将道具信息存进一个 List 并维护了。
在我的配置中 GameManager 并不是单例且会被销毁,因此在每个场景初始化时它会一并初始化背包信息。显示道具的思路是,先创建一个prefab,它附有拖动脚本和图标,遍历Inventory
中储存的所有道具,每有一个道具就生成一个这个prefab,并将道具的图标传入,然后把它放在最近的一个空格上(根据拖拽脚本,需要一并设置好parent),这样玩家就能在背包界面看到道具并用UI的逻辑对其进行交互。
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Inventory : MonoBehaviour {
public GameObject leftSlotsParent;
public GameObject ItemPrefab;
public int score = 0;
public int InventorySize = 16;
public List<Item> items = new List<Item>(); // inventory info
public Item bd1;
public Item bd2;
public Item bd3;
public Item bd4;
public Item bd5;
public Item bd6;
public delegate void OnItemChanged();
public OnItemChanged callback;
static Inventory instance;
GameObject[] slots;
private