添加项目文件。

This commit is contained in:
张子健
2023-12-30 23:12:22 +08:00
parent cba6f5759f
commit 02d2b1ea5e
515 changed files with 36285 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: df6ad89fd343e5743ad97bab26a958be
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,44 @@
using UnityEngine;
using UnityEngine.UI;
namespace ScenesScripts.GalPlot
{
/// <summary>
/// 选项类
/// </summary>
public class GalComponent_Choice : MonoBehaviour
{
/// <summary>
/// 这个选项要跳转到的ID
/// </summary>
public string _JumpID;
/// <summary>
/// 显示的文本
/// </summary>
public Text _Title;
public void Init (string JumpID, string Title)
{
_JumpID = JumpID;
_Title.text = Title;
}
/// <summary>
/// 当玩家按下了选项
/// </summary>
public void Button_Click_JumpTo ()
{
GalManager.PlotData.NowJumpID = _JumpID;
GalManager.PlotData.IsBranch = true;
GalManager_Text.IsCanJump = true;
if (_JumpID == "-1")
{
return;
}
this.gameObject.transform.parent.GetComponent<GalManager_Choice>().Button_Click_Choice();
GameObject.Find("EventSystem").GetComponent<GalManager>().Button_Click_NextPlot();
return;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9d70b5e7b3b9866499c01173b32732a9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+333
View File
@@ -0,0 +1,333 @@
using Common.Game;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using TetraCreations.Attributes;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using static ScenesScripts.GalPlot.GalManager.Struct_PlotData;
namespace ScenesScripts.GalPlot
{
public class GalManager : MonoBehaviour
{
[Title("当前对话")]
///
public GalManager_Text Gal_Text;
[Title("当前角色部分")]
public GalManager_CharacterImg Gal_CharacterImg;
[Title("控制选项")]
public GalManager_Choice Gal_Choice;
[Title("控制背景图片的组件")]
public GalManager_BackImg Gal_BackImg;
/// <summary>
/// 角色发言的AudioSource
/// </summary>
private AudioSource Gal_Voice;
/// <summary>
/// 当前场景角色数量
/// </summary>
[Title("当前场景角色数量")]
public int CharacterNum;
private class CharacterConfig
{
public static GameConfig CharacterInfo = new($"{GameAPI.GetWritePath()}/Config/CharacterInfo.ini");
public static GameConfig Department = new($"{GameAPI.GetWritePath()}/Config/Department.ini");
}
/// <summary>
/// 存储整个剧本的XML文档
/// </summary>
private XDocument PlotxDoc;
public class Struct_PlotData
{
public string Title;
public string Synopsis;
public List<XElement> BranchPlot = new();
public Queue<XElement> BranchPlotInfo = new();
public Queue<XElement> MainPlot = new();
public class Struct_Choice
{
public Struct_Choice (string Title, string JumpID)
{
this.Title = Title;
this.JumpID = JumpID;
}
public string Title;
public string JumpID;
}
public class Struct_CharacterInfo
{
public string CharacterID;
public GameObject CharacterGameObject;
public string Name;
public string Affiliation;
}
public List<Struct_CharacterInfo> CharacterInfo = new();
public List<Struct_Choice> ChoiceText = new();
/// <summary>
/// 当前的剧情节点
/// </summary>
public XElement NowPlotDataNode;
/// <summary>
/// 当前是否为分支剧情节点
/// </summary>
public bool IsBranch = false;
public string NowJumpID;
}
public static Struct_PlotData PlotData = new();
private void Start ()
{
Gal_Voice = this.gameObject.GetComponent<AudioSource>();
ResetPlotData();
StartCoroutine(LoadPlot());
return;
}
/// <summary>
/// 重置
/// </summary>
private void ResetPlotData ()
{
PlotData = new Struct_PlotData();
return;
}
/// <summary>
/// 解析框架文本
/// </summary>
/// <returns></returns>
public IEnumerator LoadPlot ()
{
yield return null;
try
{
var _PlotText = Resources.Load<TextAsset>("TextAsset/Plots/Test").text;
GameAPI.Print($"游戏剧本:{_PlotText}");
PlotxDoc = XDocument.Parse(_PlotText);
//-----开始读取数据
foreach (var item in PlotxDoc.Root.Elements())
{
switch (item.Name.ToString())
{
case "title":
{
PlotData.Title = item.Value;
break;
}
case "Synopsis":
{
PlotData.Synopsis = item.Value;
break;
}
case "BranchPlot":
{
foreach (var BranchItem in item.Elements())
{
PlotData.BranchPlot.Add(BranchItem);
}
break;
}
case "MainPlot":
{
foreach (var MainPlotItem in item.Elements())
{
PlotData.MainPlot.Enqueue(MainPlotItem);
}
break;
}
default:
{
throw new Exception("无法识别的根标签");
}
}
}
}
catch (Exception ex)
{
if (ex.Message != "无法识别的根标签")
{
GameAPI.Print(ex.Message, "error");
}
}
Button_Click_NextPlot();
}
/// <summary>
/// 点击屏幕 下一句
/// </summary>
public void Button_Click_NextPlot ()
{
if (PlotData.MainPlot.Count == 0)
{
GameAPI.Print("游戏结束!");
return;
}
//IsCanJump这里有问题,如果一直点击会为false,而不是说true,这是因为没有点击按钮 ,没有添加按钮
if (GalManager_Text.IsSpeak || !GalManager_Text.IsCanJump) { return; }
if (!PlotData.IsBranch)
{
PlotData.MainPlot.TryDequeue(out PlotData.NowPlotDataNode);//队列出队+内联 出一个temp节点
PlotData.BranchPlotInfo.Clear();
}
else//当前为分支节点
{
//这块得妥善处理
PlotData.NowPlotDataNode = GetBranchByID(PlotData.NowJumpID);
}
PlotData.ChoiceText.Clear();
if (PlotData.NowPlotDataNode == null)
{
GameAPI.Print("无效的剧情结点", "error");
return;
}
switch (PlotData.NowPlotDataNode.Name.ToString())
{
case "AddCharacter"://处理添加角色信息的东西
{
var _ = new Struct_CharacterInfo();
var _From = PlotData.NowPlotDataNode.Attribute("From").Value;
var _CharacterId = PlotData.NowPlotDataNode.Attribute("CharacterID").Value;
_.Name = CharacterConfig.CharacterInfo.GetValue(_From, "Name");
_.CharacterID = _CharacterId;
_.Affiliation = CharacterConfig.Department.GetValue(CharacterConfig.CharacterInfo.GetValue(_From, "Department"), "Name");
var _CameObj = Resources.Load<GameObject>("Common/Gameobject/Galgame/Img-Character");
_CameObj.GetComponent<Image>().sprite = GameAPI.LoadTextureByIO($"{GameAPI.GetWritePath()}/static/Texture2D/Portrait/{CharacterConfig.CharacterInfo.GetValue(_From, "ResourcesPath")}/{CharacterConfig.CharacterInfo.GetValue(_From, "Portrait-Normall")}");
_.CharacterGameObject = Instantiate(_CameObj, Gal_CharacterImg.gameObject.transform);
if (PlotData.NowPlotDataNode.Attributes("SendMessage").Count() != 0)
{
_.CharacterGameObject.GetComponent<GalManager_CharacterAnimate>().Animate_StartOrOutside = PlotData.NowPlotDataNode.Attribute("SendMessage").Value;
}
PlotData.CharacterInfo.Add(_);
Button_Click_NextPlot();
break;
}
case "Speak": //处理发言
{
var _nodeinfo = GetCharacterObjectByName(PlotData.NowPlotDataNode.Attribute("CharacterID").Value);
if (PlotData.NowPlotDataNode.Elements().Count() != 0) //有选项,因为他有子节点数目了
{
GalManager_Text.IsCanJump = false;
foreach (var ClildItem in PlotData.NowPlotDataNode.Elements())
{
if (ClildItem.Name.ToString() == "Choice")
PlotData.ChoiceText.Add(new Struct_Choice(ClildItem.Value, ClildItem.Attribute("JumpID").Value));
}
Gal_Text.StartTextContent(PlotData.NowPlotDataNode.Attribute("Content").Value, _nodeinfo.Name, _nodeinfo.Affiliation, () =>
{
foreach (var ClildItem in GalManager.PlotData.ChoiceText)
{
Gal_Choice.CreatNewChoice(ClildItem.JumpID, ClildItem.Title);
}
});
}
else Gal_Text.StartTextContent(PlotData.NowPlotDataNode.Attribute("Content").Value, _nodeinfo.Name, _nodeinfo.Affiliation);
//处理消息
if (PlotData.NowPlotDataNode.Attributes("SendMessage").Count() != 0)
SendCharMessage(_nodeinfo.CharacterID, PlotData.NowPlotDataNode.Attribute("SendMessage").Value);
if (PlotData.NowPlotDataNode.Attributes("AudioPath").Count() != 0)
StartCoroutine(PlayAudio(Gal_Voice, PlotData.NowPlotDataNode.Attribute("AudioPath").Value));
break;
}
case "ChangeBackImg"://更换背景图片
{
var _Path = PlotData.NowPlotDataNode.Attribute("Path").Value;
Gal_BackImg.SetImage(GameAPI.LoadTextureByIO(_Path));
Button_Click_NextPlot();
break;
}
case "DeleteCharacter":
{
DestroyCharacterByID(PlotData.NowPlotDataNode.Attribute("CharacterID").Value);
break;
}
}
if (PlotData.BranchPlotInfo.Count == 0)
{
PlotData.IsBranch = false;
}
return;
}
public void Button_Click_FastMode ()
{
GalManager_Text.IsFastMode = true;
return;
}
public Struct_CharacterInfo GetCharacterObjectByName (string ID)
{
return PlotData.CharacterInfo.Find(t => t.CharacterID == ID);
}
public XElement GetBranchByID (string ID)
{
if (PlotData.BranchPlotInfo.Count == 0)
foreach (var item in PlotData.BranchPlot.Find(t => t.Attribute("ID").Value == ID).Elements())
{
PlotData.BranchPlotInfo.Enqueue(item);
}
PlotData.BranchPlotInfo.TryDequeue(out XElement t);
return t;
}
/// <summary>
/// 销毁一个角色
/// </summary>
/// <param name="ID"></param>
public void DestroyCharacterByID (string ID)
{
var _ = PlotData.CharacterInfo.Find(t => t.CharacterID == ID);
SendCharMessage(ID, "Quit");
PlotData.CharacterInfo.Remove(_);
}
public void SendCharMessage (string CharacterID, string Message)
{
var _t = GetCharacterObjectByName(CharacterID);
_t.CharacterGameObject.GetComponent<GalManager_CharacterMessage>().HandleMessage(Message);
}
private IEnumerator PlayAudio (AudioSource audioSource, string fileName)
{
//获取.wav文件,并转成AudioClip
GameAPI.Print($"{GameAPI.GetWritePath()}/{fileName}");
UnityWebRequest www = UnityWebRequestMultimedia.GetAudioClip($"{GameAPI.GetWritePath()}/static/Audio/Plot/{fileName}", AudioType.MPEG);
//等待转换完成
yield return www.SendWebRequest();
//获取AudioClip
AudioClip audioClip = DownloadHandlerAudioClip.GetContent(www);
//设置当前AudioSource组件的AudioClip
audioSource.clip = audioClip;
//播放声音
audioSource.Play();
}
private void FixedUpdate ()
{
CharacterNum = PlotData.CharacterInfo.Count;
}
private void Update ()
{
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4187ce6bb31fd5443a2e7eb384144de7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,32 @@
using UnityEngine;
using UnityEngine.UI;
namespace ScenesScripts.GalPlot
{
public class GalManager_BackImg : MonoBehaviour
{
private Image BackImg;
private void Start ()
{
BackImg = this.gameObject.GetComponent<Image>();
}
/// <summary>
/// 直接传递图片
/// </summary>
/// <param name="ImgSprite"></param>
public void SetImage (Sprite ImgSprite)
{
BackImg.sprite = ImgSprite;
}
/// <summary>
/// 从Resources资源文件夹读图片
/// </summary>
/// <param name="ImgSpriteFilePath"></param>
public void SetImage (string ImgSpriteFilePath)
{
BackImg.sprite = Resources.Load<Sprite>(ImgSpriteFilePath);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ae12d1bbe863d1b41a47672fd1c49d9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,190 @@
using Common.Game;
using DG.Tweening;
using TetraCreations.Attributes;
using UnityCustom;
using UnityEngine;
using UnityEngine.UI;
namespace ScenesScripts.GalPlot
{
public class GalManager_CharacterAnimate : MonoBehaviour
{
/// <summary>
/// 出入场出场动画
/// </summary>
[StringInList("ToShow", "Outside-ToLeft", "Outside-ToRight")] public string Animate_StartOrOutside = "ToShow";
/// <summary>
/// 动画
/// <para>Shake:颤抖</para>
/// <para>Shake-Y-Once:向下抖动一次</para>
/// <para>ToGrey:变灰</para>
/// <para>To - :不解释了,移动到指定位置</para>
/// </summary>
[StringInList("Shake", "Shake-Y-Once", "ToLeft", "ToCenter", "ToRight")] public string Animate_type = "Shake";
/// <summary>
/// 角色立绘
/// </summary>
private Image CharacterImg;
[Title("注意,主画布的名称必须是MainCanvas")]
public Canvas MainCanvas;
private void Awake ()
{
CharacterImg = this.gameObject.GetComponent<Image>();
if (MainCanvas == null) MainCanvas = GameObject.Find("MainCanvas").GetComponent<Canvas>();
}
[Button(nameof(Start), "重新执行入场动画")]
private void Start ()
{
HandleInOrOutsideMessgae(Animate_StartOrOutside);
}
[Button(nameof(Start), "重新执行及时动画")]
public void HandleMessgae ()
{
var _rect = CharacterImg.GetComponent<RectTransform>();
switch (Animate_type)
{
case "Shake":
{
_rect.DOShakePosition(0.5f, 30f);
break;
}
case "Shake-Y-Once":
{
_rect.DOAnchorPosY(_rect.anchoredPosition.y - 50f, 0.6f).OnComplete(() =>
{
_rect.DOAnchorPosY(_rect.anchoredPosition.y + 50f, 0.6f);
});
break;
}
case "ToLeft":
{
DOTween.To(() => _rect.anchoredPosition, x => _rect.GetComponent<RectTransform>().anchoredPosition = x, PositionImageInside(_rect, -1), 1f);
break;
}
case "ToCenter":
{
DOTween.To(() => _rect.anchoredPosition, x => _rect.GetComponent<RectTransform>().anchoredPosition = x, PositionImageInside(_rect, 0), 0.8f);
break;
}
case "ToRight":
{
DOTween.To(() => _rect.anchoredPosition, x => _rect.GetComponent<RectTransform>().anchoredPosition = x, PositionImageInside(_rect, 1), 1f);
break;
}
case "Quit":
{
CharacterImg.DOFade(0, 0.7f).OnComplete(() =>
{
Destroy(this.gameObject);
});
break;
}
default:
{
GameAPI.Print("当前剧情文本受损,请重新安装游戏尝试", "error");
break;
}
}
}
/// <summary>
/// 处理出场动画消息
/// </summary>
/// <param name="Messgae"></param>
public void HandleInOrOutsideMessgae (string Messgae)
{
CharacterImg.color = new Color32(255, 255, 255, 0);//完全透明
var rect = this.gameObject.GetComponent<RectTransform>();
switch (Messgae)
{
//逐渐显示
case "ToShow":
{
PositionImageOutside(this.gameObject.GetComponent<RectTransform>(), 0);
break;
}
//从屏幕边缘滑到左侧
case "Outside-ToLeft":
{
PositionImageOutside(this.gameObject.GetComponent<RectTransform>(), -1);
DOTween.To(() => rect.anchoredPosition, x => rect.GetComponent<RectTransform>().anchoredPosition = x, new Vector2(rect.anchoredPosition.x + CharacterImg.sprite.texture.width, rect.anchoredPosition.y), 1f);
break;
}
//从屏幕边缘滑到右侧
case "Outside-ToRight":
{
PositionImageOutside(this.gameObject.GetComponent<RectTransform>(), 1);
DOTween.To(() => rect.anchoredPosition, x => rect.GetComponent<RectTransform>().anchoredPosition = x, new Vector2(rect.anchoredPosition.x - CharacterImg.sprite.texture.width, rect.anchoredPosition.y), 1f);
break;
}
default:
{
GameAPI.Print("当前剧情文本受损,请重新安装游戏尝试", "error");
break;
}
}
//都需要指定的
{
CharacterImg.DOFade(1, 0.7f);
}
}
/// <summary>
/// 设置image的位置到屏幕之外
/// </summary>
/// <param name="ImageGameObject"></param>
/// <param name="Position">-1:左侧 0:中间 1:右侧</param>
private void PositionImageOutside (RectTransform ImageGameObject, int Position)
{
// 获取Image的Rect Transform
switch (Position)
{
case -1:
this.gameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2((-MainCanvas.GetComponent<RectTransform>().sizeDelta.x / 2) - (ImageGameObject.gameObject.GetComponent<Image>().sprite.texture.width / 2), ImageGameObject.anchoredPosition.y);
break;
case 1:
this.gameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2((MainCanvas.GetComponent<RectTransform>().sizeDelta.x / 2) + (ImageGameObject.gameObject.GetComponent<Image>().sprite.texture.width / 2), ImageGameObject.anchoredPosition.y);
break;
case 0:
this.gameObject.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, ImageGameObject.anchoredPosition.y);
break;
default: break;
}
}
/// <summary>
/// 获取image的位置到屏幕之内的位置
/// </summary>
/// <param name="ImageGameObject"></param>
/// <param name="Position">-1:左侧 0:中间 1:右侧</param>
private Vector2 PositionImageInside (RectTransform ImageGameObject, int Position)
{
// 获取Image的Rect Transform
switch (Position)
{
case -1:
return new Vector2((-MainCanvas.GetComponent<RectTransform>().sizeDelta.x / 2) + (ImageGameObject.gameObject.GetComponent<Image>().sprite.texture.width / 2), ImageGameObject.anchoredPosition.y);
case 1:
return new Vector2((MainCanvas.GetComponent<RectTransform>().sizeDelta.x / 2) - (ImageGameObject.gameObject.GetComponent<Image>().sprite.texture.width / 2), ImageGameObject.anchoredPosition.y);
case 0:
return new Vector2(0, ImageGameObject.anchoredPosition.y);
default:
{
GameAPI.Print("当前剧情文本受损,请重新安装游戏尝试", "error");
return new Vector2(0, 0);
}
}
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 54b43f7a21b91734699b948fa62c4456
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,32 @@
using UnityEngine;
using UnityEngine.UI;
namespace ScenesScripts.GalPlot
{
public class GalManager_CharacterImg : MonoBehaviour
{
private Image CharacterImg;
private void Start ()
{
CharacterImg = this.gameObject.GetComponent<Image>();
}
/// <summary>
/// 直接传递图片
/// </summary>
/// <param name="ImgSprite"></param>
public void SetImage (Sprite ImgSprite)
{
CharacterImg.sprite = ImgSprite;
}
/// <summary>
/// 从Resources资源文件夹读图片
/// </summary>
/// <param name="ImgSpriteFilePath"></param>
public void SetImage (string ImgSpriteFilePath)
{
CharacterImg.sprite = Resources.Load<Sprite>(ImgSpriteFilePath);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0a3dc170f98da4848a48e1bb8cc1698a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,17 @@
using UnityEngine;
namespace ScenesScripts.GalPlot
{
public class GalManager_CharacterMessage : MonoBehaviour
{
[SerializeField]
public GalManager_CharacterAnimate Gal_CharacterAnimate;
public void HandleMessage (string MessageContent)
{
Gal_CharacterAnimate.Animate_type = MessageContent;
Gal_CharacterAnimate.HandleMessgae();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 33a5795aa795b1046919e1869c8d65c3
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,35 @@
using UnityEngine;
namespace ScenesScripts.GalPlot
{
public class GalManager_Choice : MonoBehaviour
{
private GameObject GameObject_Choice;
private void Start ()
{
GameObject_Choice = Resources.Load<GameObject>("Common/Gameobject/Galgame/Button-Choice");
}
[SerializeField]
public void CreatNewChoice (string JumpID, string Title)
{
var _ = GameObject_Choice;
_.GetComponent<GalComponent_Choice>().Init(JumpID, Title);
Instantiate(_, this.transform);
return;
}
public void Button_Click_Choice ()
{
for (int i = 0; i < this.transform.childCount; i++)
{
//不可用DestroyImmediate
//原因:DestroyImmediate是同步的,如果使用则会导致每次获取的都是0,无法删除,
Destroy(this.transform.GetChild(i).gameObject);
}
return;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b881bc00d6924c94e9caaeb957f23cde
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,117 @@
using DG.Tweening;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace ScenesScripts.GalPlot
{
public class GalManager_Text : MonoBehaviour
{
public const float DefalutSpeed = 0.045f;
public const float FastSpeend = 0.02f;
/// <summary>
/// 当前是否剧情加速
/// </summary>
public static bool IsFastMode;
/// <summary>
/// 当前是否正在发言
/// 如果为假则可以开始下一句
/// 当这个文本快结束的时候也为True
/// </summary>
public static bool IsSpeak;
/// <summary>
/// 文本内容打字机动画事件
/// </summary>
public static Tweener TextAnimateEvemt;
/// <summary>
/// 文本内容
/// </summary>
public Text Text_TextContent;
/// <summary>
/// 发言人
/// </summary>
public Text Text_CharacterName;
/// <summary>
///是否可以跳过
/// </summary>
public static bool IsCanJump = true;
/// <summary>
/// 对话框右下角的下一句提示
/// </summary>
public GameObject Button_Next;
/// <summary>
/// 对话框是否可见
/// </summary>
public void SetDialogHide (bool value = false)
{
this.gameObject.SetActive(value);
}
/// <summary>
/// 设置对话内容
/// </summary>
/// <param name="TextContent"></param>
public void SetText_Content (string TextContent)
{
Text_TextContent.text = TextContent;
}
/// <summary>
/// 设置发言人的名称
/// </summary>
public void SetText_CharacterName (string CharacterName, string CharacterIdentity)
{
Text_CharacterName.text = $"<b>{CharacterName}</b><size=45> <color=#F684EE>{CharacterIdentity}</color></size>";
}
/// <summary>
/// 开始发言
/// </summary>
/// <param name="TextContent">文本内容</param>
/// <param name="CharacterName">发言人名称</param>
/// <param name="CharacterIdentity">发言人所属</param>
/// <param name="CallBack">回调事件</param>
/// <returns></returns>
public Tweener StartTextContent (string TextContent, string CharacterName, string CharacterIdentity, UnityAction CallBack = null)
{
//100 60 40
void Alwayls ()
{
SetText_CharacterName(CharacterName, CharacterIdentity);
}
if (IsSpeak && Text_TextContent.text.Length >= TextContent.Length * 0.75f && IsCanJump)//当前还正在发言
{
//但是 ,如果当前到了总文本的三分之二,也可以下一句
SetText_Content(TextContent);
IsSpeak = false;
TextAnimateEvemt.Kill();
Button_Next.SetActive(true);
Alwayls();
return TextAnimateEvemt;
}
else if (IsSpeak) return TextAnimateEvemt;
IsSpeak = true;
SetText_Content(string.Empty);//先清空内容
Button_Next.SetActive(false);
Alwayls();
TextAnimateEvemt = Text_TextContent.DOText(TextContent, TextContent.Length * (IsFastMode ? FastSpeend : DefalutSpeed)).SetEase(Ease.Linear).OnComplete(() =>
{
IsSpeak = false;
CallBack?.Invoke();
Button_Next.SetActive(true);
});
return TextAnimateEvemt;
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be1c5720203259149a471ba8c12d2566
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+156
View File
@@ -0,0 +1,156 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using UnityEngine;
using UnityEngine.Networking;
namespace Common.Game
{
/// <summary>
/// 游戏内通用API
/// </summary>
public static class GameAPI
{
/// <summary>
/// 返回可读可写路径
/// PC端:streamingAssetsPath
/// 移动端:Application.persistentDataPath
/// </summary>
/// <returns></returns>
public static string GetWritePath ()
{
#if UNITY_EDITOR || UNITY_STANDALONE
return Application.streamingAssetsPath;
#elif UNITY_IOS || UNITY_ANDROID
return Application.persistentDataPath;
#endif
}
/// <summary>
/// 接管Debug.Log(...)
/// </summary>
/// <param name="_Message">调试信息</param>
/// <param name="_Type">1.debug 2.warn 3.error</param>
public static void Print (object _Message, string _Type = "debug")
{
string currentTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string res = $"[{currentTime}] {_Type} : {_Message}";
switch (_Type)
{
case "debug":
Debug.Log(res);
return;
case "warn":
Debug.LogWarning(res);
return;
case "error":
Debug.LogError(res);
return;
default:
Debug.Log(res);
break;
}
}
/// <summary>
/// 暴力查找一个物体,找不到返回Null
/// </summary>
/// <param name="_Name"></param>
/// <returns></returns>
public static GameObject FindGameObject_Force (string _Name)
{
GameObject[] all = Resources.FindObjectsOfTypeAll(typeof(GameObject)) as GameObject[];
for (int i = 0; i < all.Length; i++)
{
var item = all[i];
if (item.name == _Name) return item;
}
return null;
}
/// <summary>
/// 生成SHA256值
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static string GenerateSha256 (string input)
{
using (SHA256 sha256Hash = SHA256.Create())
{
byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bytes.Length; i++)
{
builder.Append(bytes[i].ToString("x2"));
}
return builder.ToString().ToUpper();
}
}
/// <summary>
/// 通过UnityWebRequest获取本地StreamingAssets文件夹中的文件
/// </summary>
/// <param name="fileName">文件名称</param>
/// <returns></returns>
public static string UnityWebRequestFile (string fileName)
{
string url;
#region 分平台判断 StreamingAssets 路径
//如果在编译器或者单机中
#if UNITY_EDITOR || UNITY_STANDALONE
url = "file://" + Application.dataPath + "/StreamingAssets/" + fileName;
//否则如果在Iphone下
#elif UNITY_IPHONE
url = "file://" + Application.dataPath + "/Raw/"+ fileName;
//否则如果在android下
#elif UNITY_ANDROID
url = "jar:file://" + Application.dataPath + "!/assets/"+ fileName;
#endif
#endregion
UnityWebRequest request = UnityWebRequest.Get(url);
request.SendWebRequest();//读取数据
while (true)
{
if (request.downloadHandler.isDone)//是否读取完数据
{
return request.downloadHandler.text;
}
}
}
/// <summary>
/// 从外部指定文件中加载图片
/// </summary>
/// <returns></returns>
public static Sprite LoadTextureByIO (string Path)
{
FileStream fs = new FileStream(Path, FileMode.Open, FileAccess.Read);
fs.Seek(0, SeekOrigin.Begin);//游标的操作,可有可无
byte[] bytes = new byte[fs.Length];//生命字节,用来存储读取到的图片字节
try
{
fs.Read(bytes, 0, bytes.Length);//开始读取,这里最好用trycatch语句,防止读取失败报错
}
catch (Exception e)
{
Debug.Log(e);
}
fs.Close();//切记关闭
int width = 2048;//图片的宽(这里两个参数可以提到方法参数中)
int height = 2048;//图片的高(这里说个题外话,pico相关的开发,这里不能大于4k×4k不然会显示异常,当时开发pico的时候应为这个问题找了大半天原因,因为美术给的图是6000*3600,导致出现切几张图后就黑屏了。。。
Texture2D texture = new Texture2D(width, height);
if (texture.LoadImage(bytes))
{
return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f));//将生成的texture2d返回,到这里就得到了外部的图片,可以使用了
}
else
{
return null;
}
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dc889f71cb222774084ea6092c6534d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+190
View File
@@ -0,0 +1,190 @@
using System;
using System.Collections;
using System.IO;
namespace Common.Game
{
/// <summary>
/// 游戏配置文件的读取,使用INI
/// </summary>
public class GameConfig
{
private Hashtable keyPairs = new Hashtable();
private string iniFilePath;
private struct SectionPair
{
public string Section;
public string Key;
}
/// <summary>
/// 在给定的路径上打开INI文件并枚举IniParser中的值。
/// </summary>
/// <param name="iniPath">Full path to INI file.</param>
public GameConfig (string iniPath)
{
TextReader iniFile = null;
string strLine = null;
string currentRoot = null;
string[] keyPair = null;
iniFilePath = iniPath;
if (File.Exists(iniPath))
{
try
{
iniFile = new StreamReader(iniPath);
strLine = iniFile.ReadLine();
while (strLine != null)
{
strLine = strLine.Trim();
if (strLine != "")
{
if (strLine.StartsWith("[") && strLine.EndsWith("]"))
{
currentRoot = strLine.Substring(1, strLine.Length - 2);
}
else
{
keyPair = strLine.Split(new char[] { '=' }, 2);
SectionPair sectionPair;
String value = null;
if (currentRoot == null)
currentRoot = "ROOT";
sectionPair.Section = currentRoot;
sectionPair.Key = keyPair[0];
if (keyPair.Length > 1)
value = keyPair[1];
keyPairs.Add(sectionPair, value);
}
}
strLine = iniFile.ReadLine();
}
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (iniFile != null)
iniFile.Close();
}
}
else
{
GameAPI.Print("找不到INI配置,已自动创建", "warn");
Save();
}
}
/// <summary>
/// 返回给定section的值,key对。
/// </summary>
/// <param name="sectionName">Section name</param>
/// <param name="settingName">Key name</param>
public string GetValue (string sectionName, string settingName)
{
SectionPair sectionPair;
sectionPair.Section = sectionName;
sectionPair.Key = settingName;
return (string)keyPairs[sectionPair];
}
/// <summary>
/// 列出给定的Section的所有行
/// </summary>
/// <param name="sectionName">Section to enum.</param>
public string[] EnumSection (string sectionName)
{
ArrayList tmpArray = new ArrayList();
foreach (SectionPair pair in keyPairs.Keys)
{
if (pair.Section == sectionName)
tmpArray.Add(pair.Key);
}
return (string[])tmpArray.ToArray(typeof(string));
}
/// <summary>
/// 向要保存的节添加或替换Value。
/// </summary>
/// <param name="sectionName">Section to add under.</param>
/// <param name="settingName">Key name to add.</param>
/// <param name="settingValue">Value of key.</param>
public void SetValue (string sectionName, string settingName, string settingValue)
{
SectionPair sectionPair;
sectionPair.Section = sectionName;
sectionPair.Key = settingName;
if (keyPairs.ContainsKey(sectionPair))
keyPairs.Remove(sectionPair);
keyPairs.Add(sectionPair, settingValue);
Save();
}
/// <summary>
/// 删除设置
/// </summary>
/// <param name="sectionName">指定Section</param>
/// <param name="settingName">添加的Key</param>
public void Delete (string sectionName, string settingName)
{
SectionPair sectionPair;
sectionPair.Section = sectionName;
sectionPair.Key = settingName;
if (keyPairs.ContainsKey(sectionPair))
keyPairs.Remove(sectionPair);
Save();
}
/// <summary>
/// 保存到新文件。
/// </summary>
/// <param name="newFilePath">新的文件路径。</param>
public void SaveSettings (string newFilePath)
{
ArrayList sections = new ArrayList();
string tmpValue = "";
string strToSave = "";
foreach (SectionPair sectionPair in keyPairs.Keys)
{
if (!sections.Contains(sectionPair.Section))
sections.Add(sectionPair.Section);
}
foreach (string section in sections)
{
strToSave += ("[" + section + "]\r\n");
foreach (SectionPair sectionPair in keyPairs.Keys)
{
if (sectionPair.Section == section)
{
tmpValue = (string)keyPairs[sectionPair];
if (tmpValue != null)
tmpValue = "=" + tmpValue;
strToSave += (sectionPair.Key + tmpValue + "\r\n");
}
}
strToSave += "\r\n";
}
try
{
TextWriter tw = new StreamWriter(newFilePath);
tw.Write(strToSave);
tw.Close();
}
catch (Exception ex)
{
throw ex;
}
}
/// <summary>
/// 将设置保存回ini文件。
/// </summary>
public void Save ()
{
SaveSettings(iniFilePath);
}
public static string GetValue (string Path, string SectionName, string settingName)
{
var _ = new GameConfig(Path);
return _.GetValue(SectionName, settingName);
}
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 60a53357b897c2a439d56a47f6d762dd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
+125
View File
@@ -0,0 +1,125 @@
using System;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace UnityCustom
{
public class StringInList : PropertyAttribute
{
public delegate string[] GetStringList ();
public StringInList (params string[] list)
{
List = list;
}
public StringInList (Type type, string methodName)
{
var method = type.GetMethod(methodName);
if (method != null)
{
List = method.Invoke(null, null) as string[];
}
else
{
Debug.LogError("NO SUCH METHOD " + methodName + " FOR " + type);
}
}
public string[] List
{
get;
private set;
}
}
#if UNITY_EDITOR
[CustomPropertyDrawer(typeof(StringInList))]
public class StringInListDrawer : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI (Rect position, SerializedProperty property, GUIContent label)
{
var stringInList = attribute as StringInList;
var list = stringInList.List;
if (property.propertyType == SerializedPropertyType.String)
{
int index = Mathf.Max(0, Array.IndexOf(list, property.stringValue));
index = EditorGUI.Popup(position, property.displayName, index, list);
property.stringValue = list[index];
}
else if (property.propertyType == SerializedPropertyType.Integer)
{
property.intValue = EditorGUI.Popup(position, property.displayName, property.intValue, list);
}
else
{
base.OnGUI(position, property, label);
}
}
}
#endif
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 69e0aabd822d876489d488841d8d00f6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: