您的位置:首页 > 移动开发 > Unity3D

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

2016-03-01 17:43 489 查看
最近有个需求是想让程序解析策划编辑一个文本生成一段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)");


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: