Unity的live2dgalgame多语言可配置剧情框架

这段代码用于读取表格

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using OfficeOpenXml;
using System.IO;
using UnityEngine.Networking;
using UnityEngine.UI;
using Random = UnityEngine.Random;public class Plots : MonoBehaviour
{public static string ReadingExcel;//正在读取的表格[Header("表格文件夹")] public static string URL =  Application.streamingAssetsPath;public static string PlotsEXCEL = "Plots";private static bool m_loaded;public  class plot{public string index, CN,NameCN, NameEN,EN,NameJP, JP,Face;}public static List<plot> S_Plots= new List<plot>();public virtual void OnEnable(){initialization();}//初始化public void initialization(){if (!m_loaded){LoadExcel();m_loaded = true;} }void LoadExcel(){//获取Excel文件的信息foreach (var VARIABLE in ReadFile()){Debug.Log("剧情挂载成功");FileInfo fileInfo = new FileInfo(VARIABLE);//加载背包信息if (VARIABLE.Contains(PlotsEXCEL)){//通过Excel表格的文件信息,打开Excel表格//使用using(){}语句命令,在结束时自动关闭文件using (ExcelPackage excelPackage = new ExcelPackage(fileInfo)){//读取Excel中的第一张表, 注意EPPlus的索引值是从1开始的ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[1];//取得第一行第一列的数据
//                    Debug.Log("行数"+worksheet.Dimension.End.Row + 1);for (int Left = 2; Left < worksheet.Dimension.End.Row + 1; Left++) //根据行数遍历{if (worksheet.Cells[Left, 1].Value.ToString().Length>0){plot Plot = new plot();Plot.index= worksheet.Cells[Left, 1].Value.ToString();Plot.Face= worksheet.Cells[Left, 2].Value.ToString();Plot.CN= worksheet.Cells[Left, 3].Value.ToString();Plot.NameCN= worksheet.Cells[Left, 4].Value.ToString();Plot.EN= worksheet.Cells[Left, 5].Value.ToString();Plot.NameEN= worksheet.Cells[Left, 6].Value.ToString();Plot.JP= worksheet.Cells[Left, 7].Value.ToString();Plot.NameJP= worksheet.Cells[Left, 8].Value.ToString();S_Plots.Add(Plot);}}}}}}/// <summary>/// 字符串转Enum/// </summary>/// <typeparam name="T">枚举</typeparam>/// <param name="str">字符串</param>/// <returns>转换的枚举</returns>public static T ToEnum<T>(string str){try{return (T)Enum.Parse(typeof(T), str);}catch (ArgumentException e){Debug.LogError("未找到系列"+str);throw;}}static List<string> ReadFile(){List<string> files = GetFiles(URL, "*.xlsx");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;}
}

这个方法里面设置剧情列表,和分支事件

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using DG.Tweening;
using Live2D.Cubism.Rendering;
using OfficeOpenXml.FormulaParsing.Excel.Functions.Math;
using UnityEngine;
using UnityEngine.UI;public class PlotReader : MonoBehaviour
{public Button[] ChoiceButton;public Text Text_Plot,Text_Name;public static int[] PlotBar;public static Action PlotFinEvent;public Button BTN_NextStep,BTN_Auto,BTN_Skip;public bool AutoMode,SkipMode;public Button LanguageCN, LanguageEN, LanguageJP;public float DomoveOffeset = 100;public float DomoveTime=0.1f;public GameObject Live2DFolider;public int index=0;private void Start(){LanguageCN.onClick.AddListener(()=>{Center.Language = "CN";RefreshLanguage();});LanguageEN.onClick.AddListener(()=>{Center.Language = "EN";RefreshLanguage();});LanguageJP.onClick.AddListener(()=>{Center.Language = "JP";RefreshLanguage();});BTN_Auto.onClick.AddListener(() =>{AutoMode = !AutoMode;SkipMode = false;});BTN_Skip.onClick.AddListener(() =>{SkipMode = !SkipMode;AutoMode = false;});BTN_NextStep.onClick.AddListener(PlotNext);//注意!!! 剧情要-1,选项要-2SetPlotBar(new int[]{0,1,2,3,4,5,6,7},() => MakeChoice(new int[] { 7, 8 ,16}));PlotNext();}private float AutoTimeindex;private float AutoTimeMax = 3f;private void Update(){if (AutoMode){if (index<=PlotBar.Length){AutoTimeindex -= Time.deltaTime;}if (AutoTimeindex < 0 ){AutoTimeindex = AutoTimeMax;PlotNext();}}if (SkipMode){if (index<=PlotBar.Length){AutoTimeindex -= Time.deltaTime*20;}if (AutoTimeindex < 0 ){AutoTimeindex = AutoTimeMax;PlotNext();}}}public void PlotNext(){if (index<PlotBar.Length){DoMethodEvent(Plots.S_Plots[PlotBar[index]].Face);Text_Plot.text = GetLanguagePlot(PlotBar[index]);Text_Name.text = GetLanguageName(PlotBar[index]);}else if (index== PlotBar.Length){PlotFinEvent();}index++;}public void RefreshLanguage(){try{Text_Plot.text = GetLanguagePlot(PlotBar[index-1]);Text_Name.text = GetLanguageName(PlotBar[index-1]);}catch (IndexOutOfRangeException e){Text_Plot.text = GetLanguagePlot(PlotBar[PlotBar.Length-1]);Text_Name.text = GetLanguageName(PlotBar[PlotBar.Length-1]);}}/// <summary>/// 根据语言获得剧情/// </summary>/// <param name="index"></param>/// <returns></returns>public string GetLanguagePlot(int index){//  Debug.LogError(index+Plots.S_Plots[index].CN+Plots.S_Plots[index].NameCN);switch (Center.Language){case "CN":return Plots.S_Plots[index].CN;case "EN":return Plots.S_Plots[index].EN;case "JP":return Plots.S_Plots[index].JP;}
Debug.LogError("语言??");return null;}/// <summary>/// 根据语言获得剧情/// </summary>/// <param name="index"></param>/// <returns></returns>public string GetLanguageName(int index){switch (Center.Language){case "CN":return Plots.S_Plots[index].NameCN;case "EN":return Plots.S_Plots[index].NameEN;case "JP":return Plots.S_Plots[index].NameJP;}Debug.LogError("语言??");return null;}/// <summary>/// 设置对话列表/// </summary>/// <param name="t"></param>public void SetPlotBar(int[] t,Action FinEvent){PlotBar = t;PlotFinEvent = FinEvent;}#region 分支public void MakeChoice(int [] choices){CloseAllButtons();for (int i = 0; i<choices.Length; i++){int i1 = i;ChoiceButton[i1].gameObject.SetActive(true);ChoiceButton[i1].transform.Find("Text").GetComponent<Text>().text = GetLanguagePlot(choices[i1]+1);ChoiceButton[i1].onClick.AddListener(() =>{index = 0;Debug.LogError("执行事件BTN"+(choices[i1]+2));ExecuteMethodByName("BTN"+(choices[i1]+2));CloseAllButtons();PlotNext();});}}public void CloseAllButtons(){foreach (var VARIABLE in ChoiceButton){VARIABLE.onClick.RemoveAllListeners();VARIABLE.gameObject.SetActive(false);}}public void BTN9(){SetPlotBar(new int[]{10,11,12,13},JumpToGameLevel);}public void BTN10(){SetPlotBar(new int[]{14,15,16},JumpToGameLevel);}public void BTN18(){SetPlotBar(new int[]{0,1,2,3,4,5,6,7},() => MakeChoice(new int[] { 7, 8 ,16}));}#endregionpublic void JumpToGameLevel(){Debug.LogError("将跳转场景");}public void ExecuteMethodByName(string methodName){// 使用反射获取类的类型Type type = this.GetType();// 使用反射获取方法信息MethodInfo methodInfo = type.GetMethod(methodName);if (methodInfo != null){// 调用匹配的方法methodInfo.Invoke(this, null);}else{Console.WriteLine("Method not found: " + methodName);}}public string[] CutMethod(string input){return input.Split('+');}public void DoMethodEvent(string input){Debug.LogError(input);foreach (var VARIABLE in CutMethod(input)){if (!VARIABLE.Contains("(")){ExecuteMethodByName(VARIABLE);}else if (VARIABLE.Contains("JOIN_")){Match match = Regex.Match(VARIABLE, @"\(([^)]*)\)");if (match.Success){// 获取括号内的内容,并使用逗号分割string[] parts = match.Groups[1].Value.Split(',');if (parts.Length == 4){string stringValue = parts[0];int intValue1, intValue2;if (int.TryParse(parts[1], out intValue1) && int.TryParse(parts[2], out intValue2)){string stringValue2 = parts[3];GameObject go = Instantiate(Resources.Load<GameObject>($"Live2D/{stringValue}"), Live2DFolider.transform);go.transform.position = new Vector3(-999, -999, 2);go.name = go.name.Replace("(Clone)", "");Vector3 worldCoordinate= Vector3.down;;switch (stringValue2){case "Left":worldCoordinate =Camera.main.ScreenToWorldPoint( new Vector3(intValue1-DomoveOffeset, intValue2, 2));Debug.LogError(worldCoordinate);worldCoordinate.z = 2;go.transform.position = worldCoordinate;worldCoordinate = Camera.main.ScreenToWorldPoint(new Vector3(intValue1, intValue2, 0));worldCoordinate.z = 0;go.transform.DOMove(worldCoordinate,DomoveTime);break;case "Right":worldCoordinate =Camera.main.ScreenToWorldPoint( new Vector3(intValue1+DomoveOffeset, intValue2, 2));Debug.LogError(worldCoordinate);worldCoordinate.z = 2;go.transform.position = worldCoordinate;worldCoordinate = Camera.main.ScreenToWorldPoint(new Vector3(intValue1, intValue2, 0));worldCoordinate.z = 0;go.transform.DOMove(worldCoordinate,DomoveTime);break;}}else{Debug.LogError("Failed to parse integers from the input.");}}else{Debug.LogError("Input does not contain 4 comma-separated values.");}}else{Debug.LogError("Input does not match the expected format.");}}else if (VARIABLE.Contains("SETA_")){Match match = Regex.Match(VARIABLE, @"\(([^)]*)\)");if (match.Success){// 获取括号内的内容,并使用逗号分割string[] parts = match.Groups[1].Value.Split(',');if (parts.Length == 3){string stringValue = parts[0];int intValue1, intValue2;if (int.TryParse(parts[1], out intValue1) && int.TryParse(parts[2], out intValue2)){GameObject go = Live2DFolider.transform.Find(parts[0]).gameObject;SetLive2DAlpha(go,intValue1,intValue2);}else{Debug.LogError("Failed to parse integers from the input.");}}else{Debug.LogError("Input does not contain 3 comma-separated values."+VARIABLE+$"length={parts.Length}");}}else{Debug.LogError("Input does not match the expected format.");}}else if (VARIABLE.Contains("FACE")){Match match = Regex.Match(VARIABLE, @"\(([^)]*)\)");if (match.Success){// 获取括号内的内容,并使用逗号分割string[] parts = match.Groups[1].Value.Split(',');if (parts.Length == 2){string stringValue = parts[0];string stringValue2 = parts[1];GameObject go = Live2DFolider.transform.Find(parts[0]).gameObject;SetFace(go,stringValue2);}else{Debug.LogError("Input does not contain 4 comma-separated values.");}}else{Debug.LogError("Input does not match the expected format.");}}else if (VARIABLE.Contains("LEAV_")){Match match = Regex.Match(VARIABLE, @"\(([^)]*)\)");if (match.Success){// 获取括号内的内容,并使用逗号分割string[] parts = match.Groups[1].Value.Split(',');if (parts.Length == 2){string stringValue = parts[0];GameObject go = Live2DFolider.transform.Find(parts[0]).gameObject;Vector3 worldCoordinate;StartCoroutine(des(go));break;IEnumerator des(GameObject go){SetLive2DAlpha(go,(int)(go.transform.Find("Drawables").GetComponentsInChildren<CubismRenderer>()[0].GetComponent<CubismRenderer>().Color.a)*100, 0);Debug.LogError($"Des{go.name}");yield return new WaitForSeconds(0.3f);Destroy(go);}}else{Debug.LogError("Input does not contain 4 comma-separated values.");}}else{Debug.LogError("Input does not match the expected format.");}}}}public void SetLive2DAlpha(GameObject target, int begin,int end){StartCoroutine(AlphaChangerCoroutine(target, begin / 100.0f, end / 100.0f));}private IEnumerator AlphaChangerCoroutine(GameObject target, float begin, float end){foreach (var renderer in target.transform.Find("Drawables").GetComponentsInChildren<CubismRenderer>()){Color currentColor = renderer.Color;currentColor.a = begin;Debug.LogError(currentColor.a);renderer.Color = currentColor;}float duration = 0.1f;int numSteps = 10;float stepTime = duration / numSteps;for (int step = 0; step <= numSteps; step++){float a = begin;if (end>begin){a += (end - begin) / numSteps * step;}else{a -= (begin - end) / numSteps * step;}foreach (var renderer in target.transform.Find("Drawables").GetComponentsInChildren<CubismRenderer>()){
//            Debug.LogError(renderer.name);Color currentColor = renderer.Color;currentColor.a = a;Debug.LogError(currentColor.a);renderer.Color = currentColor;}yield return new WaitForSeconds(stepTime);}}public void SetFace(GameObject go, string Animatorname){go.GetComponent<Animator>().Play(Animatorname);}}

最终效果

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/128901.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工业5G路由器;小体积 千兆高速通信组网

计讯物联工业路由器TR232&#xff0c;5G高速网络&#xff0c;超低时延、高可靠性&#xff0c;小体积、易安装、强兼容&#xff0c;串口/网口多设备接入联网&#xff0c;为用户提供高速稳定的数据传输通道 。    小体积5G工业路由器TR323&#xff0c;外形1047824mm&#xff0…

系列六、Mybatis的一级缓存

一、概述 Mybatis一级缓存的作用域是同一个SqlSession&#xff0c;在同一个SqlSession中执行两次相同的查询&#xff0c;第一次执行完毕后&#xff0c;Mybatis会将查询到的数据缓存起来&#xff08;缓存到内存中&#xff09;&#xff0c; 第二次执行相同的查询时&#xff0c;会…

ArmSom---SPI开发指南

1. 简介 RK3588从入门到精通本⽂主要介绍在Rockchip平台配置spi接口并且使用的方法开发板&#xff1a;ArmSoM-W3Kernel&#xff1a;5.10.160OS&#xff1a;Debian11 2. SPI接口概述 SPI&#xff08;Serial Peripheral Interface&#xff09;&#xff0c;即串行外围设备接口&…

ElementuiPlus的table组件实现行拖动与列拖动

借助了插件sortablejs。这种方法只适合做非树状table。如果想实现树状table&#xff0c;并且可拖动。可以试一下aggridVue3这个插件 <template><div class"draggable" style"padding: 20px"><el-table row-key"id" :data"t…

RabbitMQ 消息对象 序列化/反序列化 天坑!异常处理方案

目录 1. 报错的背景 2. 问题分析 3. 最佳解决办法 1. 报错的背景 a&#xff09;使用 RabbitMQ 发送消息时&#xff0c;发送消息的类型为 Map<String, Object>&#xff0c;map 里面我 put 了一个 <String, Long> 类型&#xff0c;如下图&#xff1a; b&#xff…

【考研数据结构代码题2】删除单链表倒数第n个结点

题目&#xff1a;删除单链表倒数第n个结点 难度&#xff1a;★ 算法思路&#xff1a; 首先题目没有指明链表的长度&#xff0c;多以首先需要编写一个函数getLength()来求表长&#xff0c;其次删除倒数第n个结点&#xff0c;即删除正数第length-n1个结点&#xff0c;这是二者之间…

更快更准 | YOLOv3算法超详细解析(包括诞生背景+论文解析+技术原理等)

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。YOLOv3是一种基于深度学习的目标检测算法&#xff0c;它可以快速而准确地在图像中检测出多个目标。它是由Joseph Redmon和Ali Farhadi在2018年提出的&#xff0c;是YOLO&#xff08;You Only Look Once&#xff09;系列算法…

Linux权限+Shell和Linux的关系

文章目录 1.Shell存在的意义及作用1.1对于Shell的认知过程1.2Shell/图形化界面外壳程序的意义 2.对Linux权限的理解2.1对Linux权限的认知过程2.2对于Linux下ll指令显示的文件属性的认识 1.Shell存在的意义及作用 1.1对于Shell的认知过程 Linux是什么? Linux是一套免费使用和自…

msvcr110.dll丢失的解决方法都有哪些,有效解决msvcr110.dll丢失

今天在使用电脑的时候提示一个和“msvcr110.dll丢失”有关的报错&#xff0c;出现这样的问题小编也是一脸懵&#xff0c;一下也不是知道该怎么处理了&#xff0c;于是小编去了解了一下msvcr110.dll丢失是什么情况&#xff0c;为什么会有这样的问题发生&#xff0c;同时msvcr110…

多模态论文阅读之VLMo

VLMo泛读 TitleMotivationContributionModelExpertimentsSummary Title VLMo:Unified Vision_Langugae Pre-Training with Mixture-of-Modality-Experts Motivation CLIP和ALIGN都采用dual-encoder的方式分别编码图像和文本&#xff0c;模态之间的交互采用cosine similarity…

《C++ Primer》第6章 函数(一)

参考资料&#xff1a; 《C Primer》第5版《C Primer 习题集》第5版 6.1 函数基础&#xff08;P182&#xff09; 典型的函数定义包括&#xff1a;返回类型&#xff08; return type &#xff09;、函数名字、0 个或多个形参&#xff08; parameter &#xff09;组成的列表、函…

Redis常见的全局命令

Redis中最核心的两个命令set和get 两个最核心的命令就是get和set. redis是按照键值对的方式来存储数据的,所以set就表示把key-value存储进去,get表示根据key来查询对应的value. 需要注意的是,必须进入redis客户端才能输入redis命令. 此处的key和value都是字符串类型.对于上述…

致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC]

文章目录 致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 致远OA wpsAssistServlet任意文件上传漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用…

【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队

在云原生领域&#xff0c;无论使用哪种编排调度平台&#xff0c;Kubernetes&#xff0c;DockerSwarm&#xff0c;OpenShift等&#xff0c;业务都需要基于镜像进行交付&#xff0c;我们在内部实践“Source-to-image”和链式构建&#xff0c;总而总结出“OneBuild”模式。 其核心…

VS2022安装时碰到VsWebProtocolSelector.Msi包安装错误,2330code解决方法

未能安装包“Microsoft.VisualStudio.VsWebProtocolSelector.Msi,version17.8.34129.139”。 搜索 URL https://aka.ms/VSSetupErrorReports?qPackageIdMicrosoft.VisualStudio.VsWebProtocolSelector.Msi;PackageActionInstall;ReturnCode2330 详细信息 …

C++——定义一个 Book(图书)类

完整代码&#xff1a; /*定义一个 Book(图书)类&#xff0c;在该类定义中包括数据成员和成员函数 数据成员&#xff1a;book_name &#xff08;书名&#xff09;、price(价格)和 number(存书数量)&#xff1b; 成员函数&#xff1a;display()显示图书的 情况&#xff1b;borro…

Spring面试题:(二)基于xml方式的Spring配置

xml配置Bean的常见属性 id属性 name属性 scope属性 lazy-init属性 init-method属性和destroy属性 initializingBean方法 Bean实例化方式 ApplicationContext底层调用BeanFactory创建Bean&#xff0c;BeanFactory可以利用反射机制调用构造方法实例化Bean&#xff0c;也可采用工…

Apollo云实验:使用Sim control仿真自动驾驶

使用Sim control仿真自动驾驶 概述Sim control仿真自动驾驶启动DreamView仿真系统 实验目的福利活动 主页传送门&#xff1a;&#x1f4c0; 传送 概述 自动驾驶汽车在实现落地应用前&#xff0c;需要经历大量的道路测试来验证算法的可行性和系统的稳定性&#xff0c;但道路测试…

关于Linux下排查C++进程Segment fault问题的步骤

C 中出现Segment问题的常见原因有: 如果要定位Segment fault问题&#xff0c;需要进行如下几步&#xff1a; gdb your_program(gdb) break main(gdb) run(gdb) backtrace同时要在CMakeLists.txt文件中配置编译时启用符号调试信息&#xff0c; 在C或者C中的设置分别如下&#x…

Pytest UI自动化测试实战实例

环境准备 序号库/插件/工具安装命令1确保您已经安装了python3.x2配置python3pycharmselenium2开发环境3安装pytest库pip install pytest4安装pytest -html 报告插件pip install pytest-html5安装pypiwin32库(用来模拟按键)pip install pypiwin326安装openpyxl解析excel文件库p…