Temel Oyun Oynatma Sistemleri

*Bu içerik, yapay zekâ (beta) kullanılarak çevrildi ve hatalar içerebilir. Sayfayı İngilizce görüntülemek için buraya tıkla.

Aşağıdaki sistemler, The Mystery of Duvall Drive için istediğimiz oyun oynatışını kurmak için temeldi.

Oyun Durumu Yöneticisi

The GameStateManager / GameStateClient is probably the most complicated system in the experience, as it deals with:

  • Lobideki oyuncuları başlatıyor, grubu ana oyun alanına ışınlanmak için sayıyı başlatıyor ve oyuncuları rezerve sunuculara ışınlanıyor.
  • Korup odaları klonlayın, onları asen yayınlayın ve oyuncuları belirli bir CFrame koordinatına ışınlatın.
  • Mekanikleri yakalamak ve yerleştirmek.
  • Kapıları kilitleme ve açma.
  • Son ışınlanmayı lobiye başlatın ve son kesinti sahnesini oynayın.

We implemented it as a simple state machine (Update function), ve devletler DemoConfig (GameStates枚) içinde bulunur. Some states deal with initial lobby/reserved server ışınlan, while others deal with finding a mission, triggering the puzzle, and solving the mission. Note that apart from seals, we tried to not have mission-specific code in the GameStateManager .

GameStates çoğunlukla sunucu tarafından yönetilir, ancak müşteri bir şey yapması gerektiğinde, örneğin sayıyı göster, gelenekleri veya yayınlanma durdurma UI'sini devre dışı bırakmak gibi, sunucu ve müşteri (GameStatusClient) arasında şu anki olay olayı GameStateEvent ile iletiş

Işınlanma Oyun Durumları

Teleportasyonu bozuk odaya gizleyen üç benzersiz cutscene'i içeren 3 oyun devleti vardır: Warmup, InFlight

Yayınlanırken, InFlight çalışır, birazcık solgun bir ekran tutan. Bir Class.Player.

Oyuncuları normal odanın durumuna ışınladığımızda, TeleportWarmupBack, TeleportInFlightBack ve TeleportCooldownBack , ve deneyimin sonunda, TeleportW

Yıldırım ve Atmosphere Oyun Durumları

Her odanın normal ve bozulmuş durumunun f

Kapı kilitleme Oyun Durumları

O

Etkinlik Yöneticisi

Etkinlik Yöneticiyi kullanarak "eylemleri" zamanla yürütmemize izin verdiği gibi:

  • İн스턴스 özellikleri ve öznitelikleri arasındaki bağlantıyı sağlar.
  • Kodları çalıştırıyor.
  • Oynama sesi.
  • Kamera sarsıntılarını çekiyor.

İdeal olarak, iz tabanlı UI'ye sahip bir araç kullanırız, ancak bu demoda, anahtar ve özellik isimlerini manuel olarak yazdık. Etkinlik Yöneticisi sistemi birkaç script ve bir etkinlik/fonksiyon içerir, bunlar arasında:

  • EventManager - Etkinlikleri oluşturma ve durdurma için genel mantık, sunucu-taraflı eylemler de dahil.
  • EventManagerClient - Klient tarafı eylemleri.
  • EventManagerModule - Her sunucu ve müşteri tarafı eylemler için ortak kod.
  • EventManagerConfig - Birkaç komut deklarasyonu içeren küçük bir dosya.
  • EventManagerDemo - Bu demo için tüm gerçek olayların oyun spesifik kodunda tanımlanmasının nerede.
  • EventManagerEvent , EventManagerFunc - Klient veya sunucudan etkinlikleri çalıştırmak ve durdurmak için uzaktan etkinlik ve bağlantılı işlev. Bu, diğer sistemlerin etkinlikleri nasıl ayarlayabileceğini, çalıştırılabilir ve durdurulabilir işlevleri nasıl ayarlayabileceğini gösterir.

Her etkinliğin bir adı, başlatma veya bitirme için gerekli bilgilerin bulunduğu bir bölüm, etkinliğin parametreleri ve gecikme için işlevi vardır. Kameraya sallanır ve ses oynatır.

Yer İşaretlemesi

Yerleşik olarak, anahtar çerçeveler arasında zıplayan objelerin yerleri değiştirmek için nesne özellikleri ve öznitelikleri arasındaki boşlukları doldurabilirsiniz. Örneğin, a


interpolants = {
objectParam = "TextLabel",
property = "TextTransparency",
keys = {
{value = 1},
{time = .5, value = 0},
{time = 2.25, value = 0},
{time = 3, value = 1}
}
}

Aşağıdaki kod örneğinde gibi, hangi nesne özelliğinin veya özelliğinin hangi nesneye ait olduğunu tanımlayabildiğimizden memnuniyet duyuyorduk, böylece müşterideki yayınlanma ile ilgili olarak ve "objelerin oluşturulma zamanında" ile ilgili olarak çalışabilir.


object = workspace.SomeFolder.SomeModel

Bunu başarabilmek için, etkinliğin başlatbir nesneyi referans etmeye ve bir isimli parametreleri etkinliğe bağlı olarak geçerli kılmaya izin verdik. Named olan nesneleri etkinliğin altında bulmak için, etkinliğin başlangıcında bir "r


params = {
["RootObject"] = workspace.Content.Interior.Foyer["Ritual-DemoVersion"],
},
interpolants = {
objectName = "Wander",
attribute = "TimeScale",
keys = {
{value = 0.2}
}
}

Özellikler bölümünde etkinliklere parametreleri geçirebilirsiniz ve etkinlik başlangıcında çalışan kodlar varsayılan değerleri değiştirebilir veya "param" tablosunda daha fazla parametre ekleyebilir


params = {
isEnabled = false
},
interpolants = {
{
objectName = "FocuserGlow",
property = "Enabled",
keys = {
{valueParam = "isEnabled"}
}
}

Parametreler, deneyimin başlangıcında bile mevcut olmayan nesneleri işaret etmemize izin verir. Örneğin, aşağıdaki kod örneğinde, etkinliğin başlangıcında çalışan bir işlev, bir nesne oluşturur ve parametrelerde BlackScreenObject girişini ayarlar, oluşturulan nesneye işaret edilir.


{objectParam = "BlackScreenObject",
property = "BackgroundTransparency",
keys = {
{value = 0},
{time = 19, value = 0},
{value = 1},
}}

Etkinlikler, Etkinlik Instanları ve Tetiklere Bağlanma

Bir etkinliği çalıştırmak için, klijlerden bir uzaktan etkinlik kullanırız veya sunucudan bir işlev. Aşağıdaki örnekte, birkaç parametreyi RootObject ve isEnabled etkinliklerine veriyoruz. İçeride, etkinliğin açıklamasının bir kopyası oluşturulur, parametreler gerç


local params = {
RootObject = workspace.Content.Interior.Foyer["Ritual-DemoVersion"]["SealDropoff_" .. missionName],
isEnabled = enabled
}
local eventId = eventManagerFunc:Invoke("Run", {eventName = "Ritual_Init_Dropoff", eventParams = params} )

Bir etkinliği "Dur" ile durdurmak için işlevi çağırabiliriz:


eventManagerFunc:Invoke("Stop", {eventInstId = cooldownId} )

“Kozmetik” (tüm oyuncular için simülasyonu değiştirmeyin) eylemleri, kliplerde yürütülebilir ve bu da daha pürüzsüz bir işleme sonuçlanabilir. Etkinliğin açıklamasında, tüm eylemler için varsayılan değeri sunabilirsiniz (bu, varsayılan olmadan, klipler üzerindeki herhangi bir eylemi geçersiz kılar). Her klip, kendi

Bir etkinliği bir başlatıcıya kolayca bağlamak için yardımcı işlevleri kullandık ConnectTriggerToEvent veya ConnectSpawnedTriggerToEvent, bu da ismiyle etkinliği bulur. Aynı etkinliği farklı başlatıcılarla

Etkinlik Parçaları

Etkinliği oluştururken geçerli kullanıcı tarafından atanan özel etkinlik parametreleri dışında, oluşturulan etkinliğin gerektiğinde göçebileceği diğer veriler de dahil olmak üzere, oluşturulan etkinliğin gerektiğinde göçebileceği diğer oyuncude dahil olmak üzere, oluşturul

Etkinliklerin bekleme sürelerini minCooldownTime ve maxCooldownTime ile belirleyebilirsiniz. Min ve max, oyuncu sayısına bağlı olarak ölçeği artırma için

Kullanılan Kodlar

Class.Script|Scripts ile özel anahtar çerçevelerinde Scriptler bölümünde adlandırabiliriz. Örneğin:


scripts = {
{startTime = 2, scriptName = "EnablePlayerControls", params = {true}, onServer = false }
}

Önceki örnekte, EnablePlayerControls Script eylem menajer modülüne kaydedilmesi gerekir, şu şekilde:


emModule.RegisterFunction("EnablePlayerControls", EnablePlayerControls)

ClientScript'teki işlevler için kullanıcı tarafından çağrılan işlevler ve ServerScript'teki işlevler için onServer = true için kullanıcı tarafından çağrılan işlevler olarak kaydedilir. İşlevin kendisi etkinliği alır, ancak bu durumda, sadece bir parametre etkinliği geçerlidir.


local function EnablePlayerControls(eventInst, params)

Oynatma Audio

Anahtar karelerindeki non-positional audio oynatmak için sınırlı desteğimiz var, örneğin:


sounds = {
{startTime = 2, name = "VisTech_ethereal_voices-001"},
}

Etkinliğin bitmesi çağrısının olay süresi dolduğunda ateşlenmesine注意avatar, ancak ses eylemleri hala oynatıyor olabilir.

Kamera Titremeleri

Kamerası Shake'leri kamerası Shake'leri bölümünde, şu şekilde tanımlayabiliriz:


cameraShakes = {
{startTime = 15, shake = "small", sustainDuration = 7, targets = emConfig.ShakeTargets.allPlayers, onServer = true},
}

“hedefler” sadece etkinliği başlatan oyuncuya, tümOyuncu veya playersInRadius'e bağlı olan oyuncular için başlatılabilir. Kamerası sarsıntılar için üçüncü taraf bir kod kullandık ve sarsıntılar önceden tanımlanmış: eventManagerDemo.bigShake ve

Görevlerin mantığı

Toplam 7 görev var ve sadece 6'sı kullanıyor kullanıyor. çoğu görevin ortak parametreleri var, ancak bazıları sadece kullanıyor ve hizmet odasına ışınlanmak için kullanıyor. Her görevin bir DemoConfig kriptiyle bir seti içinde parametreleri var:

  • MissionRoot : Tüm olmayan versiyonlarınızın bir klasörü.
  • Kapılar : Bir oyuncu bir kilidi seçene kadar kilit kapatır.
  • SealName / SolvedSealName : Bozulmamış ve bozulmuş kalem isimleri.
  • SealPlaceName : Mührü yerleştirmeniz gereken yerler.
  • PlacedSealPlaceholderName : Mührü yerleştirmek için yerleştirme nesneyi yerleştirir.
  • TeleportPositionsName : Oyuncu teleport pozisyonlarını ve dönüşleri belirlemek için bozulmuş oda, ve normal alan ile yeniden oluştururken kullanıcının konumlarını ayarlayan bir klasörün adı. Bu aynı ad kullanılır.
  • CorruptRoomName : İçe aktarma için kök klasörlerinin adları (ServerStorage'a göre) bozulmuş odalar için. İçe aktarma başladığında, TempStorage.Cloned altında gösterilir ve görev tamamlandığında yok edilir.
  • MissionCompleteButtonName : Koruma odalarındaki bir hile butonu, hemen görevi bitirmeye yarar. Bu, depresyon amaçları için.
  • CheatKey : Aynı şey bir sayı veya CtrlShift[Numara] ile aynı.

Görev mantığının bir kısmı GameStateManager skriptlerinde, halkalar ve kapılar en çok oyun akışını sağlayan ana oyun akışını sağlar, ancak görev özelliği için çoğu görev için ana oyun akışını sa

  • kilit üzerinde bir anahtar kullanın - Kapıyı açmak için ilk görevi. Bu tip LockName , KeyName tarafından tanımlanır.
  • Eşleştirme öğeleri - 4 görev eşleştirme öğelerine eşittir. Bu tip MatchItems tarafından tanımlanır.
  • Bir mankeni katmanlı kumaş kullanarak giydirmeye çalışıyorsunuz - 1 görevi atıkta olan oyuncular üç öğeyi toplar. Bu tip DressItemsTagList tarafından tanımlanır.
  • Click on item to finish. - 1 görevi bu yaztanımlar ClickTargetName .

Her görevi tipinin kendi öz StartMissionFunc ve CompleteMissionFunc . Giriş işlevi genellikle MaçEşyası</

Eşleştirme öğelerin mantığına göre, "kullanmak" (takılırken tıklayın) öğeleri PuzzlePieceXX etiketleriyle takılan öğeleri kullanmak için mümkündür. MatchItems haritasındaki

Alınıyor

Bir nesneyi yakalamak için basit bir yakalama sistemi geliştirdik. Yakalama GrabServer2 ve Grab

Her karede, bir yakalama denemesi devam edip etmediğini kontrol ederiz. Eğer oyuncu reachDist içindedirse, ToolHoldAnim oynayı başlatırız. Bir oyuncu maxGrabDistance içindedirse, istemcisi sunucuya bir model almak için bir istek gönderir (1> playerGrab1> işlevi).

Sunucu tarafı kodun 2 ana işlevi vardır:

  • Alın - Bir modeli almak için bir istemciyenin isteğini ele alır.
  • Bırakma Talebini Geri Alma: - Yakalanmış bir modeli serbest bırakma isteğini işleyin.

Her oyuncunun ne sakladığının bilgisi playerInfos haritasında saklanır. Takip girişim, bu modelin zaten başka bir oyuncu tarafından alınmış olup olmadığını kontrol ederiz. Eğer öyleyse - bir "EquipWorldFail" gönderilir kliya ve kayış denemesini iptal eder. Aynı

Erişim izin verilirse, Attachments , sağ elinizde ve diğer elinizde birer Class.Attach|E

Bir yakalanmış modeli serbest bırakmak için, client script HUD ScreenGUI'deki GrabReleaseButton düğmesine bağlanır. Bir Connected işlevi, serbest bırakma işlemi için sunucuya bir etkinliği başlatır. Sunuc