主要展示剧情部分
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class TextViewer : PlotTexts
{
public GameObject PlotShower,PlotChooser;
public Image CG;
public Text Name, Talk;
private void Awake()
{
}
private void Update()
{
if (Plots.Count>0)
{
PlotShower.SetActive(true);
Ploting();
}
else
{
PlotShower.SetActive(false);
}
}
public void Ploting()
{
Debug.Log(Plots.Count);
CG.sprite = Plots[0].TalkCg;
Name.text = Plots[0].Name;
Talk.text = Plots[0].Say;
if (Plots.Count>0&&Plots[0].PlotEvent==0)
{
PlotChooser.SetActive(false);
if (Input.GetMouseButtonDown(0))
{
Plots.RemoveAt(0);
}
}
else if (Plots[0].PlotEvent!=0)
{
PlotEvents(Plots[0].PlotEvent);
}
}
public void PlotEvents(int index)
{
Choose('A').onClick.RemoveAllListeners();
Choose('B').onClick.RemoveAllListeners();
switch (index)
{
case 1:
PlotChooser.SetActive(true);
Choose('A').onClick.AddListener(() =>
{
Plots.RemoveAt(0);
SceneManager.LoadScene("Battle");
});
Choose('B').onClick.AddListener(() =>
{
Plots.RemoveAt(0);
Plots.Add(new Plot(){PlotEvent = 0,Say = "测试剧情选项B",Name = "测试人"});
Plots.Add(new Plot(){PlotEvent = 0,Say = "测试剧情选项B第二句",Name = "测试人"});
});
break;
case -1:
{
if (Input.GetMouseButtonDown(0))
{
Plots.RemoveAt(0);
SceneManager.LoadScene("Main");
}
}
break;
case -2:
{
if (Input.GetMouseButtonDown(0))
{ Plots.RemoveAt(0);
SceneManager.LoadScene("Main");
}
}
break;
}
Button Choose(char finder)
{
if (finder=='A')
{
return PlotChooser.transform.Find("A").GetComponent<Button>();
}
else
{
return PlotChooser.transform.Find("B").GetComponent<Button>();
}
}
}
}
剧本存储部分
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlotTexts : MonoBehaviour
{
public struct Plot
{
public int PlotEvent;
public string Say;
public string Name;
public Sprite TalkCg;
}
public static List<Plot> Plots=new List<Plot>();
public static void PlotAdder(int index)
{
switch (index)
{
case 1: Plots.Add(new Plot(){PlotEvent = 0,Say = "测试剧情1",Name = "测试人"});
Plots.Add(new Plot(){PlotEvent = 0,Say = "测试剧情2",Name = "测试人"});
Plots.Add(new Plot(){PlotEvent = 1,Say = "测试剧情3",Name = "测试人"});
break;
case 2:
Plots.Add(new Plot(){PlotEvent = 0,Say = "AA",Name = "主角"});
Plots.Add(new Plot(){PlotEvent = 0,Say = "BB",Name = "对方"});
break;
case -1:
Plots.Add(new Plot(){PlotEvent = 0,Say ="战败第一句",Name = "主角"});
Plots.Add(new Plot(){PlotEvent = -1,Say ="战败第2句",Name = "主角"});
break;
case -2:
Plots.Add(new Plot(){PlotEvent = 0,Say ="战胜第一句",Name = "主角"});
Plots.Add(new Plot(){PlotEvent = -2,Say ="战胜第二句",Name = "主角"});
break;
}
}
}
最终效果
第二种,类似文字游戏的,用lua支持
控制按钮的
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using XLua;
[CSharpCallLua]
public class ButtonEvent : MonoBehaviour
{
public Button[] Buttons;
public Text ShowPort;//文本框
public Image ShowIMG;//展示立绘
public Sprite[] Sprites;//备选图集
private bool IsBattle;
// [CSharpCallLua]
// public delegate void LuaBtnEvent(int index);
//[CSharpCallLua]
// public static LuaBtnEvent BtnEvent;//被LuaModer引用
private void OnEnable()
{
BTNSetEvent(0);
}
public void BTNSetEvent(int index)
{
ResetBTN();
if (index==0)
{
ShowPort.text += "\n开始";
BtnText(0).text = "开始游戏";
GetBTN(0).onClick.AddListener(()=>BTNSetEvent(1));
}
else
{
if (PlotEvent.Plots[index].Specail)
{
LuaModer.luaEnv.DoString($"main.PlotEventBar({index})");
}
ShowPort.text += "\n" + PlotEvent.Plots[index].Plot;
if (PlotEvent.Plots[index].Branch)
{
for (int i = 0; i < PlotEvent.Plots[index].BranchPlot.Length; i++)
{
int i1 = i;
BtnText(i1).text = $"选择{(i1+1).ToString()}";//从0开始不符合玩家习惯
GetBTN(i1).onClick.AddListener(() =>
{
BTNSetEvent(PlotEvent.Plots[index].BranchPlot[i1]);
});
}
}
else
{
BtnText(0).text = "继续";
GetBTN(0).onClick.AddListener(() =>
{
BTNSetEvent(PlotEvent.Plots[index].BranchPlot[0]);
});
}
}
}
/// <summary>
/// 战斗逻辑
/// </summary>
public void EnemyATK()
{
}
public Button GetBTN(int index)
{
return Buttons[index];
}
public Text BtnText(int index)
{
return Buttons[index].transform.Find("BTNtext0").GetComponent<Text>();
}
public void ResetBTN()
{//这里调节文本
if (ShowPort.text.Length>400)
{
ShowPort.text = ShowPort.text.Substring(ShowPort.text.Length-400, 400);
}
foreach (var VARIABLE in Buttons)
{
VARIABLE.onClick.RemoveAllListeners();
VARIABLE.transform.Find("BTNtext0").GetComponent<Text>().text = "";
}
}
}
存储
using System.Collections;
using System.Collections.Generic;
using Tutorial;
using UnityEngine;
using XLua;
public class PlotEvent : MonoBehaviour
{
public class PlotClass
{
public int ID;
public string Plot;
public bool Branch;
public bool Specail;
public int[] BranchPlot;
}
[CSharpCallLua]
public static PlotClass[] Plots = new PlotClass[100];//被LuaModer引用
}
LuaModer
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using XLua;
public class LuaModer : MonoBehaviour
{
public static LuaEnv luaEnv=new LuaEnv();
readonly string ModPath=Application.streamingAssetsPath+"\\Mod";//Mod路径
public PlotEvent PlotEvent;
public void Start()
{
luaEnv.AddLoader(Loader);
List<string> files = ReadFile();
foreach (var VARIABLE in files)
{
string Luafile = VARIABLE.Replace(ModPath+"\\", "");//获取Mod路径中lua文本的文件名
Luafile = Luafile.Replace(".lua.txt", "");
luaEnv.DoString($"require '{Luafile}'");
}
#region 赋值
global::PlotEvent.Plots=luaEnv.Global.Get<PlotEvent.PlotClass[]>("PlotTable");
// ButtonEvent.BtnEvent=luaEnv.Global.Get<ButtonEvent.LuaBtnEvent>("PlotEventBar");
#endregion
}
/// <summary>
/// 获取文件的方法
/// </summary>
List<string> ReadFile()
{
List<string> files = GetFiles(ModPath, "*.txt");
foreach (var item in files)
{
Console.WriteLine(item);
}
Console.ReadKey();
List<string> GetFiles(string directory, string pattern)
{
List<string> files = new List<string>();
foreach (var item in Directory.GetFiles(directory, pattern))
{
files.Add(item);
}
foreach (var item in Directory.GetDirectories(directory))
{
files.AddRange(GetFiles(item, pattern));
}
return files;
}
return files;
}
/// <summary>
/// 自定义加载器
/// </summary>
/// <param name="filepath"></param>
/// <returns></returns>
private byte[] Loader(ref string filePath)
{
Debug.Log(filePath.ToString());
string path = ModPath+"\\"+filePath+@".lua.txt";
return System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(path));
}
}
lua部分
print "剧本加载成功"
local Unity=CS.UnityEngine.GameObject.Find("Console")
local PublicInterface=Unity:GetComponent("LuaModer")
local PlotEvent=PublicInterface.PlotEvent
local Buttons=Unity:GetComponent("ButtonEvent").Buttons
local Player=Unity:GetComponent("PlayerInfo")
-----------------------------------------------------------------
main={}
print"链接成功"
print (Player.HP)
----剧情编辑器----
PlotTable={{
--ID:[int]剧情编号
--Plot:[string]剧情内容 换行用 \n 表示
--Branch:[boolean]是否分支.如果为false,可忽略.true为有
--Specail:[boolean]是否有事件.如果为false,可忽略
--BranchPlot:[int[]]分支或继续指向的剧情.如果是分支,要用逗号隔开
},
{
ID=1,
Plot="测试分支剧情\n 1: 恢复玩家HP10 \n 2:玩家获得一个测试的buff \n 3:玩家向北移动1格",
Branch=true,
BranchPlot={2,3,4}
},
{
ID=2,
Plot="剧情剧情1\n玩家的HP恢复10",
Specail=true,
BranchPlot={1}
},
{
ID=3,
Plot="剧情剧情2",
Specail=true,
BranchPlot={1}
},
{
ID=4,
Plot="剧情剧情3",
Specail=true,
BranchPlot={1}
}
}
----剧情事件编辑器----
--[[
如果剧本编辑器里的剧情启动了Specail
那么它对应的ID要在这里注册事件
预制方法:
ChangeValue(A,目标)
更改目标的数值,使目标数值与A相加
目标{
HP=生命值
EP=意志
HHP=敌人生命值
EHP=敌人意志
}
举例 ChangeValue(HP,-10) 玩家失去10HP
Effect("状态名称",可加成)
增加一个状态,双引号不能忽略.可加成部分填true或false(若false可忽略).可加成的意思是:如果已经有这个状态
就强化为+
举例 Effect("中毒",true) 玩家中毒.如果已经中毒,就改为中毒+
EffectClear("状态名称")
移除一个状态.如果状态名称是"ALL",就移除所有状态
EffectFind("状态名称")
判断是否有这个状态
Move("方向",格数)
向某方向移动几格?双引号不能忽略
方向{
Up=北
Down=南
Left=西
Right=东
}
举例 Move("UP",1) 玩家向北1格
如果以上的糖不能满足需求..属性直接调用:
Player.HP [int]玩家的体力
Player.EP [int]玩家的意志
Player.EnemyHP [int]敌人的体力(如果有)
Player.EnemyEP [int]敌人的意志(如果有)
Player.Effects [List<string>] 玩家的状态
Player.Player [GameObject] 只读:玩家单位(仅用于目标检测,判定)
]]
function PlotEventBar(ID)
if ID<11 then
if ID==2 then
ChangeValue("HP",10)
end
if ID==3 then
if EffectFind("一个测试状态+") then
Effect("超强的测试状态")
else
Effect("一个测试状态",true)
end
end
if ID==4 then
Move("Up",1)
end
end
end
main.PlotEventBar=PlotEventBar
function ChangeValue(target,value)
if target=="HP" then
Player.HP=value+Player.HP
elseif target=="EP" then
Player.EP=value+Player.EP
elseif target=="EHP" then
Player.EnemyHP=value+Player.EnemyHP
elseif target=="EEP" then
Player.EnemyEP=value+Player.EnemyEP
end
end
function Effect(AdV,Pls)
if Player.Effects:Contains(AdV) or Player.Effects:Contains(AdV.."+") then
for i = 1, Player.Effects.Count do
if Player.Effects[i-1]==AdV then
if Pls==true then
Player.Effects[i-1]=AdV.."+"
end
break
end
end
else
Player.Effects:Add(AdV)
end
end
function EffectFind(AdV,Plus)
if Player.Effects:Contains(AdV) or Player.Effects:Contains(AdV.."+") then
return true
else return false
end
end
function EffectClear(AdV)
if Player.Effects:Contains(AdV) or Player.Effects:Contains(AdV.."+") then
for i = 1, Player.Effects.Count do
if Player.Effects[i-1]==AdV then
Player.Effects:Remove(AdV)
end
if Player.Effects[i-1]==(AdV.."+") then
Player.Effects:Remove(AdV.."+")
end
end
end
if AdV=="ALL" then
Player.Effects:Clear()
end
end
function Move(Where,Value)
print((Player.Player:GetComponent("RectTransform").anchoredPosition3D+CS.UnityEngine.Vector3(Value*200,0,0)))
if Where=="Left" then
Player.Player:GetComponent("RectTransform").anchoredPosition3D=(Player.Player:GetComponent("RectTransform").anchoredPosition3D+CS.UnityEngine.Vector3(Value*200,0,0))
end
if Where=="Right" then
Player.Player:GetComponent("RectTransform").anchoredPosition3D=(Player.Player:GetComponent("RectTransform").anchoredPosition3D+CS.UnityEngine.Vector3(Value*-200,0,0))
end
if Where=="Up" then
Player.Player:GetComponent("RectTransform").anchoredPosition3D=(Player.Player:GetComponent("RectTransform").anchoredPosition3D+CS.UnityEngine.Vector3(0,Value*200,0))
end
if Where=="Down" then
Player.Player:GetComponent("RectTransform").anchoredPosition3D=(Player.Player:GetComponent("RectTransform").anchoredPosition3D+CS.UnityEngine.Vector3(0,Value*-200,0))
end
end
return main
效果文章来源:https://www.toymoban.com/news/detail-673746.html
文章来源地址https://www.toymoban.com/news/detail-673746.html
到了这里,关于自用Unity剧情系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!