unity游戏设计之背包系统

这次任务是模仿上图的样子,制作一个类似的背包系统

上面的链接为:http://www.tasharen.com/ngui/exampleX.html

我们的目标是:

1.实现背包系统的UI界面

2.实现物品的移动

 

最后的效果:

 

界面没有网页上的效果好啦,但是基本实现了背包系统。

 

下面是步骤:

 

首先构建如上所示的背包的基础结构。

参考课程的例子,利用canvas实现背包系统的框架,包含canvas,camera。 

首先新建一张canvas,设置render mode,render camera, UI scale mode,match。 

新建一个camera 并设置 render camera。

 

然后在canvas里面新建一个canvas,用于存储装备栏与背包栏。

然后我们在做具体实现背包的格子。

再刚才新建的canvas下,创建两个panel,并且命名为backpack与wear。分别用于存放装备与背包物品。然后分别添加Grid Layout Group的component, 以实现添加元素的自动对齐。

背包中的格子我全部使用image实现。然后可以添加一些text。

 

下面我们需要添加一个背景和人物。

背景直接在百度上找了一张图,人物在asset store上下载了一个卡通战士的model。

添加背景我们首先创建一个空对象,将main camera添加进去,然后再里面添加一个空对象,并命名为background,给他添加sprite render 的 component。

 

然后将我们的想要的背景图片直接拖入asset中,unity会将他自动生成sprite格式,素材的右边会多出一个小的播放按钮一样的图示就可以了。

 

然后将其拖入sprite render中的sprite,material选择sprite default。我之前没有改成default会有错误产生。

这样子再修改修改图片大小什么的就差不多了。

然后是人物,就在asset store上下载了一个人物,然后拖入。调整一个位置与大小。

这里还要注意我们需要调整一下摄像机。一个负责看UI,一个看背景等其他。

我们只需要调整culling mask这个参数,里面可以勾选显示的部分。然后就是这样子了。

 

接着实现背包拖放的功能。在subcanvas里面新建一个对象树,然后新建image来表示物品,存放我们需要的物品。source image中放的是从网络上找来的图片素材来表示装备。

最后一步,实现物品的拖放我们主要是依靠代码实现的,这里我们需要继承IBeginDragHandler, IDragHandler, IEndDragHandler这三个接口,使用Unity自带的Event Trigger检测物品拖放的操作。

 

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class drag : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
{
	private Transform transform_;
	private RectTransform rectTransform_;
	private CanvasGroup canvasG_;
	public Vector3 rootPosition;
	private GameObject lastE = null;
	private Color lastEcolor;
	private Color hcolor = Color.cyan;

	void Start()
	{
		transform_ = this.transform;
		rectTransform_ = this.transform as RectTransform;
		canvasG_ = GetComponent<CanvasGroup>();
		rootPosition = transform_.position;
		//originalPosition = new Vector3(0, 0, 0);
	}
	void Update()
	{
	}

	public void OnBeginDrag(PointerEventData eventData)
	{
		canvasG_.blocksRaycasts = false;//event trigger忽略自身
		lastE = eventData.pointerEnter;
		lastEcolor = lastE.GetComponent<Image>().color;
		rootPosition = transform_.position;//拖拽前记录起始位置
		gameObject.transform.SetAsLastSibling();//保证当前操作的对象能够优先渲染,即不会被其它对象遮挡住
	}
	public void OnDrag(PointerEventData eventData)
	{
		Vector3 globalMousePos;
		if (RectTransformUtility.ScreenPointToWorldPointInRectangle(rectTransform_, eventData.position, eventData.pressEventCamera, out globalMousePos))
		{
			rectTransform_.position = globalMousePos;
		}
		GameObject curEnter = eventData.pointerEnter;
		bool inItemGrid = EnterItemGrid(curEnter);
		if (inItemGrid)
		{
			Image img = curEnter.GetComponent<Image>();
			lastE.GetComponent<Image>().color = lastEcolor;
			if (lastE != curEnter)
			{
				lastE.GetComponent<Image>().color = lastEcolor;
				lastE = curEnter;//记录当前物品格子以供下一帧调用
			}
			//当前格子设置高亮
			img.color = hcolor;
		}
	}
	public void OnEndDrag(PointerEventData eventData)
	{
		GameObject curEnter = eventData.pointerEnter;
		//拖拽到的空区域中(如包裹外),恢复原位
		if (curEnter == null)
		{
			transform_.position = rootPosition;
		}
		else
		{
			//移动至物品格子上
			if (curEnter.name == "Image")
			{
				transform_.position = curEnter.transform.position;
				rootPosition = transform_.position;
				curEnter.GetComponent<Image>().color = lastEcolor;//当前格子恢复正常颜色
			}
			else
			{
				//移动至包裹中的其它物品上
				if (curEnter.name == eventData.pointerDrag.name && curEnter != eventData.pointerDrag)
				{
					Vector3 targetPostion = curEnter.transform.position;
					curEnter.transform.position = rootPosition;
					transform_.position = targetPostion;
					rootPosition = transform_.position;
				}
				else//拖拽至其它对象上面(包裹上的其它区域)
				{
					transform_.position = rootPosition;
				}
			}
		}
		lastE.GetComponent<Image>().color = lastEcolor;//上一帧的格子恢复正常颜色
		canvasG_.blocksRaycasts = true;//确保event trigger下次能检测到当前对象
	}
	bool EnterItemGrid(GameObject Obj)
	{
		if (Obj == null)
		{
			return false;
		}
		return Obj.name == "Image";
	}
}

 

posted @ 2017-05-03 22:33  Alala_713  阅读(1152)  评论(0编辑  收藏  举报