自用Unity剧情系统

这篇具有很好参考价值的文章主要介绍了自用Unity剧情系统。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

主要展示剧情部分

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;
        }
    }

}

最终效果

unity剧情编辑器,lua,UNITY学习之路,unity,游戏引擎

 第二种,类似文字游戏的,用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

效果

unity剧情编辑器,lua,UNITY学习之路,unity,游戏引擎文章来源地址https://www.toymoban.com/news/detail-673746.html

到了这里,关于自用Unity剧情系统的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Unity编辑器扩展 | 编辑器扩展基础入门

    前言 当谈到游戏开发工具,Unity编辑器是一个备受赞誉的平台。它为开发者提供了一个强大且灵活的环境,使他们能够创建令人惊叹的游戏和交互式体验。 然而,Unity编辑器本身也是可以扩展和定制的,这为开发者提供了进一步提升工作流程和增强功能的机会。 在Unity 编辑器

    2024年02月10日
    浏览(77)
  • 【Unity编辑器扩展】 | 编辑器扩展入门基础

    前言 当谈到游戏开发工具,Unity编辑器是一个备受赞誉的平台。它为开发者提供了一个强大且灵活的环境,使他们能够创建令人惊叹的游戏和交互式体验。 然而,Unity编辑器本身也是可以扩展和定制的,这为开发者提供了进一步提升工作流程和增强功能的机会。 在Unity 编辑器

    2024年02月10日
    浏览(84)
  • Unity 可视化节点编辑器(GraphView、编辑器扩展)

      前几天把导师的项目打包发布交了一稿,这半个星期除了再把项目缝缝补补外(说实话项目做到后边实在有些无聊,都是些琐碎的东西而且自己也学不到什么,纯粹是 浪费 消磨时间)无聊逛Unity商店发现了个有意思的东西,说实话一开始我以为只是单纯绘制的2D动画:

    2024年02月12日
    浏览(63)
  • Unity编辑器紫色

    紫色原因是因为编辑器内跑了其他平台的shader兼容性导致的,需要动态的去修改shader,主要用到Unity的api :  Shader.Find(shaderName); 具体的工具代码如下: Shader的添加形式大概有两种: 跟随AssetBundle 打进包里面,可以直接使用       自建材质  

    2024年02月03日
    浏览(57)
  • Unity 编辑器常用方法

    自动根据RuntimeInitializeLoadType选择一个时机执行。静态方法 AfterSceneLoad 在场景加载之后初始化子系统。这意味着子系统将在场景加载完成后进行初始化,并在场景加载后的脚本执行时可用。 BeforeSceneLoad 在场景加载之前初始化子系统。这意味着子系统将在场景加载之前进行初始

    2024年02月07日
    浏览(54)
  • Unity编辑器扩展(外挂)

    每日一句:未来的样子藏在现在的努力里 目录 什么是编译器开发 C#特性[System.Serializable] 特殊目录 命名空间 /*检视器属性控制*/     //添加变量悬浮提示文字     //给数值设定范围(最小0,最大150) //指定输入框,拥有5行 //默认显示5行,最多显示10行内容,再多用滚动条控

    2024年01月24日
    浏览(88)
  • 修改unity代码编辑器

    将   Unity  自带的 MonoDevelop  替换成微软的 VS  2017 编辑器。 操作步骤 : 第一步:选择Edit选项卡下的Preferences..选项 第二步:选择External Tools 第三步:修改右侧的External Script Editor,选择VS2017  有的小伙伴可能下拉框中没有VS2017选项,没关系,点击Brower..,找到VS2017的应用程序

    2024年02月11日
    浏览(48)
  • 【Unity知识树】Unity编辑器加速小技巧

      运行游戏时不重新编译脚本 现象:每次运行游戏都会弹出一个重新加载脚本的框,耽误几秒钟时间。     提速技巧:勾选工程设置 编辑器 Enter Play Mode Options的选项即可。     以后如果脚本没有改动,运行时不会重新编译。   取消不必要的csproj脚本工程文件 新版本的Uni

    2024年02月12日
    浏览(42)
  • 面试题 :Unity编辑器基础

      1、请描述游戏动画有几种,以及其原理。 关键帧动画 :每一帧动画序列当中包含了顶点的空间位置信息以及改变量,然后通过插值运算,得出动画效果。选中某一游戏对象,创建animation,添加属性Transform,MeshRender、collider。还可以添加关键帧,在关键帧上Add Animation Even

    2023年04月17日
    浏览(52)
  • Unity编辑器拓展-Odin

    Unity不支持泛型类型序列化,例如字典原生Unity不支持序列化,而Odin可以继承序列化的Mono实现 功能强大且使用简单,原生Unity想实现一些常见的功能需要额外自己编写Unity扩展的编码,实现功能只需要加一个特性即可Odin帮忙写好了内部管理和实现 编辑器的窗口实现简单且美观

    2024年02月08日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包