一线天关卡脚本转为 slua

本贴最后更新于 1982 天前,其中的信息可能已经事过景迁

2018/2/14
在新版本里,已经决定不要在战斗中使用 slua 脚本
因为一个场景里有最多 16 个人物角色,各种关卡道具,和道具刷新点以及可破坏物件等,全部用脚本来每一帧刷新会严重的降低帧率(但是原作是 C++ 和 pscript 的架构不一样)
所以以下文章意义不大,可以不用浪费时间了。
unity 里引入脚本,还是单纯的调用一下接口好了,比如 UI/刷物品
不要试图在战斗部分使用脚本(就是不要每帧 update),这个性能损失得不偿失

这篇日志只是还原一下原版本里的 sn03 关卡里,拒马和落石,以及开门的机关等的处理
落石是受击后播放动画滚动到悬崖下,然后碎裂,同时播放音效,落石动画时还带有攻击盒,可以攻击任意人物角色
拒马是一个长木栅栏,他背后有一个隐形的阻碍盒阻挡了角色的前进,当角色击打拒马时,拒马会随着血量的减少,播放不同的几个状态下的受击动画,当拒马的血量小于 0 时,会播放碎裂动画,同时把隐形的盒子取消激活 SetActive(false)
当碎裂动画结束时,其被 SetActive(false),这样角色就能够继续前进
开门机关,类似一个模型按钮,当受击时,他会使门播放开门动画,并且停留在最后一帧,而门在 OnIdle 里会判断,距离开门时刻有多久了,超过了设定的关门时间,门就会播放关门动画。

以下脚本是从原版里改为 slua 后的脚本
sn03.pst=>sn03.txt
关卡剧本 sn03-.pst 还没有改
这个脚本主要负责一线天关卡里的(关口尖刺)(拒马(木栅栏))(滚石)而其他的瓶子罐子,还有武器盒子,buff 盒子我都注释掉了
尖刺通过加载关卡 des 文件时,里面有 custom{ name=damage100}之类的来设置伤害值
SetSceneItem(name, "attribute", "damage", 1);是设置其能够攻击游戏阵营角色
SetSceneItem(name, "name", "machine", 1);是设置其不要上下移动并绕 Y 轴旋转
SetSceneItem("D_ADoor01", "attribute", "collision", 1);可以与角色碰撞,即角色不能穿越
SetSceneItem("D_ADoor01", "attribute", "damagevalue", g_iLevel03DoorDamage);设置道具如果可以攻击角色,那么每次打角色多少血
SetSceneItem("D_Abutton01", "pose", 0, 0);播放 0 编号动作,不循环

这个脚本需要引用 main 脚本里定义的一些公共函数,公共函数在 main 脚本里调用到原生 c#类 这里 main 里引用了 U3D 类,调用这个类的静态函数提供脚本的具体实现
main.txt 脚本

--脚本全局常量
--item parameters for each level
--小箱子HP
g_iBoxMaxHP = 100;	
--大箱子HP
g_iBBoxMaxHP = 200;
--椅子HP
g_iChairMaxHP = 100;
--桌子HP
g_iDeskMaxHP = 150;
--水罐HP
g_iJugMaxHP = 100;
--拒马HP
g_iGiMaMaxHP = 3000;
-- special parameter for each level
g_iLevel01StoneMaxHP = 500;
g_iLevel03DoorWaitTime = 7000;
g_iLevel03GiMaMaxHP = 3000;
g_iLevel03StoneDamage = 300;
g_iLevel03DoorDamage = 50;
g_iLevel04GiMaMaxHP = 10000;
g_iLevel07KnifeDamage = 300;
g_iLevel07PinDamage = 200;
g_iLevel08StickDamage = 300;
g_iLevel09StepTime = 1000;
g_iLevel11DoorMaxHP = 10000;
g_iLevel12StoveHP = 5000;
g_iLevel13BridgeHP = 4000;

function main()
end

function load()
end

function save()
U3D.SaveClean()
--U3D.SaveState("answer", answer)
--U3D.SaveState("getreward", getreward)
--U3D.SaveState("npcId", npcId)
--U3D.SaveState("chufu_npc_talk", chufu_npc_talk)
U3D.SaveDone()
end

function SetSceneItem(a, b, c, d)
	U3D.SetSceneItem(a, b, c, d)
end

function MakeString(b, c)
	str = string.format("%02d",c)
	return (b..str)
end

function GetSceneItem(a, b)
	return U3D.GetSceneItem(a, b)
end

function GetTeam(a)
	return U3D.GetTeam(a)--得到角色属于流星或者蝴蝶
end

function Output(a)
	print(a)
end

function NetEvent(a)
	U3D.NetEvent(a)
end

function CreateEffect(a, b)
	U3D.CreateEffect(a, b)
end

///////////////////////////////////////main脚本结束//////////////////////////////////////

关卡sn03.txt原版里sn03.pst)
local g_bStone01Active;
local g_bStone02Active;

local g_iADoor02OpenTime;
local g_iBDoor01OpenTime;
local g_iDoorWaitTime = 7000;

local g_iPdoorMaxHP = 2000;
local g_iPdoorState1HP;
local g_iPdoorState2HP;
local g_iPdoorState3HP;
local g_iPdoorState4HP;
local g_iPdoorState5HP;

local g_bAPdoorAlive;
local g_iAPdoorState;
local g_iAPdoorShakePose;
local g_iAPdoorHP;

local g_bBPdoorAlive;
local g_iBPdoorState;
local g_iBPdoorShakePose;
local g_iBPdoorHP;

local function Scene_OnLoad()
	local i;
	local name;
	
	g_iDoorWaitTime = g_iLevel03DoorWaitTime;
	g_iPdoorMaxHP = g_iLevel03GiMaMaxHP;
	
	g_iPdoorState1HP = (g_iPdoorMaxHP*3)/4;
	g_iPdoorState2HP = (g_iPdoorMaxHP*2)/4;
	g_iPdoorState3HP = (g_iPdoorMaxHP*1)/4;
	g_iPdoorState4HP = 0;

	SetSceneItem("D_ston01", "name", "machine", 1);
	SetSceneItem("D_ston02", "name", "machine", 1);

	for i=1,10 do
		name = MakeString("D_sn03t", i);
		SetSceneItem(name, "name", "machine", 1);
		SetSceneItem(name, "attribute", "damage", 1);
	end
	
	SetSceneItem("D_Abutton01", "name", "machine", 1);
	SetSceneItem("D_Abutton02", "name", "machine", 1);
	SetSceneItem("D_ADoor01", "name", "machine", 1);
	SetSceneItem("D_ADoor01", "attribute", "collision", 1);
	SetSceneItem("D_ADoor01", "attribute", "damagevalue", g_iLevel03DoorDamage);
	SetSceneItem("D_ADoor01", "attribute", "damage", 1);

	SetSceneItem("D_Bbutton01", "name", "machine", 1);
	SetSceneItem("D_Bbutton02", "name", "machine", 1);
	SetSceneItem("D_BDoor01", "name", "machine", 1);
	SetSceneItem("D_BDoor01", "attribute", "collision", 1);
	SetSceneItem("D_BDoor01", "attribute", "damagevalue", g_iLevel03DoorDamage);
	SetSceneItem("D_BDoor01", "attribute", "damage", 1);

	SetSceneItem("D_APdoor01", "name", "machine", 1);
	SetSceneItem("D_APdoor01", "attribute", "damagevalue", 20);
	
	SetSceneItem("D_BPdoor01", "name", "machine", 1);
	SetSceneItem("D_BPdoor01", "attribute", "damagevalue", 20);

	SetSceneItem("D_APd02Box01", "name", "machine", 1);
	SetSceneItem("D_BPd02Box01", "name", "machine", 1);
end

local function Scene_OnInit()
	g_bStone01Active = 1;
	g_bStone02Active = 1;

	SetSceneItem("D_ston01", "pose", 0, 0);
	SetSceneItem("D_ston01", "attribute", "active", 1);
	SetSceneItem("D_ston01", "attribute", "collision", 1);
	SetSceneItem("D_ston01", "attribute", "damage", 0);
	SetSceneItem("D_ston01", "attribute", "damagevalue", g_iLevel03StoneDamage);
	
	SetSceneItem("D_ston02", "pose", 0, 0);
	SetSceneItem("D_ston02", "attribute", "active", 1);
	SetSceneItem("D_ston02", "attribute", "collision", 1);
	SetSceneItem("D_ston02", "attribute", "damage", 0);
	SetSceneItem("D_ston02", "attribute", "damagevalue", g_iLevel03StoneDamage);
	
	SetSceneItem("D_Abutton01", "pose", 0, 0);
	SetSceneItem("D_Abutton02", "pose", 0, 0);
	SetSceneItem("D_ADoor01", "pose", 0, 0);
	
	SetSceneItem("D_Bbutton01", "pose", 0, 0);
	SetSceneItem("D_Bbutton02", "pose", 0, 0);
	SetSceneItem("D_BDoor01", "pose", 0, 0);

	SetSceneItem("D_APdoor01", "pose", 0, 0);
	SetSceneItem("D_APdoor01", "attribute", "collision", 0);
	SetSceneItem("D_APdoor01", "attribute", "damage", 0);
	SetSceneItem("D_APd02Box01", "attribute", "collision", 1);
	
	SetSceneItem("D_BPdoor01", "pose", 0, 0);
	SetSceneItem("D_BPdoor01", "attribute", "collision", 0);
	SetSceneItem("D_BPdoor01", "attribute", "damage", 0);
	SetSceneItem("D_BPd02Box01", "attribute", "collision", 1);

	g_iAPdoorHP = g_iPdoorMaxHP;
	g_bAPdoorAlive = 1;
	g_iAPdoorState = 1;
	g_iAPdoorShakePose = 1;
	
	g_iBPdoorHP = g_iPdoorMaxHP;
	g_bBPdoorAlive = 1;
	g_iBPdoorState = 1;
	g_iBPdoorShakePose = 1;

	--InitBoxes(g_iNumBoxes);
	--InitBBoxs(g_iNumBBoxes);//函数名不对,可能是原版就有BUG 应该是InitBBoxes
	--InitChairs(g_iNumChairs);
	--InitDeskes(g_iNumDeskes);
	--InitJugs(g_iNumJugs);
end

function D_APdoor01_OnAttack(id, character, damage)
	if (GetTeam(character) ==1) then
		return 0;
	end
	
	local state;

	g_iAPdoorHP = g_iAPdoorHP - damage;
	
	if ( g_iAPdoorState==1 and g_iAPdoorHP < g_iPdoorState1HP ) then
	
		g_iAPdoorState = g_iAPdoorState + 1;
		g_iAPdoorShakePose = 3;
		NetEvent(1);
		SetSceneItem(id, "pose", 2, 0);
		NetEvent(0);
	end
	
	if ( g_iAPdoorState==2 and g_iAPdoorHP < g_iPdoorState2HP ) then
		g_iAPdoorState = g_iAPdoorState  + 1;
		g_iAPdoorShakePose = 5;
		NetEvent(1);
		SetSceneItem(id, "pose", 4, 0);
		NetEvent(0);
	end
	
	if ( g_iAPdoorState==3 and g_iAPdoorHP < g_iPdoorState3HP ) then
	
		g_iAPdoorState = g_iAPdoorState + 1;
		g_iAPdoorShakePose = 7;
		NetEvent(1);
		SetSceneItem(id, "pose", 6, 0);
		NetEvent(0);
	end
	
	if ( g_iAPdoorState==4 and g_iAPdoorHP < 0 ) then
	
		g_iAPdoorState = g_iAPdoorState + 1;
		NetEvent(1);
		CreateEffect(id, "GiMaBRK");
		SetSceneItem(id, "attribute", "interactive", 0);
		SetSceneItem(id, "attribute", "collision", 0);
		SetSceneItem(id, "pose", 8, 0);
		SetSceneItem("D_APd02Box01", "attribute", "active", 0);
		NetEvent(0);
	end

	state = GetSceneItem(id, "state");
	if ( state==3 ) then
		NetEvent(1);
		CreateEffect(id, "GiMaHIT");
		SetSceneItem(id, "pose", g_iAPdoorShakePose, 0);
		NetEvent(0);
	end
end

function D_APdoor01_OnIdle(id)
	if ( g_iAPdoorState==5 and g_bAPdoorAlive==1 ) then
		local pose;
		pose = GetSceneItem(id, "pose");
		if (pose ~= 8 ) then
			return 0;
		end
		local state;
		state = GetSceneItem(id, "state");
		if ( state==3 ) then
			g_bAPdoorAlive = 0;
			NetEvent(1);
			SetSceneItem("D_APdoor01", "attribute", "active", 0);
			NetEvent(0);
		end
	end
end

function D_BPdoor01_OnAttack(id, character, damage)
	if ( GetTeam(character)==2 ) then
		return 0;
	end
	
	local state;

	g_iBPdoorHP = g_iBPdoorHP - damage;
	
	if ( g_iBPdoorState==1 and g_iBPdoorHP < g_iPdoorState1HP ) then
		g_iBPdoorState = g_iBPdoorState + 1;
		g_iBPdoorShakePose = 3;
		NetEvent(1);
		SetSceneItem(id, "pose", 2, 0);
		NetEvent(0);
	end
	
	if ( g_iBPdoorState==2 and g_iBPdoorHP < g_iPdoorState2HP ) then
		g_iBPdoorState = g_iBPdoorState + 1;
		g_iBPdoorShakePose = 5;
		Output("Change State 3");
		NetEvent(1);
		SetSceneItem(id, "pose", 4, 0);
		NetEvent(0);
	end
	
	if ( g_iBPdoorState==3 and g_iBPdoorHP< g_iPdoorState3HP ) then
		g_iBPdoorState = g_iBPdoorState + 1;
		g_iBPdoorShakePose = 7;
		Output("Change State 4");
		NetEvent(1);
		SetSceneItem(id, "pose", 6, 0);
		NetEvent(0);
	end
	
	if ( g_iBPdoorState==4 and g_iBPdoorHP < g_iPdoorState4HP ) then
		g_iBPdoorState = g_iBPdoorState + 1;
		NetEvent(1);
		CreateEffect(id, "GiMaBRK");
		SetSceneItem(id, "attribute", "interactive", 0);
		SetSceneItem(id, "attribute", "collision", 0);
		SetSceneItem(id, "pose", 8, 0);
		SetSceneItem("D_BPd02Box01", "attribute", "active", 0);
		NetEvent(0);
	end

	state = GetSceneItem(id, "state");
	if ( state==3 ) then
		NetEvent(1);
		CreateEffect(id, "GiMaHIT");
		SetSceneItem(id, "pose", g_iBPdoorShakePose, 0);
		NetEvent(0);
	end
end

function D_BPdoor01_OnIdle(id)
	if ( g_iBPdoorState==5 and g_bBPdoorAlive==1 ) then
		local pose = GetSceneItem(id, "pose");
		if ( pose~=8 ) then
			return 0;
		end
		local state;
		state = GetSceneItem(id, "state");
		if ( state==3 ) then
			g_bBPdoorAlive = 0;
			NetEvent(1);
			SetSceneItem("D_BPdoor01", "attribute", "active", 0);
			NetEvent(0);
		end
	end
end

function D_ston01_OnAttack(id, character, damage)
	local pose = GetSceneItem(id, "pose");
	if ( pose==1 ) then
		return 0;
	end

	NetEvent(1);
	CreateEffect(id, "StoneFIL");
	CreateEffect("D_Sston01", "StoneFIL");
	SetSceneItem(id, "pose", 1, 0);
	SetSceneItem(id, "attribute", "collision", 0);
	SetSceneItem(id, "attribute", "damage", 1);
	NetEvent(0);
end

function D_ston01_OnIdle(id)
	if ( g_bStone01Active==1 ) then
		local pose = GetSceneItem(id, "pose");
		if ( pose==0 ) then
			return 0;
		end
		local state = GetSceneItem(id, "state");
		if ( state==3 ) then
			g_bStone01Active=0;
			NetEvent(1);
			SetSceneItem(id, "attribute", "active", 0);
			NetEvent(0);
		end
	end
end

function D_ston02_OnAttack(id, character, damage)
	local pose = GetSceneItem(id, "pose");
	if ( pose==1 ) then
		return 0;
	end
	
	NetEvent(1);
	CreateEffect(id, "StoneFIL");
	CreateEffect("D_Sston02", "StoneFIL");
	SetSceneItem(id, "pose", 1, 0);
	SetSceneItem(id, "attribute", "collision", 0);
	SetSceneItem(id, "attribute", "damage", 1);
	NetEvent(0);
end

function D_ston02_OnIdle(id)
	if ( g_bStone02Active==1 ) then
		local pose = GetSceneItem(id, "pose");
		if ( pose==0 ) then
			return 0;
		end
		local state = GetSceneItem(id, "state");
		if ( state==3 ) then
			g_bStone02Active = 0;
			NetEvent(1);
			SetSceneItem(id, "attribute", "active", 0);
			NetEvent(0);
		end
	end
end

function D_Abutton01_OnAttack(id, character, damage)
	local pose = GetSceneItem("D_ADoor01", "pose");
	if ( pose~=0 ) then
		return 0;
	end
	g_iADoor02OpenTime = Misc("gettime");
	NetEvent(1);
	SetSceneItem("D_ADoor01", "pose", 1, 0);
	SetSceneItem(id, "pose", 1, 0);
	NetEvent(0);
end

function D_Abutton02_OnAttack(id, character, damage)
	local pose = GetSceneItem("D_ADoor01", "pose");
	if ( pose~=0 ) then
		return 0;
	end
	g_iADoor02OpenTime = Misc("gettime");
	NetEvent(1);
	SetSceneItem("D_ADoor01", "pose", 1, 0);
	SetSceneItem(id, "pose", 1, 0);
	NetEvent(0);
end

function D_ADoor01_OnIdle(id)
	local pose = GetSceneItem(id, "pose");
	if ( pose==0 ) then
		return 0;
	end
	local state = GetSceneItem(id, "state");
	if ( pose==1 and state==3 ) then
		local diff = Misc("gettime") - g_iADoor02OpenTime;
		if ( diff > g_iDoorWaitTime ) then
			Output("Close Door");
			NetEvent(1);
			SetSceneItem(id, "pose", 2, 0);
			NetEvent(0);
		end
		return 1;
	end
	if ( pose==2 and state==3 ) then
		NetEvent(1);
		SetSceneItem(id, "pose", 0, 0);
		NetEvent(0);
		return 1;
	end
end

function D_Bbutton01_OnAttack(id, character, damage)
	local pose = GetSceneItem("D_BDoor01", "pose");
	if ( pose~=0 ) then
		return 0;
	end
	g_iBDoor01OpenTime = Misc("gettime");
	NetEvent(1);
	SetSceneItem("D_BDoor01", "pose", 1, 0);
	SetSceneItem(id, "pose", 1, 0);
	NetEvent(0);
end

function D_Bbutton02_OnAttack(id, character, damage)
	local pose = GetSceneItem("D_BDoor01", "pose");
	if ( pose~=0 ) then
		return 0;
	end
	g_iBDoor01OpenTime = Misc("gettime");
	NetEvent(1);
	SetSceneItem("D_BDoor01", "pose", 1, 0);
	SetSceneItem(id, "pose", 1, 0);
	NetEvent(0);
end

function D_BDoor01_OnIdle(id)
	local pose = GetSceneItem(id, "pose");
	if ( pose==0 ) then
		return 0;
	end
	local state = GetSceneItem(id, "state");
	if ( pose==1 and state==3 ) then
		local diff = Misc("gettime") - g_iBDoor01OpenTime;
		if ( diff > g_iDoorWaitTime ) then
			Output("Close Door");
			NetEvent(1);
			SetSceneItem(id, "pose", 2, 0);
			NetEvent(0);
		end
	end
	if ( pose==2 and state==3 ) then
		NetEvent(1);
		SetSceneItem("D_BDoor01", "pose", 0, 0);
		NetEvent(0);
	end
	end

function main()
	Scene_OnLoad()
	Scene_OnInit()
end

分析下物件的处理代码,物件主要有受击消息,和 Idle 消息
看下石头的受击消息处理

function D_ston01_OnAttack(id, character, damage)
	local pose = GetSceneItem(id, "pose");取得石头当前动画编号这个是fmc文件里的
	if ( pose==1 ) then当播放1编号动画时1是石头从山顶落到地面这种情况下石头应该是无法受击的但是他这里写了
		return 0;
	end

	NetEvent(1);网络同步开始
	CreateEffect(id, "StoneFIL");在石头上创建一个特效StoneFil.ef
	CreateEffect("D_Sston01", "StoneFIL");在地面挂载点D_Sston01上创建一个特效这个特效就是石头炸开的声音
	SetSceneItem(id, "pose", 1, 0);让石头播放1号动画不循环
	SetSceneItem(id, "attribute", "collision", 0);//让场景角色可以穿越石头
	SetSceneItem(id, "attribute", "damage", 1);让石头拥有攻击能力他的攻击力在 des文件里有设定
	NetEvent(0);网络同步结束
end

看石头在 Idle 时候的处理

function D_ston01_OnIdle(id)
	if ( g_bStone01Active==1 ) then 如果还是激活的
		local pose = GetSceneItem(id, "pose");取得动画id
		if ( pose==0 ) then 动画id为0返回
			return 0;
		end
		local state = GetSceneItem(id, "state");取得动画状态
		if ( state==3 ) then 如果是播放到末尾帧停止了
			g_bStone01Active=0; 脚本内设置变量标识其为非激活
			NetEvent(1);网络同步开始
			SetSceneItem(id, "attribute", "active", 0);设置石头激活为 false
			NetEvent(0);网络同步结束
		end
	end
end

可以看到,这个石头没有 HP,仅仅受击就播放动画,播放特效,动画播放完了播放状态就变化为 3,然后在其对应的 Update 里调用这个 Idle 消息,他就会把自己 SetActive(false),这样脚本控制起来非常灵活,但是要很细致的用脚本控制所有细节

然后看下拒马的消息处理

function D_BPdoor01_OnAttack(id, character, damage)
	if ( GetTeam(character)==2 ) then 如果打击场景物件的角色属于蝴蝶阵营
		return 0;直接返回过滤了蝴蝶阵营打拒马的情况
	end
	
	local state;

	g_iBPdoorHP = g_iBPdoorHP - damage;更新气血
	
	if ( g_iBPdoorState==1 and g_iBPdoorHP < g_iPdoorState1HP ) then 如果状态为1且气血小与3/4
		g_iBPdoorState = g_iBPdoorState + 1;切换到下个状态 状态+1
		g_iBPdoorShakePose = 3; 受击动画为3
		NetEvent(1);同步开始
		SetSceneItem(id, "pose", 2, 0);播放动画2
		NetEvent(0);同步结束
	end
	
	if ( g_iBPdoorState==2 and g_iBPdoorHP < g_iPdoorState2HP ) then 途观状态为2切气血小与2/4
		g_iBPdoorState = g_iBPdoorState + 1;再切换到下个状态
		g_iBPdoorShakePose = 5;受击动画为5
		Output("Change State 3");
		NetEvent(1);
		SetSceneItem(id, "pose", 4, 0);播放4号动画
		NetEvent(0);
	end
	
	if ( g_iBPdoorState==3 and g_iBPdoorHP< g_iPdoorState3HP ) then 如果状态为3 且血量小与1/4
		g_iBPdoorState = g_iBPdoorState + 1; 切换状态+1
		g_iBPdoorShakePose = 7;受击抖动动画为7
		Output("Change State 4");
		NetEvent(1);
		SetSceneItem(id, "pose", 6, 0);播放6号动画
		NetEvent(0);
	end
	
	if ( g_iBPdoorState==4 and g_iBPdoorHP < g_iPdoorState4HP ) then 如果状态为4切气血小于0时
		g_iBPdoorState = g_iBPdoorState + 1;切换状态
		NetEvent(1);
		CreateEffect(id, "GiMaBRK");在拒马上播放特效
		SetSceneItem(id, "attribute", "interactive", 0);设置拒马不能与其他角色交互这句意思还不明显
		SetSceneItem(id, "attribute", "collision", 0);设置拒马能与角色互相穿透
		SetSceneItem(id, "pose", 8, 0);播放动画8
		SetSceneItem("D_BPd02Box01", "attribute", "active", 0);把隐形的阻碍物件 SetActive(false),就相当于开门了
		NetEvent(0);
	end

	state = GetSceneItem(id, "state"); 取得动画播放状态
	if ( state==3 ) then 如果动画播放完毕
		NetEvent(1);
		CreateEffect(id, "GiMaHIT");在拒马上创建特效
		SetSceneItem(id, "pose", g_iBPdoorShakePose, 0);播放受击抖动动画
		NetEvent(0);
	end
end

看下 Idle 函数

function D_BPdoor01_OnIdle(id)
	if ( g_iBPdoorState==5 and g_bBPdoorAlive==1 ) then 如果状态为5且还处于激活
		local pose = GetSceneItem(id, "pose"); 得到当前动画ID
		if ( pose~=8 ) then 如果是动画8则返回不处理
			return 0;
		end
		local state;
		state = GetSceneItem(id, "state");得到动画播放状态
		if ( state==3 ) then 如果动画播放完毕
			g_bBPdoorAlive = 0; 取消激活
			NetEvent(1);
			SetSceneItem("D_BPdoor01", "attribute", "active", 0);设置游戏对象SetActive(false)
			NetEvent(0);
		end
	end
end

这个拒马如果不用脚本来处理,真的很麻烦,光配置数据要实现这种 (血量处于某个范围对应某个受击动画这种,要配的数据估计不少),而且这完全是个特例,基本上原版里很少见这样用的

看到后面的 秦皇陵,里面摆动的斧头,还有岩浆下往上冒的石柱,都是通过脚本与角色交互的。

这里的机关按钮,还没研究清楚,他的 des 文件里,有些参数猜不出意思
他的摇杆部分,这个摇杆还不清楚为啥没设置可受击就跑到消息处理了,照我的想法最少先告诉我这个摇杆可受攻击,然后才会调用碰撞检测,再进入受击消息处理。
Object objon
{
Position: 0.379 0.007 -0.878
Quaternion: -0.991 0.001 0.131 0.004
TextureAnimation: 0 0.000 0.000
Custom:
{
motionanimation=0;
onClick=3;
IExtparam1=100;
pose0=0,70;
}
}
底座部分
Object sobseat01
{
Position: 0.002 0.615 -0.878
Quaternion: -1.000 0.000 0.000 0.004
TextureAnimation: 0 0.000 0.000
Custom:
{
}
}

开门机关处理函数

function D_Bbutton01_OnAttack(id, character, damage)
	local pose = GetSceneItem("D_BDoor01", "pose");q取得大门的动画ID
	if ( pose~=0 ) then 如果大门的动画ID不是0则返回也就是当大门处于开启和关闭的动画时攻击这个机关是没起作用的
		return 0;
	end
	g_iBDoor01OpenTime = Misc("gettime");得到当前游戏时间记录开门的时刻
	NetEvent(1);
	SetSceneItem("D_BDoor01", "pose", 1, 0);使大门播放开启动画
	SetSceneItem(id, "pose", 1, 0);自己播放1号动画也就是摇杆的拉动动画
	NetEvent(0);
end

看下大门的处理 OnIdle

function D_BDoor01_OnIdle(id)
	local pose = GetSceneItem(id, "pose");取得当前动作编号
	if ( pose==0 ) then 如果是0号动画返回
		return 0;
	end
	local state = GetSceneItem(id, "state")取得动画状态3代表动画播放完毕停留在最后一帧;
	if ( pose==1 and state==3 ) then 如果动作是开门且停留在最后一帧
		local diff = Misc("gettime") - g_iBDoor01OpenTime; 用当前游戏时间减去开门时刻的时间
		if ( diff > g_iDoorWaitTime ) then 如果 间隔时间大于 等待关门时间
			Output("Close Door");
			NetEvent(1);
			SetSceneItem(id, "pose", 2, 0);播放2号动画关门
			NetEvent(0);
		end
	end
	if ( pose==2 and state==3 ) then 如果是2号动画且播放完毕了
		NetEvent(1);
		SetSceneItem("D_BDoor01", "pose", 0, 0); 设置播放0号动画0号动画为待机动画就是第一帧
		NetEvent(0);
	end
	end

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • 锤子科技

    锤子科技(Smartisan)成立于 2012 年 5 月,是一家制造移动互联网终端设备的公司,公司的使命是用完美主义的工匠精神,打造用户体验一流的数码消费类产品(智能手机为主),改善人们的生活质量。

    4 引用 • 31 回帖 • 7 关注
  • 周末

    星期六到星期天晚,实行五天工作制后,指每周的最后两天。再过几年可能就是三天了。

    14 引用 • 297 回帖
  • 京东

    京东是中国最大的自营式电商企业,2015 年第一季度在中国自营式 B2C 电商市场的占有率为 56.3%。2014 年 5 月,京东在美国纳斯达克证券交易所正式挂牌上市(股票代码:JD),是中国第一个成功赴美上市的大型综合型电商平台,与腾讯、百度等中国互联网巨头共同跻身全球前十大互联网公司排行榜。

    14 引用 • 102 回帖 • 401 关注
  • jsoup

    jsoup 是一款 Java 的 HTML 解析器,可直接解析某个 URL 地址、HTML 文本内容。它提供了一套非常省力的 API,可通过 DOM,CSS 以及类似于 jQuery 的操作方法来取出和操作数据。

    6 引用 • 1 回帖 • 473 关注
  • frp

    frp 是一个可用于内网穿透的高性能的反向代理应用,支持 TCP、UDP、 HTTP 和 HTTPS 协议。

    16 引用 • 7 回帖 • 2 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    86 引用 • 897 回帖 • 1 关注
  • QQ

    1999 年 2 月腾讯正式推出“腾讯 QQ”,在线用户由 1999 年的 2 人(马化腾和张志东)到现在已经发展到上亿用户了,在线人数超过一亿,是目前使用最广泛的聊天软件之一。

    45 引用 • 557 回帖 • 160 关注
  • 996
    13 引用 • 200 回帖 • 5 关注
  • Gzip

    gzip (GNU zip)是 GNU 自由软件的文件压缩程序。我们在 Linux 中经常会用到后缀为 .gz 的文件,它们就是 Gzip 格式的。现今已经成为互联网上使用非常普遍的一种数据压缩格式,或者说一种文件格式。

    9 引用 • 12 回帖 • 125 关注
  • Sphinx

    Sphinx 是一个基于 SQL 的全文检索引擎,可以结合 MySQL、PostgreSQL 做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。

    1 引用 • 194 关注
  • Android

    Android 是一种以 Linux 为基础的开放源码操作系统,主要使用于便携设备。2005 年由 Google 收购注资,并拉拢多家制造商组成开放手机联盟开发改良,逐渐扩展到到平板电脑及其他领域上。

    334 引用 • 323 回帖 • 19 关注
  • SEO

    发布对别人有帮助的原创内容是最好的 SEO 方式。

    35 引用 • 200 回帖 • 30 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    84 引用 • 139 回帖 • 1 关注
  • Hadoop

    Hadoop 是由 Apache 基金会所开发的一个分布式系统基础架构。用户可以在不了解分布式底层细节的情况下,开发分布式程序。充分利用集群的威力进行高速运算和存储。

    85 引用 • 122 回帖 • 617 关注
  • 微服务

    微服务架构是一种架构模式,它提倡将单一应用划分成一组小的服务。服务之间互相协调,互相配合,为用户提供最终价值。每个服务运行在独立的进程中。服务于服务之间才用轻量级的通信机制互相沟通。每个服务都围绕着具体业务构建,能够被独立的部署。

    96 引用 • 155 回帖 • 1 关注
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    198 引用 • 120 回帖
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    5 引用 • 26 回帖 • 499 关注
  • IDEA

    IDEA 全称 IntelliJ IDEA,是一款 Java 语言开发的集成环境,在业界被公认为最好的 Java 开发工具之一。IDEA 是 JetBrains 公司的产品,这家公司总部位于捷克共和国的首都布拉格,开发人员以严谨著称的东欧程序员为主。

    180 引用 • 400 回帖 • 1 关注
  • CSS

    CSS(Cascading Style Sheet)“层叠样式表”是用于控制网页样式并允许将样式信息与网页内容分离的一种标记性语言。

    186 引用 • 471 回帖 • 3 关注
  • Sillot

    Insights(注意当前设置 master 为默认分支)

    汐洛彖夲肜矩阵(Sillot T☳Converbenk Matrix),致力于服务智慧新彖乄,具有彖乄驱动、极致优雅、开发者友好的特点。其中汐洛绞架(Sillot-Gibbet)基于自思源笔记(siyuan-note),前身是思源笔记汐洛版(更早是思源笔记汐洛分支),是智慧新录乄终端(多端融合,移动端优先)。

    主仓库地址:Hi-Windom/Sillot

    文档地址:sillot.db.sc.cn

    注意事项:

    1. ⚠️ 汐洛仍在早期开发阶段,尚不稳定
    2. ⚠️ 汐洛并非面向普通用户设计,使用前请了解风险
    3. ⚠️ 汐洛绞架基于思源笔记,开发者尽最大努力与思源笔记保持兼容,但无法实现 100% 兼容
    29 引用 • 25 回帖 • 52 关注
  • Facebook

    Facebook 是一个联系朋友的社交工具。大家可以通过它和朋友、同事、同学以及周围的人保持互动交流,分享无限上传的图片,发布链接和视频,更可以增进对朋友的了解。

    4 引用 • 15 回帖 • 458 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖 • 1 关注
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    62 引用 • 289 回帖
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 20 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    28 引用 • 66 回帖 • 7 关注
  • 又拍云

    又拍云是国内领先的 CDN 服务提供商,国家工信部认证通过的“可信云”,乌云众测平台认证的“安全云”,为移动时代的创业者提供新一代的 CDN 加速服务。

    21 引用 • 37 回帖 • 523 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 329 关注