Jump to content
模组网
icedream

【Creation Kit 学习指南 32】状态

Recommended Posts

概述

脚本运行在变化的状态下 - 但是脚本在一个时刻只能有一个状态。当调用函数或事件发生时,代码的运行取决于脚本所处的状态。

定义状态

在脚本中定义状态非常简单,只需如下设置:

state MyState
	; 不同函数在此
endState
如果你希望你的脚本以特定状态开始,只需在state前面加上"auto":

auto state StartHere
	; 函数在此
endState
'空状态'

'空状态',顾名思义,就是所有函数都不在state语句块所属的地方。

function MyFunction()
	;此函数处于'空状态'
endFunction
 
state MyState
	function MyFunction()
		;此函数处于MyState状态
	endFunction
endState
在状态中定义函数/事件

To define a function or event inside a state, simply put the function or event inside the state block.

state MyState
	function SpecialFunction()
		; 此函数处于MyState状态
	endFunction
endState
请注意:函数和状态必须以相同的返回类型和相同参数类型定义在'空状态'中,否则编译器将发出错误警告。这是因为游戏解决函数和事件的过程运行于游戏运行时。

function SampleFunction(int myParameter)
	; 代码在此
endFunction
 
state SampleState
	function SampleFunction(int aParameter)
		; 此函数无误 - 参数类型和'空状态'相同
	endFunction
 
	function OtherFunction()
		; 错误!其它函数并不存在于'空状态'中
	endFunction
endState
 
state OtherState
	int function SampleFunction(int myParameter)
		; 错误!此函数返回类型和'空状态'中的所有类型均不匹配
	endFunction
endState
 
state YetAnotherState
	function SampleFunction(int myParameter, float parameter2)
		; 错误!此函数参数和'空状态'中的所有参数均不匹配
	endFunction
endState
为了方便,只要是你继承的脚本中的空状态,不同种类脚本中的事件都能收到它里面定义的东西(换言之,目标参照、角色等等)。因此当你要在特定情况下修改事件时,你不必在每个空状态内定义事件。

如何选择函数

调用一个函数或目标接收事件时,函数选择遵循如下规则:

  • 如果当前状态下脚本含有函数,那么调用它
  • 如果当前状态下脚本继承另一个有函数的脚本,那么调用那个脚本中的函数
  • 如果在'空状态'下脚本含有函数,那么调用它
  • 如果脚本继承另一个在'空状态'下有函数的脚本,那么调用那个脚本中的函数
长话短说,状态内的函数优先于'空状态'内的函数,脚本内的函数优先于继承其它脚本得到的函数。

如何设置脚本状态

设定脚本状态非常简单,只需调用GotoState和状态的名称。事件顺序如下所示:

  • OnEndState在脚本中标明之前的状态
  • 状态转换为所需状态
  • OnBeginState在脚本中标明进入时的状态
进入时状态的名称并非敏感事件。如果你想让其进入'空状态',只需简单的使用空字符串: ""

同样调用GotoState将不会结束你的函数 - 它将继续运行,因此会受部分代码的影响而改变目标状态。

function MyFunction()
	GotoState("TurnOffActivate")
	; 一堆长期运行的东西
	GotoState("")
endFunction

state TurnOffActivate
	event OnActivate(ObjectReference akTriggerRef)
	; 不做任何事
	endEvent
endState
如何获取脚本状态

获取脚本状态依然很简单,调用GetState(),它将返回当前脚本所处的状态名称。请注意状态名称取决于在首个地方设置的状态。字符串比较是'敏感事件,因此请谨慎处理字符串比较。(以后我们将介绍忽略事件的字符串比较 - 现在需要担心)

使用技巧

  • 在特定情况下,如果你想禁用一个事件或函数,那么可以简单地定义事件和函数并将状态设为空。此方法可以帮助你忽略触发事件。
  • 如果你认为在一个时刻只有一个状态是一种限制,那么记住你可以把多个脚本关联一个目标 - 每个脚本都有各自的状态!它能帮助你解决复杂的运算。当然你也可以用你自己的状态变量。
  • 因为状态名称是简单字符串,所以你能在运行时刻使用"+"运算符构建它们。例如,你可以按如下方法定义"State1", "State2"等等。
Function GotoNumberedState(int number)
GotoState("State" + number)
EndFunction
总结

状态是改变脚本行为的一个强大又合理的方法,它不必书写大量的if条件语句或其它复杂代码。问题有时看起来复杂和麻烦,但运用状态可以使其变得简单!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...