术语“脚本和脚本”似乎在Game Development Stack Exchange上可以互换使用,但是除了阅读有关脚本语言选择的问题外,我不理解脚本和脚本与核心语言之间的关系。脚本通常会做什么,何时使用?在某些情况下(由游戏程序员定义),脚本与脚本语言是否不同?
术语“脚本和脚本”似乎在Game Development Stack Exchange上可以互换使用,但是除了阅读有关脚本语言选择的问题外,我不理解脚本和脚本与核心语言之间的关系。脚本通常会做什么,何时使用?在某些情况下(由游戏程序员定义),脚本与脚本语言是否不同?
Answers:
脚本是为脚本语言编写的。人们可以使用语句子中的单词来弄清楚您所指的内容,但向任何人询问脚本,脚本和脚本语言的定义,您将得到类似的信息:脚本是使用脚本语言编写脚本的行为。
将脚本语言嵌入游戏引擎或所引用的核心语言时,不仅会暴露游戏引擎中的对象,而且还会为游戏引擎编写逻辑。值得注意的另一件事是,这将您的游戏变成了一种虚拟机,因为脚本语言很少会编译成机器语言,而是被转换为字节码形式,并在运行时由游戏引擎进行解释。
这为开发团队带来了巨大的好处,接下来列出其中一些:
我敢肯定,这个列表会一直持续下去,尤其是当您进入专门的游戏类型,以及脚本编写如何帮助定义用于在RTS中移动单位组的组形成规则或如何在UI中创建UI逻辑时脚本语言为最终用户等提供可扩展的UI。
与“核心语言”相比,使用脚本具有许多优势。其中一些包括:
脚本通常是在核心引擎之外运行的一段代码。它通常包含在文本文件中,无论您希望将它们保留在哪里。然后通常由引擎加载,解析并在运行时执行。
通常会发生的是,无论您使用哪种语言(例如Lua,Angelscript),该语言通常都具有一些功能,使引擎程序员可以将引擎功能甚至整个类公开给当前正在运行的“脚本引擎”实例。 。
例如(完全愚蠢的例子,但只是为了说明问题),您的游戏代码可能具有一个公共功能,该功能会在某处生成僵尸:
void SpawnZombie(int x, int y, int hp /* whatever else */)
{
//...
}
现在,您使用的脚本语言使您可以将此功能公开给正在运行的脚本解析器。这实际上意味着您可以打开一个文本文件,编写“ SpawnZombie(200,300,1337)”,并且一旦您的引擎执行了代码,僵尸就会在该位置生成。
其他答案已经列出了一些有关如何通常使用此方法的很好的例子,但它们遗漏了一个我认为非常重要的观点:
这些类型的脚本使运行时调试或测试游戏过程变得非常容易。
假设您想找出在地图上放置僵尸的最佳方法,这样一经发现,僵尸便会对玩家产生最大的恐吓效果。如果没有脚本支持,则必须退出应用程序,在代码中更改一些幻数,然后重新编译和测试它。
有了脚本支持(假设您已经有了某种在运行时输入文本的方法,例如调试控制台),您只需键入“ SpawnZombie(333,444,555)”,然后查看其外观。
以同样的方式,您可能会生成武器,车辆,加载不同的地图,更改游戏中某些物品的值等,杀死敌人,因为您不想浪费时间去寻找需要的部分经过测试等
在更复杂的游戏中,这将为您节省大量时间。
脚本使您可以编写更高级别的逻辑。换句话说,您编写的代码更少,功能更多。
因此,下面的示例显示了用代码编写内容和使用脚本语言编写内容之间的区别。
Update Loop
{
if (CarExplodeAnimation.FinalFrame == true)
{
SceneGraph.Remove(Car);
Message("You have destroyed the car.";
}
else
{
CarExplodeAnimation.AdvanceToNextFrame();
}
}
PlayAnimation(ShipExplode) // blocks until animation completes
Message("You have destoryed the car.")
看看使用脚本语言时设计人员要做的编码少了多少?
原因是在游戏代码中,您必须将一个事件分成多个框架,并从多个框架的角度编写代码。另一方面,脚本编写使您可以将多帧事件视为仅一行代码,因为所有额外的代码都在脚本函数后面进行了抽象。
您可能会问,但是该功能也不能只用游戏代码编写吗?好吧,是的,但这意味着设计人员将必须打开游戏引擎的源代码并在其中编写所有代码,并且您不希望您的设计师浏览游戏引擎的源代码(他们可能会意外更改)一些其他代码,整个事情都会崩溃)。
相反,您希望设计师执行以下操作:在“地图编辑器”中右键单击汽车,单击“插入脚本”,然后键入脚本代码。关键游戏引擎的源代码没有混乱。