Unity3d 解析文本执行已注册的自定函数
最近有个需求是想让程序解析策划编辑一个文本生成一段CG,内容使用大致是这样
cgSetCameraEx(118.6324,30.71189,75.55666,45,-45,0,0)
cgCloneMyPlayer(1)
cgSetPosDir(1,109,80,0)
cgSetCameraEx(114.18,23.17,96.9,11.51974,-61.49661,-3.384705,3.5)
cgCreateActor(2,25,108,100,90)
cgWait(0.2)
cgMove(1,109.7,100,9,false)
cgWait(3)
cgFaceToActor(1,2)
cgWait(1.5)
cgPopTalk(1,1,2)
我的做法是借助一个第三方库NCalc,把自定义的函数注册到解析器里,让解析器去Load这段文本
using UnityEngine;
using System.Collections;
using NCalc;
using System.Collections.Generic;
using System; //解析字符串表达式执行函数 public class CallFunctionScript
{
//缓存函数表
private readonly Dictionary<string, Func<Expression[], object>> mRegisterFunctions = new Dictionary<string, Func<Expression[], object>>(); //注册可被执行的函数
//注册的函数格式满足 public static object Func(Expression[] args)
//函数返回值不能是null,如果不需要返回值可以返回1
public void RegisterFunction(string funcName, Func<Expression[], object> func)
{
if (!mRegisterFunctions.ContainsKey(funcName))
{
mRegisterFunctions.Add(funcName, func);
}
else
{
UnityEngine.Debug.LogError("duplicate func " + funcName);
}
} //反注册所有函数
public void UnRgisterAllFunction()
{
mRegisterFunctions.Clear();
} //执行函数
public object Execute(string expression)
{
var exp = new Expression(expression); //函数代理
exp.EvaluateFunction += delegate(string name, FunctionArgs args)
{
Func<Expression[], object> func;
if (mRegisterFunctions.TryGetValue(name, out func))
{
object result = null;
try
{
result = func(args.Parameters);
}
catch (Exception ex)
{
UnityEngine.Debug.LogError("Execute "+name + "() Error:" + ex.ToString());
}
finally
{
args.Result = result;
}
}
else
{
UnityEngine.Debug.LogError("Can't find function [" + name+"]");
}
}; try
{
return exp.Evaluate();//执行函数
}
catch (Exception ex)
{
Debug.LogError("Evaluate \"" + expression + "\" Error: "+ex.ToString());
return null;
}
}
}
//被注册的函数如这样
public static class CGFunctionWrapper
{
public static object cgCloneMyPlayer(Expression[] args)
{
if (args.Length < 1)
{
Logger.Error("cgCloneMyPlayer() args<[1]");
return 0;
}
PlayCG.Instance.cgCloneMyPlayer(
Convert.ToInt32(args[0].Evaluate())
);
return 1;
}
}
使用方法
public CallFunctionScript mExecutor = new CallFunctionScript();
mExecutor.RegisterFunction("cgCloneMyPlayer", CGFunctionWrapper.cgCloneMyPlayer);
mExecutor.Execute("cgCloneMyPlayer(1)");
Unity3d 解析文本执行已注册的自定函数的更多相关文章
- springIOC源码解析之BeanDefinition的注册
ApplicationContext类结构 context是一个存储上下文结构的东西,里面会引用BeanFactory BeanFactory类结构 我们从这句代码开始分析,(本文spring采用的 ...
- 解决IE11出现异常SCRIPT5011:不能执行已释放Script的代码
功能概述: 最近做了一个教育科研系统,由于时间比较紧,所以能集成的功能都尽量做到了一起,其中一个上传附件的功能,在基类控制器BaseController 中建了一个Action返回视图,其他需要上传附 ...
- Python 一键拉取Git分支源码自动解析并执行SQL语句
基于Python实现自动拉取Git分支源码自动解析并执行SQL语句 by:授客 QQ:1033553122 1.代码用途 开发过程中,研发人员会提交SQL更新脚本到Git源码库,然后测试负责去拉取这些 ...
- 【Dubbo 源码解析】04_Dubbo 服务注册&暴露
Dubbo 服务注册&暴露 Dubbo 服务暴露过程是通过 com.alibaba.dubbo.config.spring.ServiceBean 来实现的.Spring 容器 refresh ...
- [SQL Server]无法创建 SSIS 运行时对象,请验证 DTS.dll 是否可用及是否已注册
很大可能是SQL Server Management Studio(SSMS)版本与当前操作系统不兼容造成的,与数据库本身没有关系,这种情况基本无解,不过可以使用其他机器连本机数据库导入导出数据. 今 ...
- ie11 SCRIPT5011:不能执行已释放Script的代码
依照我遇到的问题为例: (我的页面结构为:父页面中嵌套有iframe子页面) 1.造成这种情况的原因是:父页面初始化声明变量a为数组(数组对象是引用类型,赋值传递的是地址),创建iframe子页面后给 ...
- RequestMapping 注解的解析、匹配、注册
RequestMapping 注解的解析.匹配.注册 1)创建 RequestMappingHandlerMapping 实例时会触发 afterPropertiesSet 调用. 2)读取容器中所有 ...
- 我该如何学习spring源码以及解析bean定义的注册
如何学习spring源码 前言 本文属于spring源码解析的系列文章之一,文章主要是介绍如何学习spring的源码,希望能够最大限度的帮助到有需要的人.文章总体难度不大,但比较繁重,学习时一定要耐住 ...
- JS的解析与执行过程
JS的解析与执行过程 全局中的解析和执行过程 预处理:创建一个词法环境(LexicalEnvironment,在后面简写为LE),扫描JS中的用声明的方式声明的函数,用var定义的变量并将它们加到预处 ...
随机推荐
- 在Linux下如何使用GCC编译程序、简单生成 静态库及动态库
最近在编写的一个Apache kafka 的C/C++客户端,,在看他写的 example中,他的编译是用librdkafka++.a和librdkafka.a 静态库编译的,,,而我们这 ...
- fatal: Paths with -a does not make sense.
git commit -am '*屏蔽设置缓存' htdocs/s.php fatal: Paths with -a does not make sense. 应该用下面的这样. git commit ...
- 2015年12月28日 Java基础系列(六)流
2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流2015年12月28日 Java基础系列(六)流
- R语言 recommenderlab 包
recommend li_volleyball 2016年3月20日 library(recommenderlab) ## Warning: package 'recommenderlab' was ...
- Ruby中Block, Proc, 和Lambda
Block Blocks就是存放一些可以被执行的代码的块,通常用do...end 或者 {}表示 例如: [1, 2, 3].each do |num| puts num end [1, 2, 3]. ...
- POJ 1845 Sumdiv
快速幂+等比数列求和.... Sumdiv Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 12599 Accepted: 305 ...
- poj 3744 Scout YYF I(概率dp,矩阵优化)
Scout YYF I Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 5020 Accepted: 1355 Descr ...
- 2015多校.MZL's endless loop(欧拉回路的机智应用 || 构造)
MZL's endless loop Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Oth ...
- bootstrap-carousel
功能:轮播插件carousel, 主要用于首页大图片的显示与左右按钮的点击滑动图片 插件:carouse.js 要点:class="carousel slide"里的data-sl ...
- 第四章第四个例题(LRJ)
半年了,最起码的编程能力也谈不上啊,思维神马就更不不敢说了. 互联网时代讲求效率,走得慢和不走没有区别了. The war is on. (buhuidetiduokanduodajibianyehu ...