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)");

  

时间: 2024-08-27 00:05:23

Unity3d 解析文本执行已注册的自定函数的相关文章

springIOC源码解析之BeanDefinition的注册

ApplicationContext类结构 context是一个存储上下文结构的东西,里面会引用BeanFactory  BeanFactory类结构 我们从这句代码开始分析,(本文spring采用的是4.2.4的版本) ApplicationContext con = new FileSystemXmlApplicationContext("src/test/java/com//spring/test/beans-factorybean.xml"); public FileSyste

php批量检查域名是否已注册并获取注册域名的注册公司

一个小任务,给了一个包含了几千条域名的Excel,检测是否已经注册,注册的话获取注册公司,并获取对应网站是否能正常打开,最终以Excel文件呈现. 1.起初,想到的就是读取域名,通过http调用 xinnet或者是万网的 whois查询接口查询,而后将页面结果正则匹配Registrant:,registrant organization:,registrant name:字段,获取该行:后边的内容.这样的结果就是很乱,很多注册公司不用这三个字段,没有一个统一的标准来判定是否注册及注册公司. 2.

无法读取此系统上以前注册的服务器的列表。请在“已注册的服务器”窗口中重新注册您的服务器

环境: 服务器系统: 数据库版本:Microsoft SQL Server 2008 R2 错误提示如下图: 截图来自:点击打开链接 详细错误信息: 有关调用实时(JIT)调试而不是此对话框的详细信息, 请参见此消息的结尾. ************** 异常文本 ************** Microsoft.SqlServer.Management.RegisteredServers.RegisteredServerException: 无法读取此系统上以前注册的服务器的列表.请在"已注册

管理员权限执行批处理和静默执行regsvr32注册

公司软件部署经常需要注册.com组件,之前的bat批处理需要右键管理员权限运行才行.这里发布一小段命令可以免去这个步骤. @echo off color 0 REM ________________________________________________________________ >nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system&q

第十三章 解析文本

第十三章解析文本 结构化的文本格式,对我和机器来说,都具有可读性,在计算机界几乎从开始就流行,编程语言就是一个很好的示例,当然还有其他许多应用.解析文本,与前面一章"面向语言编程"是相关联的,因为,如果想要实现一种语言,不嵌入在 F# 中,那么,第一步就是要为这种格式创建解析器.然而,解析已有文本格式是有许多原因的,因此,,没有把它限制在解析语言这一章中.[ 也是这一章从原来第十二章中分出来的原因] 简单的文本格式,比如逗号分隔(comma separated values,CSV)格

RequestMapping 注解的解析、匹配、注册

RequestMapping 注解的解析.匹配.注册 1)创建 RequestMappingHandlerMapping 实例时会触发 afterPropertiesSet 调用. 2)读取容器中所有带有 Controller 或 RequestMapping 注解的类. 3)读取此类中所有满足过滤器 ReflectionUtils.USER_DECLARED_METHODS 的方法, 读取处理方法上的 RequestMapping 注解信息, 将其解析并封装为 RequestMappingIn

myBatis中的注解@Param、返回值为Map、JAVA读取Excel并解析文本、Class.getResource()和ClassLoader.getResource()

myBatis中的注解@Param:http://blog.csdn.net/gao36951/article/details/44258217:  http://www.cnblogs.com/thomas12112406/p/6217211.html. myBatis返回值为Map:http://blog.csdn.net/werewr342352321df/article/details/11892755. ====================== JAVA读取Excel并解析文本:h

JS的解析与执行过程(javascript面向对象一)

JS的解析与执行过程 全局中的解析和执行过程 预处理:创建一个词法环境(LexicalEnvironment,在后面简写为LE),扫描JS中的用声明的方式声明的函数,用var定义的变量并将它们加到预处理阶段的词法环境中去. 一.全局环境中如何理解预处理 比如说下面的这段代码: var a = 1;//用var定义的变量,以赋值 var b;//用var定义的变量,未赋值 c = 3;//未定义,直接赋值 function d(){//用声明的方式声明的函数 console.log('hello'

WordPress 前端投稿/编辑插件 DJD Site Post(支持游客和已注册用户)

说到前端用户投稿,倡萌之前推荐过3个不错的插件: WordPress匿名投稿插件:DX-Contribute (有朋友反馈不能用) WordPress投稿插件:User Submitted Posts (貌似没有集成编辑器,编辑文章不是很方便) WordPress 前端用户中心插件:WP User Frontend (免费版功能不太齐全) 今天要给大家推荐的这个 WordPress 前端投稿/编辑插件 DJD Site Post,它不仅支持已注册用户投稿,还支持给匿名游客投稿,而且在投稿界面添加