利用NGUI与XML实现RPG游戏对话框


成品图,并且可以通过点击白色背景往后载入。

制作方法


建立如图所示的层级结构,第一层利用已经做好的Atlas创建




然后通过NGUI的UIButton中的OnClick调用指定方法


上图是那三个层级的挂载脚本

整个NGUI控制我都挂在UIRoot上

代码如下

using UnityEngine;
using System.Collections;
using System.Xml;

public class NGUIButtonClick : MonoBehaviour {
	private UILabel RTalkSome;
	private UISprite RPhoto;

	private UILabel PTalkSome;
	private UISprite PPhoto;

	public GameObject RemiT;
	public GameObject PatchT;//使用两个对象的原因是因为在对象设置为不激活时,Find()函数无法调用

	private int stringCount = 0;
	private ArrayList allPersonName = new ArrayList();
	private ArrayList allExpression = new ArrayList();
	private ArrayList allSaid = new ArrayList();//动态数组,便于添加,并通过stringCount控制

	private string[] RAllFace = new string[]//本地图片加载到atlas中,这个是里面的名字控制,在下面的方法中需要使用
	{
		"レミリア_呆れ",
		"レミリア_驚き",
		"レミリア_怒り",
		"レミリア_泣き",
		"レミリア_特殊",
		"レミリア_笑い",
	};
	private string[] PAllFace = new string[]//我使用的是东方系列的图片
	{
		"パチュリー_呆れ",
		"パチュリー_驚き",
		"パチュリー_怒り",
		"パチュリー_泣き",
		"パチュリー_笑い",
		"パチュリー_通常",
	};
	void Start()
	{
		RTalkSome = GameObject.Find ("STalking").GetComponent<UILabel> ();
		RPhoto = GameObject.Find ("RemiliaTalk").GetComponent<UISprite> ();

		PTalkSome = GameObject.Find ("PTalking").GetComponent<UILabel> ();
		PPhoto = GameObject.Find ("PatchouliTalk").GetComponent<UISprite> ();

		GameObject.Find ("RemiliaTalk").SetActive (false);//Find()方法有问题,当对象不是激活态的时候,用Find无法找到对象,必须在开始使用public
		GameObject.Find("PatchouliTalk").SetActive(false);
		allContent.Clear ();
		LoadFromXML ();
	}
	void ShowTalking()
	{
		if (stringCount < 5) {//读取了XML后按照三个数组依次载入人物,人物表情,对话
			if((string)allPersonName[stringCount] == "Remilia")
			{
				PatchT.SetActive(false);
				RemiT.SetActive(true);
				RPhoto.spriteName = RAllFace[(int)allExpression[stringCount]];
				RTalkSome.text = (string)allSaid[stringCount];
				stringCount++;
			}
			else if((string)allPersonName[stringCount] == "Patchouli")
			{
				PatchT.SetActive(true);
				RemiT.SetActive(false);
				PPhoto.spriteName = PAllFace[(int)allExpression[stringCount]];
				PTalkSome.text = (string)allSaid[stringCount];
				stringCount++;
			}	
		}
		else
		{
			PatchT.SetActive(false);
			RemiT.SetActive(false);
		}


	}
	void LoadFromXML()//XML的调用
	{
		string filepath = Application.dataPath+ @"/Xml/test.xml";
		XmlDocument xmlDoc = new XmlDocument ();
		xmlDoc.Load (filepath);
		XmlNodeList nodeList = xmlDoc.SelectSingleNode ("Dialogue").ChildNodes;//users下的子节点

		foreach (XmlElement xe in nodeList) {
			foreach(XmlElement x1 in xe.ChildNodes)//搜索当前标识的子节点
			{//由于每次只搜一条,采用此种方法不能使用结构体,易出现空值
				if(x1.Name == "name")
				{
					allPersonName.Add(x1.InnerText);
				}
				if(x1.Name == "expression")
				{
					allExpression.Add(int.Parse(x1.InnerText));
				}
				if(x1.Name == "said")
				{
					allSaid.Add(x1.InnerText);
				}
			}
		}
	}


	public void ClickOnSprite()
	{
		stringCount = 0;
		ShowTalking ();
	}
	public void ClickOnLable()
	{
		print ("Lable");
	}
	public void ClickOnBackGround()//调用来显示XML的对话内容
	{
		ShowTalking ();
	}
}
<?xml version="1.0" encoding="utf-8" ?>
<Dialogue>
  <Round count="1">
    <name>Remilia</name>
	<expression>0</expression>
    <said>我有些话想要说</said>
  </Round>
 <Round count="2">
    <name>Remilia</name>
	<expression>0</expression>
    <said>就是这些了</said>
  </Round>
  <Round count="2">
    <name>Patchouli</name>
	<expression>1</expression>
    <said>你还想听什么</said>
  </Round>
  <Round count="4">
    <name>Remilia</name>
	<expression>2</expression>
    <said>测试还不够么</said>
  </Round>
  <Round count="5">
    <name>Patchouli</name>
	<expression>5</expression>
    <said>就是这样</said>
  </Round>
  <Round count="6">
    <name>Remilia</name>
	<expression>5</expression>
    <said>再见!</said>
  </Round>
</Dialogue>

以上就是完整的代码实现,并附有注释,欢迎讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值