继续来写Galgame项目。昨天写的脚本很多地方都很不规范,今天来整改一下。
首先想了一下,决定直接把DialogueTrigger删掉,硬要加入一个中间组件会使两段对话的衔接处出现很大的问题,还不如去掉,全部用DialogueManager来实现。直接定义一个GameObject的数组,来存放所有对话Object。然后是其他的定义部分,看名字应该都能懂。
//public varible for dialogue display
public GUISkin FontSet;//GUI SKIN
public GameObject[] Conversations;
public Texture2D TxtBackground;
public Texture2D TxtCharacter;
public string Current_String;
public string Speaker;
public AudioClip Current_BGM;
//private varible for some parameters
private int ConversationAmount;
private int ConversationArraySign;
private string Temp_String;//Used for display
private string[] Dialogue_Array;
private bool UpdateTrigger;
private bool EndFlag;
private Rect DrawPos;
我们先来把全局变量定义了,因为等会儿会用到文字显示的状态。新建一个GlobalManager脚本,定义枚举变量。估计BGM也会用全局变量来控制,定义了再说。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//Used for State Switch
public enum Project_State {none,playing,pause}
public enum GameBGM {none,bgm1,bgm2,bgm3,bgm4}
public class Display_State : MonoBehaviour {
//Initialize;
public static Project_State Displaying_State = Project_State.none;
public static GameBGM Dialogue_BGM = GameBGM.none;
}
修改了一下对话元素的内容,添加三个矩形来改变立绘的位置,并用index来选择绘制位置,在Manager中用switch语句来控制。
public class IndividualConversation : MonoBehaviour {
public Texture2D Background;
public Texture2D Character;
public string Speaker;
public string[] Conversations;
public int index;
public AudioClip BgmSelection;
public Rect[] Positions=new Rect[3];
void Awake()
{
Positions[0] = new Rect(new Rect(200, 100, Character.width, Character.height));
Positions[1] = new Rect(new Rect(100, 100, Character.width, Character.height));
Positions[2] = new Rect(new Rect(300, 100, Character.width, Character.height));
}
}
然后要实现动态显示文字的功能必须用到协程,必须规划好,播放对话的内容只能用一个协程来实现,不然会出现混乱的情况,函数内容和昨天Trigger里的实现原理相似,在命名上稍微规范了下。
IEnumerator Playing_Conversation(GameObject[] Cur_Conversation)
{
Display_State.Displaying_State = Project_State.playing;
foreach (GameObject gb1 in Cur_Conversation)
{
//Initializing
Current_BGM = gb1.GetComponent<IndividualConversation>().BgmSelection;
Dialogue_Array = gb1.GetComponent<IndividualConversation>().Conversations;
TxtBackground = gb1.GetComponent<IndividualConversation>().Background;
TxtCharacter = gb1.GetComponent<IndividualConversation>().Character;
//Get Character Position
switch(gb1.GetComponent<IndividualConversation>().index)
{
case 0:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[0];
break;
case 1:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[1];
break;
case 2:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[2];
break;
default:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[1];
break;
}
yield return new WaitForEndOfFrame();
ConversationArraySign = 0;
int StringSign = 0;
Current_String = "";
Debug.Log("Start Text Display");
//Debug if Got or not
//Debug.Log(Dialogue_Array.Length);
//
while (ConversationArraySign < Dialogue_Array.Length)
{
Temp_String = Dialogue_Array[ConversationArraySign];
while (StringSign < Temp_String.Length &&
Current_String.Length < Temp_String.Length && Display_State.Displaying_State == Project_State.playing)
{
Debug.Log(StringSign);
Current_String += Temp_String[StringSign];
yield return new WaitForSeconds(0.05f);
StringSign += 1;
}
if (Current_String != Temp_String)
{
Current_String = Temp_String;
}
Display_State.Displaying_State = Project_State.pause;
while (Display_State.Displaying_State == Project_State.pause)
{
yield return new WaitForSeconds(0.01f);
}
Current_String = "";
ConversationArraySign++;
StringSign = 0;
}
}
StopCoroutine("Playing_Conversation");
}
更新状态变化的函数在此(在update()中调用):
void UpdateState()
{
if(Display_State.Displaying_State == Project_State.playing&&UpdateTrigger==true)
{
Display_State.Displaying_State = Project_State.pause;
}
else if (Display_State.Displaying_State == Project_State.pause && UpdateTrigger == true)
{
Display_State.Displaying_State = Project_State.playing;
}
}
BGM还没想好怎么弄,是该直接在对话里加载还是用全局变量,之后再想吧。还需要好感度,选择支的设置,以及存档读取功能的实现,还是有点麻烦的,这几天慢慢来实现。
把脚本和图片挂上去,试一试效果
界面太丑,GUI掌握得太浅了,还需要继续学习。明天继续
把整个Manager贴上来给大家把玩
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class DialogueManager : MonoBehaviour {
//public varible for dialogue display
public GUISkin FontSet;
public GameObject[] Conversations;
public Texture2D TxtBackground;
public Texture2D TxtCharacter;
public string Current_String;
public string Speaker;
public AudioClip Current_BGM;
//private varible for some parameters
private int ConversationAmount;
private int ConversationArraySign;
private string Temp_String;
private string[] Dialogue_Array;
private bool UpdateTrigger;
private bool EndFlag;
private Rect DrawPos;
private void Awake()
{
Current_String="";
Temp_String = "";
ConversationAmount = 0;
ConversationArraySign = 0;
UpdateTrigger = false;
EndFlag = false;
}
void Start () {
StartCoroutine("Playing_Conversation", Conversations);
}
private void OnGUI()
{
GUI.skin = FontSet;
GUI.DrawTexture(new Rect(0, 0, Screen.width, Screen.height),TxtBackground);
GUI.DrawTexture(DrawPos, TxtCharacter);
GUI.Label(new Rect(20, Screen.height - 70, Screen.width - 30, 30), Current_String);
GUI.Label(new Rect(20, Screen.height - 120, 50, 20), "未定义");
UpdateTrigger= GUI.Button(new Rect(Screen.width - 100, Screen.height - 100, 90, 40),
"continue");
}
void UpdateState()
{
if(Display_State.Displaying_State == Project_State.playing&&UpdateTrigger==true)
{
Display_State.Displaying_State = Project_State.pause;
}
else if (Display_State.Displaying_State == Project_State.pause && UpdateTrigger == true)
{
Display_State.Displaying_State = Project_State.playing;
}
}
void SelectBGM(GameObject para)
{
GameObject BGMPlayer = GameObject.Find("BGM_Manager/BGM_Source");
}
IEnumerator Playing_Conversation(GameObject[] Cur_Conversation)
{
Display_State.Displaying_State = Project_State.playing;
foreach (GameObject gb1 in Cur_Conversation)
{
//Initializing
Current_BGM = gb1.GetComponent<IndividualConversation>().BgmSelection;
Dialogue_Array = gb1.GetComponent<IndividualConversation>().Conversations;
TxtBackground = gb1.GetComponent<IndividualConversation>().Background;
TxtCharacter = gb1.GetComponent<IndividualConversation>().Character;
//Get Character Position
switch(gb1.GetComponent<IndividualConversation>().index)
{
case 0:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[0];
break;
case 1:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[1];
break;
case 2:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[2];
break;
default:
DrawPos = gb1.GetComponent<IndividualConversation>().Positions[1];
break;
}
yield return new WaitForEndOfFrame();
ConversationArraySign = 0;
int StringSign = 0;
Current_String = "";
Debug.Log("Start Text Display");
//Debug if Got or not
//Debug.Log(Dialogue_Array.Length);
//
while (ConversationArraySign < Dialogue_Array.Length)
{
Temp_String = Dialogue_Array[ConversationArraySign];
while (StringSign < Temp_String.Length &&
Current_String.Length < Temp_String.Length && Display_State.Displaying_State == Project_State.playing)
{
Debug.Log(StringSign);
Current_String += Temp_String[StringSign];
yield return new WaitForSeconds(0.05f);
StringSign += 1;
}
if (Current_String != Temp_String)
{
Current_String = Temp_String;
}
Display_State.Displaying_State = Project_State.pause;
while (Display_State.Displaying_State == Project_State.pause)
{
yield return new WaitForSeconds(0.01f);
}
Current_String = "";
ConversationArraySign++;
StringSign = 0;
}
}
StopCoroutine("Playing_Conversation");
}
// Update is called once per frame
void Update () {
UpdateState();
}
}