Roblox Studio 基础教程 您所在的位置:网站首页 roblox脚本网站代码免费 Roblox Studio 基础教程

Roblox Studio 基础教程

2023-04-04 03:54| 来源: 网络整理| 查看: 265

Cover

Studio 简介

Roblox 基本上所有的资源都存储在云端,也就是说如果你想使用 Studio , 就需要你的计算机保持联网状态,这一点与大多数软件开发 IDE 都不同。打开 Roblox Studio 首先会进行自动更新,和登录操作,更新和登录完成后才可以正常使用 Roblox Studio。关于中国版 Roblox 卡在登录界面的问题,在 这篇博客里给出了解决方案。

image-20211114193025061Roblox Studio 的主界面

我这里 Studio 的语言为中文,主题为暗色主题,其他相关配置项都可以在 Studio 的设置中进行更改。

image-20211114193901652Alt + s 进入设置界面

接下来我们打开 Studio 的 Village 模板,来介绍 Studio 的相关界面。

image-20211114195213020主界面的组成部分

在 游戏主界面 中点击一个对象后,项目管理器中就会高亮显示这个对象,并且在项目管理器下面的对象属性中会展示这个对象的属性。

image-20211114195517027

如果你的界面上没有显示某些窗口,可以在菜单栏中的 视图 对相应窗口进行开关。其中高亮的部分是已经显示的窗口,点击即可取消该窗口的显示。相应的,点击没有高亮的选项,可以显示相应的窗口。

image-20211114200242451

下面介绍相机的基本操作:

按住鼠标右键可以左右移动视角,对应键盘的 , 和 .

zuoyou

使用鼠标滚轮可以前后移动相机,对应键盘的↑ 和↓或者w和s 使用鼠标滚轮移动时,会朝着鼠标指针的位置移动。

qianhou

按住鼠标滚轮拖动可以上下左右平移相机,对应键盘快捷键是QEAD

pingyi

按住 shift + QWEASD 会降低镜头移动速度。

点击一个目标对象,按f可以聚焦到这个对象(镜头中心是这个对象),这个时候进行右键旋转和鼠标滚轮滚动,都会以这个目标为中心,如果上下移动或者左右移动,则会自动退出聚焦模式。

jujiao

关于对象的创建,缩放,和旋转操作,在这篇博客里已经有过了相应介绍,此处不再举例。

部件属性

由于在 Studio 的编辑模式下,物理运算的有些内容是不更新的,部件的某些属性需要在程序运行时才能体现出来。所以在介绍部件属性之前,先介绍一下运行游戏测试的相关按钮和功能。

Roblox 游戏采用 客户端/服务器 模式,通常许多客户端连接到同一个服务器。每一名玩家对应一个客户端。在 Studio 的 测试 选项卡中可以选择玩家的数量。

image-20211114234712236

当选择 2 名玩家时,点击启动后就会额外启动 3 个 Roblox Studio,其中一个是服务器,两个客户端。服务器与客户端的区别是服务器可以使用自由相机来观察世界,而在客户端这里相机是与玩家绑定的。

image-20211114235007294

image-20211114235026005服务器视角

image-20211114235137222玩家1视角

image-20211114235216891玩家2视角

开始游戏按钮会启动一个客户端和一个服务器,默认为客户端视角,玩家会在重生点的任意位置随机出现。

image-20211114235519399启动一个客户端

image-20211114235620374点击可以切换到服务器视角

重生点就是一个特殊的部件,类型名是SpawnLocation

我们可以在模型中点击 重生点 来插入部件,当然,插入部件的方式有很多,具体可以看这篇博客

image-20211115000229660

接下来介绍部件的常用属性。官方文档会有更详细的介绍。

插入部件时可以选择部件的形状,包括方块、球体、楔形和圆柱。

image-20211117140603903

其对应的时部件的 Shape 属性。楔形部件和其他形状部件有所不同,楔形部件有其独立的属性。新插入的部件会默认插入在屏幕中央,所以,在你决定要插入部件的时候,请调整相机使其对准地面,如果相机对着天空插入部件的话,部件会被插入在很远的地方。

image-20211117140801786

接下来我们介绍部件的属性列表。

首先时颜色,颜色的属性包含 BrickColor 和 Color,这两个属性都可以修改部件的颜色,为什么会有两个属性呢,这里面包含一个 Roblox 的历史原因,几年前,Roblox 还只有一个 BrickColor 属性,只可以从弹出的选项中选择颜色。

image-20211117141329438

后来,想要加入更多颜色选项,实现可以自定义颜色数值,但是已经有许多脚本使用了 BrickColor 属性,就只能新增加一个 Color 属性。现在这两个属性几乎没有区别了。

Material 材质属性,里面包含 10 几个内置的材质可供选择,在使用不同的材质后,不仅可以改变部件的外观,还会修改部件的物理属性,比如表面摩擦力和弹性之类的。如果要修改默认的物理属性,需要勾选下面的 CustomPhysicalProperties,然后修改出现的子属性。

image-20211117142439526

Reflectance 反射,调高之后会混合天空的颜色,这个属性只对 塑料 、光滑塑料和玻璃生效。不推荐大家用这个属性,因为效果比较假,以后很可能被弃用。

image-20211117142814913

Transparency 透明度。其中 0 表示不透明 1表示全透明。

ClassName 类型名,如果想使用脚本创建一个对象,就需要知道它的类型名。

Instance.new("Part")

Name 是当前对象的名字,也是资源管理器中显示的名字,可以修改 Name 属性为部件重命名。

Parent 是当前对象的父对象。

Transform 属性列表下包含的是属性的位置及大小属性。

Anchored 这个属性需要在运行游戏时才能看出区别,勾选了 Anchored 属性后,部件可以悬停在半空中,取消勾选后,部件会由于重力的原因落到地上。

maozhu

CanCollide 是否可以与其它物体发生碰撞,true 表示可以 ,false 表示不可以。当我们的部件既没有勾选 CanCollide 属性 也没有勾选 Anchored 属性时,开始游戏后部件就会消失,准确的说时落到地面上由于不可碰撞又会继续下落。

pengzhuang

CollisionGroupId 碰撞组。我们可以给每个部件设置不同的分组,然后设定哪些组之间可以发生碰撞。这个属性只是设置 Id ,具体实现哪些组可以发生碰撞需要在脚本中实现。

Locked ,勾选后我们无法用鼠标在场景中选中部件,但是我们依然可以在资源管理器中选中部件。

脚本基础

要使用 Roblox 脚本需要创建脚本对象,Roblox 有三种脚本对象,Script、LocalScript 和 ModuleScript ,我们使用 Script 来演示脚本的编写,其他两种脚本对象与 Script 的语法都是相同的,只是运行的位置不同。Roblox 使用的时 Lua 脚本的语法。

我们在 WorkSpace 下新建一个 Script 对象,Studio 会自动写上第一行代码。当我们运行游戏就会在输出栏打印相关内容。

image-20211117150434713

服务器脚本需要放在 WorkSpace 或者 ServerScriptService 目录下才会被自动执行,放在其他位置是不会自动执行的。

如果不想脚本立即运行,可以把写好的脚本放在 ServerStorage 下,这里是专门用来存放预先制作好的对象的。

所有语言的基础内容都大致相似,这里重点介绍一下 Lua 和 Python 语法上的一些区别。

字符串连接

Lua 中使用 .. 来连接字符串。

a = "Hello " .. 'Lua' Table 类型

Table 类型是一种表结构,是一种键值对的类型,类似于 Python 中字典和列表的整合。

Table 类型的初始化使用一对大括号 {}

Table 中可以保存很多变量,每个变量使用一个 key 来索引,key 可以是数字,也可以是字符串。索引方式可以使用中括号的方式,但是需要注意,中括号中的数字 1 和字符 1 是不相等的两个数值。当 key 是合法的变量名的时候,也可以使用 . 来进行索引。

Table 类型变量中不仅可以存放普通的变量,还可以存放函数。

t = {} t[1] = 123 t["1"] = 222 t["Name"] = "lua" print(t) print(t[1],t['1'],t.Name) -- T.Name 和 t["Name"] 是等价的

image-20211117151924341

Roblox 中所有的对象都是 Table 类型,当我们想获得某个对象的引用时,可以通过Table 索引的方式来获得对象的引用。例如

p = game.Workspace.Baseplate.Position print(p) -- 也可以使用 [] 的方式进行索引 pp = game["Workspace"]["Baseplate"]["Position"] print(pp) -- 混合使用两种方式 ppp = game.Workspace["Baseplate"].Position print(ppp)

image-20211117153017767

函数

函数定义的两种方式

[作用域] 函数名 = function(参数列表) [作用域] function 函数名(参数列表) a = 10 b = '15' local add = function(a,b) return a + b -- 当字符串与数字相加减时 Lua 会首先尝试把字 符串转 换为 数值类型 end local function sub(a,b) return b - a end print(add(a,b)) print(sub(a,b))

image-20211117153810726

当 Table 类型变量进行函数参数传递时,会发生 地址传递

看示例代码:

local a = 10 -- 定义局部数值类型变量 local t = {} -- 定义局部 Table 类型变量 t.Name = "lua" -- 修改 Table 类型变量的内容 t["Friend"] = "C" local function test(a,t) -- 函数接收两个参数 第一个参数赋值为一百,修改第二个参数的值 a = 100 t.Name = "lualualua" t.Friend = "C++" end test(a,t) -- 调用 test 函数 print(a) -- test 函数没有修改当前作用域下 a 的值 print(t.Name) -- test 函数修改了 t 的内容 print(t.Friend)

image-20211117184334988

在函数执行过程中,形参的 a 和 实参的 a 不是相同的内存空间,因此修改实参的 a 不会改变实参 a 的值。此过程类似于 C++ 中的值传递,在调用函数时,系统会再声明一个变量用来接收 a 。但是由于 Table 类型的变量有可能很大,当 Table 类型的变量作为参数传递时,不会重新声明一个变量来进行值的拷贝,而是直接修改该变量的值,类似于 C++ 中的地址传递。

在 Roblox 中,函数很大的一个作用是用来连接部件的事件。例如,如果我们想实现对部件的点击操作。我们首先应该在部件下新建一个 ClickDetector 对象,在 ClickDetector 对象下新建一个脚本,用来实现点击事件。

image-20211117191123273

在 ClickDetector官方文档中,可以找到鼠标点击事件,我们在脚本中将鼠标点击事件与我们的函数绑定起来。

image-20211117191630628

function onclick(player) print("You clicked") end script.Parent.MouseClick:Connect(onclick) --MouseClick 使用冒号的方式调用 Connect 函数

click

连接事件也可以使用匿名函数,像下面这样,也可以实现相同的功能。

script.Parent.MouseClick:Connect(function onclick(player) print("You clicked") end)

使用冒号和点的区别。

在上面的例子中,我们使用冒号来调用 Connect 函数,冒号的点的区别在于:使用冒号调用函数默认传入函数的第一个变量是 函数调用者本身。

local t = {} t.Name = "Lua" t.Value = 1 t.add_func = function(tab) -- 在 Table 类型变量中加入函数 tab.Value += 1 end t.add_func(t) -- 使用点的方式调用函数,函数的参数需要传入自身 print(t.Value) -- 2 t:add_func() -- 使用冒号的方式调用函数 print(t.Value) -- 3

image-20211117193736265

于是,上面例子中的鼠标点击事件就可以重写成如下代码。

function onclick(player) print("You clicked") end -- script.Parent.MouseClick:Connect(onclick) script.Parent.MouseClick.Connect(script.Parent.MouseClick,onclick) -- 代码更长了,所以还是使用冒号的方式更加方便。

我们除了在调用函数时可以使用冒号,在写函数体的时候也可以使用冒号。

local t = {} t.Name = "Lua" t.Value = 1 --t:add_func = function() -- 这种方式是错误的 -- self.Value += 1 --end function t:add_func() -- 使用冒号来实现函数体,此时函数默认传入的第一个参数为 self self.Value += 1 end t.add_func(t) -- 使用点的方式调用函数,函数的参数需要传入自身 print(t.Value) -- 2 t:add_func() -- 使用冒号的方式调用函数 print(t.Value) -- 3

基本上所有 Roblox 对象上的函数都需要使用冒号来调用,因为这些函数都需要获取对象本身的一些参数。

全局变量和局部变量

在变量声明时,不加 local 关键字则默认声明为全局变量,全局变量在整个程序运行时任何一个地方都可以使用,局部变量则只可以在当前代码块中使用。最大的代码块就是脚本文件本身,其次,你每看见一个 end 关键字就标志着一个代码块的结束,比如一个函数就是一个代码块。

使用局部变量的好处:

避免命名冲突 存取速度块 方便阅读代码,当你读到一个 local 关键字的变量时,你可以马上意识到,这个变量只在当前代码块有用。

下面的例子来展示全局变量和局部变量在使用上的区别。

local a = 10 local f = function(param) -- 函数的实参是局部变量 print(a,param) c = function() -- 此处的 c 是全局变量,因此可以在当前代码块外继续使用 end local d = 1000 end local b = 100 f(b) print(param,c) -- nil function: 0x48b06e735faff19b -- param 是函数实参,属于局部变量,在作用域外部无法使用。或者说当前代码块中没有 param 这个变量 print(d) -- nil -- 同理 d 是被声明在函数内部的局部变量,在函数外部无法使用

使用 do … end 可以生成代码块,防止命名冲突。

do local a = 10 end do local a = 100 end

Roblox 中的全局变量和正统的 Lua 中的全局变量有所不同,即使变量声明为全局变量,在其他脚本文件中依然无法使用。

循环语句

循环语句有三种基本形式。

local a = 0 -- while 循环 while a = 10 for i = 1,10,1 do -- 1,10,1 从 1 开始 到 10 结束 步长 是 1 print(i) end

使用 for 循环遍历 table。

local arr = {"WANG","GUANG","XIN"} -- 数组类型 local dic = {WANG = 1,GUANG = 2,XIN = 3} -- 字典类型 -- 虽然一个表里可以同时有这两种方式进行索引,但是不推荐大家这么做,因为很多内置函数是假设你的 Table 是数组或者字典的。 -- 针对数组的 for 循环 for i = 1,#arr do -- 数组索引从1开始,#数组名 可以获得数组的长度 print(arr[i]) end for index,value in ipairs(arr) do -- ipairs 每次返回数组索引和值 print(arr[index],index,value) end -- 针对字典的 for 循环 for key,value in pairs(dic) do print(dic[key],value) -- dic.key 这样是不对的,使用点的方式,点后面不能是变量 如果索引是变量 只能dic[key] end

image-20211117204150188

不同脚本间的数据共享

前面提到过 Roblox 的脚本中全局变量也无法被其他脚本文件使用,这里介绍不同脚本间数据共享的几种方法。

存储在 Roblox 的对象里

这种方法适用于一个简单的数据,比如一个数值、字符串之类的。

首先点击 Workspace 创建一个 value 对象。

搜索 value 可以出现以下几种对象。

image-20211117204557282

我们创建一个 IntValue 对象,顾名思义这个对象就是用来存储整数数据的,比如 Boss 的血量等等。

image-20211117204803251

我们可以在不同脚本中修改这个 Value 对象的 Value 属性,可以修改这个对象的 Name 属性方便理解这个值的作用,比如修改成 HP 等等。

接下来我们可以在其他脚本文件中对这个 Value 对象进行操作。

local HP = game.Workspace:WaitForChild("HP") -- 这里我们使用 WaitForChild 是为了防止脚本执行时 Value 对象还没有被创建导致的程序出错。 -- local HP = game.Workspace.HP 这种方式 需要先创建了 HP 对象,再执行脚本对象才不会出错。 -- 每隔 1 秒钟打印以下 HP 的值 并且使其减一 for i = 1,100 do print(HP.Value) HP.Value -= 1 wait(1) end 使用全局表

在 Lua 里有个特殊的表,名字是 _G 。这个表里存了一些对 Lua 比较重要的东西,比如一些内置函数。

我们可以把需要共享的变量存储在这个表里,这样所有脚本之间都可以使用这个变量。为了避免与 _G 表内已经存在的内容出现冲突,我们可以在 _G 表下创建一个表,用来专门存储我们自己声明的变量。

_G.MyValues = {} _G.MyValues.HP = 1000 print(_G.MyValues.HP)

使用这种方法共享数据可能出现一个问题,由于脚本之间的执行顺序是不确定的,比如你想实现第一个脚本写入数据,第二个脚本读取数据,但实际上脚本的执行顺序是相反的,可能会读到一个不存在的数据。因此,使用这种方式共享数据还需要编写其他的逻辑来加以控制。

另外,Roblox 客户端和服务器的全局表是不同的,这种方法不能在客户端和服务器之间共享数据。

使用 ModuleScript 对象

ModuleScript 自己单独存在的时候并不会运行,你需要在别的脚本中调用它,他才会执行。在 ServerScriptService 中新建一个 ModuleScript 对象。

image-20211117223039180

Studio 会为我们自动生成两行代码。

image-20211117223152478

我们把 Boss 的信息存在这个文件的表内。

local Boss = {} Boss.HP = 1000 Boss.Name = "Lua" Boss.shou_shang = function(Boss) Boss.HP -= 1 end return Boss

然后在用到的地方先执行 require 函数,然后就可以操作这个表了。

local Boss = require(game.ServerScriptService:WaitForChild("ModuleScript")) while Boss.HP > 0 do print(Boss.HP) Boss:shou_shang() wait(0.5) end

以上就是我关于 Roblox 所了解的全部内容了🚩

更多精彩内容请自行查阅官方文档

如果你足够细心的话,你会发现下面有个按钮在闪光😉

i-am-not-interested-in-money



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有