Начинаю знакомство с платформой Roblox. Не много не мало, но сразу хочу создать Tycoon подобную игру.
Информацию буду брать из всевозможных источников — youtube, форумы, документации и т.д. и т.п.
С чего начинается родина? Нашёл один из путных видео уроков https://www.youtube.com/watch?v=6H56nsklDYc, который переделаю под себя немного. Ну а вы можете сперва просмотреть его уроки или.. продолжить читать.
Для начала создадим папочки:

Добавим пол выбрав Part, Block и зададим большой размер. 50,1,50 нам за глаза хватит. Для начала. И назовём его Footer. И нажмём Anchor чтобы он был закреплён. Вообще нажимать якорь нужно принять за правило, чтобы наши объекты во время игры не разваливались.

Поставим столбик — мы же хотим застолбить место? Part, Block размерами 6,12,6 (предполагаю, что лучше всегда задавать размеры кратные 2 и в данном случае, чтобы там свободно помещался игрок) и зададим ему параметры: Transparence = 0.5 (прозрачность), цвет чёрный, CanCollide отключаем (отключаем его физические свойства или коллизии), CastShadow тоже отключаем (не нужна нам от неё тень). Жмём Group и переименовываем в Touch to claim. Ну и добавляем в эту группу Humaiod и переименовываем столбик в Head — чтобы в игре видеть данную надпись.

Далее нам нужно чтобы участок стал наш. Для этого надо добавить команды игроков. Жмём Model сверху, выбираем Service, выделяем Teams и жмём Insert.

После чего добавляем в нём Team. Переименовываем в Tycoon и снимаем галку с AutoAssignable (нам же не нужно автоматическое присваивание команды).

Ну и главный штрих, это добавление скрипта в наш блок для того чтобы присвоить таки себе данный Tycoon. Раскрываем наш блок, и в Head добавляем Script (от автора видео с моими комментариями), куда и вставляем код ниже:
trap = script.Parent -- работаем с родителем скрипта trap.Touched:Connect(function(Part) -- вызываем событие, когда касаемся столбика local player = game.Players:GetPlayerFromCharacter(Part.Parent) -- сохраняем информацию об игроке if Part.Parent:FindFirstChild("Humanoid") and player.Neutral == true then -- если игрок Гуманоид и не состоит в команде trap.Parent.Name = Part.Parent.Name .. "'s Tycoon" -- задаём новое имя для столбика trap.Transparency = 0.95 -- выставляем прозрачность player.Team = game.Teams["Tycoon"] -- нашего игрока переносим в команду player.Neutral = false -- и убираем из нейтральных -- game.Workspace.Tycoons.Tycoon1:FindFirstChild("Owner").Value = Part.Parent.Name trap.Parent.Parent.Parent:FindFirstChild("Owner").Value = Part.Parent.Name -- прописываем владельца данного Tycoon end -- конец if end) -- конец function
Можно запустить и проверить, что команда меняется.
Добавим Script для инициализации таблицы денег, поместив его в папку Tycoons, т.к. это будет относится ко всем созданным Tycoon-ам сразу.

local function Addchild(newPlayer) -- объявляем функцию local Leaders = Instance.new("IntValue") -- создаём новую переменную local Cash = Instance.new("IntValue") -- создаём новую переменную Leaders.Name = "leaderstats" -- задаём имя переменной Cash.Name = "Cash" -- задаём имя переменной Cash.Parent = Leaders -- указываем родителя переменной Leaders.Parent = newPlayer -- указываем родителя переменной end -- конец функции game.Players.ChildAdded:Connect(Addchild) -- вызываем функцию при подключении нового игрока
Вообще, всё что касается конкретного Tycoon запихиваем в папку Tycoon1. А всё что касается всех созданных Tycoon-ов в Tycoons.
Добавляем в Tycoon1 пару переменных: IntValue — переименовываем в Money для хранения текущей суммы, StringValue переименовываем в Owner для хранения кому этот Tycoon принадлежит.

Создадим конвеер по которому будут катиться наши блоки. Бросаем кирпич -Part, Block и растягиваем его Scale за синии сферы, т.к. они будут двигаться по этому направлению. Задаём материал ему — Material, Fabric ну и цвет серо-чёрный Color. Если нужно, через Rotate поворачиваем его в нужном направлении.

Добавляем в эту ленту Script:
script.Parent.Velocity = script.Parent.CFrame.LookVector * 20 -- запускаем движение и указываем его скорость 20 -- вариант для движения в противоположную сторону: -- script.Parent.Velocity = -script.Parent.CFrame.LookVector * 20
Добавляем сюда же стенки/бордюры конвеера, чтобы наши кирпичи с него не падали.

После чего мы это всё выделяем и закрепляем — Ancor и группируем в модель — Group. Модель переименовываем в Conveer. И конечно запихиваем это всё в Tycoon1.
Должно в итоге получиться как-то так:

На данном этапе можно запустить и проверить, что конвеер нас перевозит.
Добавим дропера — кидальщика блоков или добытчика ископаемых. Для этого в Tycoon1 добавляем Model и переименовывем её в Droppers. В ней будут храниться наши дроперы.

Изобретать велосипед не будем, а потому возьмём готовый дроппер из предоставленных сообществом. В toolbox набираем Dropper и жмём поиск. После чего выбираем понравившуюся модель и перетягиваем на экран будущей супер игры.

После его ставим куда нужно Move и крутим Rotate как нам нужно. И конечно же можем подогнать его размеры под нужные нам используя Scale.

Проверяем что наш дроппер это модель, задаём ему название Dropper1 и перетаскиваем в Droppers.

Проверяем (создаём) внутри дроппера переменную IntValue с названием Money и значением Value равному цене нашего блока.

Теперь ищем деталь Drop на нашем дроппере — из неё, собственно и будут сыпаться наши детальки. Если такой нет, то перебираем и переименовываем её в Drop.

Дошла очередь до скрипта для дроперов. Добавляем Scrips в модель Droppers и вставляем в него код:
wait(1) -- ждём секунду до начала сброса чтобы у нас не падал блок сразу при появлении дроппера droppers = {"Dropper1","Dropper2"} -- массив названий дропперов, через запятую -- не обязательно указывать НЕ сущществующие дропперы, достаточно перечислить имеющиеся while true do -- бесконечный цикл for i = 1,2 do -- количество от и до if script.Parent:FindFirstChild(droppers[i])then -- если сущществует дропер с указанным названием из массива выше local Brik = Instance.new("Part") -- создаём новый блок Brik.Parent = script.Parent -- указываем родителя этого блока, т.е. того, кто бросил данный кирпич Brik.Size = Vector3.new(0.5, 0.5, 0.5) -- указываем размеры этого кирпича Brik.BrickColor = BrickColor.new("Reddish brown") -- задаём ему цвет Brik.Position = script.Parent:FindFirstChild(droppers[i]).Drop.Position -- указываем стартовую позицию кирпича Brik.CanCollide = true -- указываем что он имеет коллизии, т.е. обрабатывать столкновения Brik.Name = "Drops" -- задаём ему название Brik.Material = "Concrete" -- задаём ему материал local money = Instance.new("IntValue") -- добавляем переменную money.Name = "BrikMoney" -- задаём переменной имя money.Parent = Brik -- привязываем переменную к кирпичу money.Value = script.Parent:FindFirstChild(droppers[i]).Money.Value -- указываем значение этой переменной равной значению дроппера end -- конец условия по созданию кирпича end -- конец цикла по перебору дропперов wait(2) -- период ожидание, в секундах, до нового кирпича end -- конец бесконечного цикла, т.е. начать всё с начала
Ну вот, на текущем этапе уже можно запустить игру и удостовериться, что кирпичи начали сыпаться из дропера.
Теперь создадим сборщика высыпанных кирпичей. Part, Block и ставим его у торца конвеера, задав соответствующие размеры.

Переименовываем как Collector. Жмём Ancor. Переносим его в модель Conveer и добавляем скрипт по удалению деталей и пополнения счёта:
trap = script.Parent -- родитель (запускатель) скрипта этот блок local function Touch(OtherPart) -- объявляем функцию касания данного блока if OtherPart.Name == "Drops" then -- если коснулся с именем Drops, т.е. кирпич trap.Parent.Parent.Money.Value = trap.Parent.Parent.Money.Value + OtherPart.BrikMoney.Value -- Увеличиваем значение Money на сумма в кирпиче OtherPart:remove() -- удаляем данный кирпич end -- конец условия end -- конец функции trap.Touched:Connect(Touch) -- объявляем функцию запускаемую при контакте с данным блоком
Для красоты можно удлинить боковины конвеера и поставить блок позади данного коллектора. Ну а самому коллектор убрать свойство CanCollide, чтобы кирпичики влетали в него и не было эффекта отскока при соприкосновении с ним. Получим нечто похожее на рисунке ниже:

Проверить что всё работает как надо вы можете во время запуска игры. В Explorere открываете вкладки Workplace (рабочее пространство), Tycoons, Tycoon1 и выбрав переменную Money. Если значение в ней меняется, значит всё сделано правильно.

Ну что же, пора переходить к коллекционеру заработанного. Создавать не будем, а так же воспользуемся готовым из библиотеки доступного. Ищем в нём Cash to collect и перетаскиваем понравившийся нам на нашу игру. Главное чтобы была в нём площадка зелёная, на которую мы будем становиться для сбора денег. Ну и поворачиваем Rotate и размещаем его где нам удобней. После переименовываем модель в Cash to Collect и переносим модель в Tycoon1.

И не забываем поставить палец вверх автору модельки, раз уж мы ей пользуемся.
Сперва добавим скрипт к нажимной плите — Giver
local trap = script.Parent -- указываем родителя скрипта local function Touch(Part) -- объявляем функцию обработки if Part.Parent.Name == trap.Parent.Parent.Parent.Owner.Value then -- проверяем что это хозяин tycoon её коснулся -- если это условие убрать, то по идее деньги может тырить любой игрок trap.BrickColor = BrickColor.new("Bright red") -- меняем цвет плиты if trap.Parent.Parent.Parent.Money.Value > 0 then -- проверяем что в коллекторе деньги есть local stats = game.Players:GetPlayerFromCharacter(Part.Parent) -- заводим локальную переменную local stats2 = stats:FindFirstChild("leaderstats") -- заносим в переменную нас из таблицы лидеров local cash = stats2:FindFirstChild("Cash") --заносим в переменную наши деньги в таблице лидеров cash.Value = cash.Value + trap.Parent.Parent.Parent.Money.Value -- прибавляем к переменной выше наши деньги trap.Parent.Parent.Parent.Money.Value = 0 -- обнуляем текущую сумму собранных коллектором денег end -- конец условия проверки денег wait(1) -- ждём секунду trap.BrickColor = BrickColor.new("Sea green") -- возвращаем плите зелёный цвет end -- конец условия проверки на хозяина end -- конец описания функции trap.Touched:Connect(Touch) -- задаём обработчик запускающий выполнение функции по касанию плиты
И исправляем скрипт для самого дисплея сборщика:

script.Parent.Text = "$"..script.Parent.Parent.Parent.Parent.Parent.Parent.Money.Value -- привязка дисплея к текущему счёту собранных денег script.Parent.Parent.Parent.Parent.Parent.Parent.Money.Changed:connect(function(money) script.Parent.Text = "$"..money -- собственно сам вывод на дисплей end)
На данном этапе, при запуске игры, мы увидим что кирпичи пропадают, а на дисплее коллектора отображается текущий счёт денег. Если мы сразу встанем на плиту, то ничего не произойдёт, потому что сперва нужно присвоить участок. И только после этого встав на плиту, она перекрасится в красный, деньги перейдут на счёт, а на дисплее станет ноль. И через пару секунд плита вновь станет зелёной.

Ну что же, переходим к части кнопок. Создаём модель Buttons в нашем Tycoon1 в которой будут храниться наши кнопки.
Ну а теперь очередь кнопки. Part, Cylinder, развернём стоя и зададим размеры 0.1,3,3 и т.к. кнопка для добывания денег, то делаем её красной. После чего жмём Group и.. кнопка превращается в Model. И вот тут самое интересное — как мы эту модель назовём, такую надпись и будем видеть во время игры над кнопкой. Но для этого в модель нужно добавить элемент Humanoid, а сам элемент Part переименовать в Head. И заодно запихнём это в дочернюю Model Buttons созданную в Folder Tycoon1. Выглядеть это будет примерно так:

Добавляем к кнопке переменную StringValue и задаём имя Object (тут будет храниться имя объекта) и целую переменную IntValue с именем Price (в ней будет храниться необходимая сумма для активации)

Добавляем Script в Tycoon1:
Object = {} -- массив для перебора объектов for i,v in pairs(script.Parent.Buttons:GetChildren()) do -- цикл который перебирает все кнопки spawn(function() -- объявление функции -- условие сокрытия if v:FindFirstChild("Dependency") then -- если есть переменная v.Head.CanCollide = false -- делаем проходимым v.Head.Transparency = 1 -- делаем не видимым end -- конец условия -- условие отображения if v:FindFirstChild("Dependency") and script.Parent.Droppers:WaitForChild(v.Dependency.Value) then -- если есть у кноки данная переменная и есть дроппер с значением данной переменной while v.Head.Transparency > 0 do -- плавно отображаем данную кнопку v.Head.Transparency = v.Head.Transparency - 0.05 wait(0.03) end -- конец цикла v.Head.CanCollide = true -- делаем кнопку не проходимой end -- конец условия end) -- конец функции Object[v.Object.Value] = v.Parent.Parent.Droppers:FindFirstChild(v.Object.Value):Clone() -- перебираем все объекты из Droppers и заносим их в массив Object v.Parent.Parent.Droppers:FindFirstChild(v.Object.Value):remove() -- удаляем реальный объект v.Head.Touched:Connect(function (Part) -- описываем событие / функцию по касанию кнопки if v.Head.CanCollide == true then -- если кнопка не проходимая if Part.Parent.Name == script.Parent.Owner.Value then -- имя касателя соответствует владельцу тайкуна if Part.Parent:FindFirstChild("Humanoid") then -- и у него есть в блоке Humanoid local stats = game.Players:GetPlayerFromCharacter(Part.Parent) -- сохраняем игрока local stats2 = stats:FindFirstChild("leaderstats") -- берём данные о нём из статистики local cash = stats2:FindFirstChild("Cash") -- количество денег у него if cash.Value >= v.Price.Value then -- сравниваем с ценой на кнопке cash.Value = cash.Value - v.Price.Value -- вычитаем цену Object[v.Object.Value].Parent = v.Parent.Parent.Droppers -- отображение объекта v:remove() -- удаление кнопки end end end end end) end script.Parent.Finish.Value = true
После чего добавим имя объекта на который будет указывать наша кнопка в значение переменной Object кнопки. Например, пропишем туда Dropper1. Т.е. при нажатии кнопки будет появляться первый дроппер. На данном этапе можно проверить, что пока мы не станем владельцем и не нажмём кпопку дроппера не будет. И стоит нажать кнопку, как он появится.

А теперь… Создадим ещё пару копий нашего дроппера (Ctrl+C, Ctrl+V) переименуем их соответственно Dropper2 и Dropper3. Поставим возле конвеера и перенесём в папку Droppers. Выставим у них значение 5 и 10 соответственно в переменных Money. Т.е. такая сумма будет ехать в их блоках. После чего так же дважды скопируем стартовую кнопку и зададим им имена Buy Dropper 2 — [$20] и Buy Dropper 3 — [$100]. И конечно в них выставим значение переменной Object согласно имени — Dropper2 и Dropper3 (как мы назвали свои дропперы перед этим). И выставим соответствующие цены в переменной Price этих кнопок (20 и 100).
И тут самое интересное. В новых кнопках надо добавить строковую переменную StringValue с именем Dependency, которая будет указывать когда будет появляться данная кнопка на игровом поле. Т.е. после появления какого именно объекта. В нашем случае это будет: у Buy Dropper 2 значение Dropper1, а Buy Dropper 3 — значение Dropper2.



На этом собственно и всё было бы что нужно знать для создания Tycoon… Если бы не нужно было что-нибудь построить. Этим мы сейчас и займёмся.
Для начала из Part, Block создадим стены вокруг нашей площадки. И т.к. передняя стена будет состоять из 3х блоков (дверной проём), его придётся сгруппировать нажав Group. Стены соответственно назовём Wall1,Wall2,Wall3,Wall4. Не забываем заякорить их кнопкой Anchor. И переносим их в Droppers. к ним так же нужно создать 4 кнопки. Но этим кнопкам зададим голубоватый цвет, т.к. это кнопки постройки, а не бизнеса. Опять копипастим, как это было ранее, но делаем это из кнопки Buy Dropper 2, чтобы было меньше телодвижений.
На примере одной кнопки — задаём ей имя Buy wall 1 — [$20]. Соответственно Price = 20, Object = Wall1. Dependency менять не будем, пусть так и появляются все эти кнопки после установки первого дроппера. И сделав одну кнопку, раскопируем её ещё 3 раза — для остальных стен. А хотя… Для красоты эксперимента, зададим 3 и 4 кнопкам появляться после появления Dropper2.
И тут выяснился косяк. Кнопки не убирались т.к. скрипт спотыкался о Touch to claim и дальше не перебирал существующие кнопки. Нужно вынести Touch to claim из группы Buttons в группу Tycoon1. И исправить в нём скрипт, удалив один Parent из строчки присвоения игрока области. Строка должна выглядеть теперь так:
trap.Parent.Parent:FindFirstChild(«Owner»).Value = Part.Parent.Name — прописываем владельца данного Tycoon
Собственно на этом можно посмотреть на результат наших трудов и сказать — я умею создавать Tycoon!
Конечно в реальности не совсем так. Тут ещё нет апгрейдеров. Нет покупок VIP и внутри игровых бонусов за бабки. Скрипт получения области надо переделывать, чтобы изначально участок был пустым. Ещё нужно научиться создавать несколько конвееров. Да много чего ещё можно придумать…
в скрипте для Giver в 7 строке
if trap.Parent.Parent.Parent.Money.Value > 0 then — проверяем что в коллекторе деньги есть
— выдает ошибку из-за >:
Workspace.Tycoons.Tycoon1.Cash to Collect.CollectorParts.Giver.Giver:7: Expected ‘then’ when parsing if statement, got ‘&’
Возможно тут какая-то опечатка? Поменял на ссылку в Owner но тогда придется все Owner называть 1,2,3…
if trap.Parent.Parent.Parent.Money.Value and trap.Parent.Parent.Parent.Owner.Value then
Да. Есть такая проблема. Это сработала автоподмена…
local trap = script.Parent
local function Touch(Part)
if Part.Parent.Name == trap.Parent.Parent.Parent.Owner.Value then
trap.BrickColor = BrickColor.new(«Bright red»)
if trap.Parent.Parent.Parent.Money.Value > 0 then
local stats = game.Players:GetPlayerFromCharacter(Part.Parent)
local stats2 = stats:FindFirstChild(«leaderstats»)
local cash = stats2:FindFirstChild(«Cash»)
cash.Value = cash.Value + trap.Parent.Parent.Parent.Money.Value
trap.Parent.Parent.Parent.Money.Value = 0
end
wait(1)
trap.BrickColor = BrickColor.new(«Sea green»)
end
end
trap.Touched:Connect(Touch)
простите,а как открыть комманды игрока?
Не понял что за команды?
Teams?
У меня тоже проблема с гивером. Значение показывает а вот выдавать не хочет. Проверьте пожалуйста:
local trap = script.Parent — указываем родителя скрипта
local function Touch(Part) — объявляем функцию обработки
if Part.Parent.Name == trap.Parent.Parent.Parent.Owner.Value then — проверяем что это хозяин tycoon её коснулся
— если это условие убрать, то по идее деньги может тырить любой игрок
trap.BrickColor = BrickColor.new(«Bright red») — меняем цвет плиты
if trap.Parent.Parent.Parent.Money.Value > 0 then — проверяем что в коллекторе деньги есть
local stats = game.Players:GetPlayerFromCharacter(Part.Parent) — заводим локальную переменную
local stats2 = stats:FindFirstChild(«leaderstats») — заносим в переменную нас из таблицы лидеров
local cash = stats2:FindFirstChild(«Cash») —заносим в переменную наши деньги в таблице лидеров
cash.Value = cash.Value + trap.Parent.Parent.Parent.Money.Value — прибавляем к переменной выше наши деньги
trap.Parent.Parent.Parent.Money.Value = 0 — обнуляем текущую сумму собранных коллектором денег
end — конец условия проверки денег
wait(1) — ждём секунду
trap.BrickColor = BrickColor.new(«Sea green») — возвращаем плите зелёный цвет
end — конец условия проверки на хозяина
end — конец описания функции
trap.Touched:Connect(Touch) — задаём обработчик запускающий выполнение функции по касанию плиты
дропперы 2 и 3 и соответствующие им кнопки есть с самого начала при тесте. в чём может быть проблема?
На моменте с cash to collect ничего не понятно , делаю все как написано , НО все равно ничего не работает.
admin помоги с скриптом на giver а то не работайт
У меня проблема на Giver, деньги на нем показывает, я состою в тайконе, на когда встаю на плиту, ничего не происходит, деньги все еще остаются там
а что значит столбик: ставим столбик?
Это значит бросаем стандартный Part.
Здравстуйте, в скрипте где Dependency там тоже опечатка???
while v.Head.Transparency > 0 do — плавно отображаем данную кноп
Head is not a valid member of Model «Workspace.Tycoons.Tycoon1.Buttons.Dropper 2 — 20$»
Вероятней всего, судя по тексту ошибки, у вас расположение в Explorer-е изменено, т.к. ошибка переводится как: «Head не является наследником модели «Workspace.Tycoons.Tycoon1.Buttons.Dropper 2 — 20$».
Одно из предположений, что у вас знак длинного тире, вместо минуса стоит.
а что сделать можно?
У вас есть вк? мой если можно вот: https://vk.com/baushkayt
Добавьте там будет быстрее просто.
https://vk.com/gavsi
здравстуйте вылетает проблема в output Head is not a valid member of Model «Workspace.Tycoons.Tycoon1.Buttons.Buy dropper2 — 20$»
Помогите пожалуйста! Выдаёт ошибку «BrikMoney is not a valid member of Part «Workspace.Tycoons.Tycoon1.Droppers.Dropper1.Click.Drops». И блоки не исчезают :(.
Блин… «Finish is not a valid member of Folder «Workspace.Tycoons.Tycoon1» 😡😡😡😡 . Плиз помогите!!! С прошлой ошибкой я справился.
Finish не содержится в папке Workspace.Tycoons.Tycoon1
Надо посмотреть что у вас в этой папке и почему оно там ищется.
Помогите. Нажимаю на первую кнопку, дроппер появляется(пока что всё нормально). А следующая кнопка потом не появляется!
Почему не удаляется предмет из дропера который едет по конвееру они просто на том квадрате который должен удалять и приносить деньги не удаляет
привйт
Помогите пожалуйста! Я становлюсь на кнопку Start Button и пишет что : Workspace.Tycoons.Tycoon1.Touch to claim.Head.Script:11: attempt to index nil with ‘Value’ — Server — Script:11
Тебе пишет что пустое значение в указанном месте.
Здравствуйте, у меня такая проблема. Я нажал Model, далее Service, у меня высвечивается Insert Service. В Insert Service я не могу найти Team, его там нет.
А при чём тут модель? Сервис Teams находится в корне Explorer.
Здравствуйте, у меня проблема. Я не могу найти Team. Я захожу в Model, далее в Service. У меня высвечивается Insert Service, а там нет Team. Помогите пожалуйста
Добрый день, скажите пожалуйста, как это будет работать после перезахода игрока ?
Или всё там будет оставаться.
Я просто написал проверку, если игрок вышел из игры и был владельцем тайкона, то всё начинается сначала, но кнопки перестают работать.
Помогите пожалуйста.
Честно, не проверял. Набросал это на скорую руку.
Можно просто на PlayerRemoved повесить удаление площадки вышедшего игрока.
У меня возникла проблема с гивером и дисплеем. Гивер не выдаёт деньги, хотя я всё сделал как надо. А дисплеей всё время отображает ноль. Помогите, пожалуйста.