Variables and Properties (Papyrus)/uk

From the CreationKit Wiki
Jump to navigation Jump to search

Змінні та властивості



Передмова[edit | edit source]

Змінні та властивості є схожими поняттями, вони створенні для зберігання значень та об'єктів. Змінна є "власною" у тому розумінні, що лише скрипт, якому вона належить, може зчитувати або задавати її значення. Властивість, по суті, є тією ж самою змінною, за винятком того, що не лише скрипт, якому вона належить, а й інші скрипти мають можливість зчитати або змінити її значення.

Якщо змінна або властивість містять числове значення - ціле число, як приклад, то його зчитування призведе до отримання цього значення. Якщо змінна або властивість містять об'єкт, то ви маєте змогу отримати доступ до його властивостей та функцій. (Аналогічно до змінної-посилання у старій скриптовій системі.)

Оголошення змінних[edit | edit source]

 float myFloat
 float myOtherFloat = 13.5

Змінна MyFloat матиме початкове значення 0, а змінна myOtherFloat - 13.5. Доступ до цих змінних може існувати лише у тому скрипті, у якому вони оголошені, але більше у жодному іншому.

Оголошення властивостей[edit | edit source]

Повна властивість[edit | edit source]

Для того, щоб оголосити властивість спершу слід вказати її тип, потім - ключове слово "property", після - унікальне ім'я властивості. У тілі властивості, між ключовими словами State та EndState слід визначити дві функції: з іменем get - функція, що повертатиме значення властивості, та з іменем set, що сприйматиме значення властивості при його зміні. На кінець оголошення властивості вказує ключове слово EndState.

Приклад:

; Змінна, у якій властивість триматиме своє значення
int myInt_Var = 0
int property myInt
  int function get()
    return myInt_Var
  endFunction
  function set(int value)
    myInt_Var = value
  endFunction
endProperty

У тому випадку, якщо функція get залишиться невизначеною, то властивість буде доступна лише для встановлення значення. Це означає, що такій властивості можна бути встановити значення, але в жодному разі не вдасться його отримати. Певна річ, що скрипт, якому належить ця властивість, завжди має доступ до змінної, у якій зберігається значення властивості. Якщо ж не визначити функцію set, то значення властивості буде доступним лише для читання, його можна бути зчитати, та ніяким чином не можна бути змінити. Як і в попередньому випадку, скрипт, якому належить ця властивість, має змогу змінити значення змінної, де зберігається значення цієї властивості.

Функції get та set є повноцінними користувацькими функціями, здатними до виконання різноманітних програмних дій, їх не обов'язково використовувати лише для встановлення та повернення значення властивості. Так, наприклад, ви можете влаштувати перевірку значення аргументу, що передається до функції set, щоб контролювати значення властивості у певному діапазоні. Або можна призначити програш якоїсь анімації об'єкта у залежності від певного значення властивості. Нарешті вам зовсім не обов'язково зберігати значення властивості у змінній, воно може бути отримане, як результат певних операцій, функцій, тощо або бути константою.

Приклад:

bool property Locked
  bool function get()
    return IsLocked()
  endFunction
  function set(bool value)
    Lock(value)
  endFunction
endProperty

Попередня властивість приховує функціїї Lock (en) та IsLocked (en), що належать ObjectReference (en), так що ви в змозі замкнути та відімкнути цей об'єкт просто надавши властивості Locked дійсного (true) або хибного (false) значення.

Example:

int myVar = 5
int property ReadOnly
  int function get()
    return myVar
  endFunction
endProperty

Властивість, що наведено у прикладі вище, є доступною лише для читання. Будь-який інший скрипт може отримати її значення, та лише скрипт, якому вона належить, може змінити його шляхом зміни значення змінної, у якій зберігається значення властивості.

Приклад:

int myVar = 5
int property WriteOnly
  function set(int value)
    if value >= 0
      myVar = value
    else
      myVar = 0
    endIf
  endFunction
endProperty

Властивість, що наведено у прикладі вище, є доступною лише для запису. Жоден зовнішній скрипт, тобто скрипт, якому вона не належить, не зможе зчитати її значення. Також, як ви могли помітити, у функції set вказано умову, за якою значення, що присвоюється властивості, не може бути меншим нуля.

Авто-властивості[edit | edit source]

Авто-властивості - це властивості зі спрощеним синтаксисом у яких відсутня необхідність визначати функції get та set. Також авто-властивості працюють дещо швидше, у порівнянні із повними властивостями, за рахунок деяких внутрішніх оптимізацій у віртуальній машині. Для оголошення авто-властивості слід опустити визначення функцій get та set, ключове EndProperty також не слід вказувати. У кінці оголошення властивості слід додати ключове слово Auto. У випадку, коли ви оголошуєте авто-властивість, ви також можете вказати її початкове значення після імені властивості, через знак "=": <Тип> <Property> <І'мя_властивості> = <Початкове_значення> Auto

Приклад:

int property myInt = 5 auto


Авто-властивості лише для читання[edit | edit source]

Початкове значення авто-властивості, що оголошена лише для читання, є постійним і в жодному разі не може бути змінене. Це може бути зручним, коли певні постійні значення такої властивості вказують на якісь відповідні взаємопов'язані речі. Оголошення авто-властивості, що призначена лише для читання, подібне до оголошення авто-властивості, що описано у попередньому пункті, за винятком того, що замість ключового слова Auto слід писати AutoReadOnly. Пам'ятайте, що авто-властивість лише для читання повинна мати початкове значення. Присвоєння початкового значення для авто-властивості лише для читання відбувається аналогічно до авто-властивості.

Приклад:

int property myReadOnlyInt = 20 autoReadOnly


Умовні властивості[edit | edit source]

Звичайні властивості не можуть бути використані як умовні. Авто властивості можуть бути оголошені як умовні, бо вони визначають приховану змінну, що може використовуватися в умовах. Саме тому ви можете спостерігати відповідні назви авто-властивостей, коли обираєте скриптові змінні у системі умов, - насправді ви обираєте відповідні значення прихованих змінних. Для оголошення умовної властивості слід вказати ключове слово Conditional після ключового слова Auto.

Приклад:

; Оголошення умовоної авто-властивості
int Property myVar Auto Conditional

Більше інформації про вживання ключового слова Conditional ви можете знайти у статтях "Базові поняття Papyrus" (en) та "Флаги та їх вживання" (en). Зверніть увагу, що AutoReadOnly властивості не можуть бути умовними.

Доступ до властивостей квестового скрипту[edit | edit source]

З підсумкового скрипту у тому ж самому квесті[edit | edit source]

Для вас завжди буде необхідно використовувати властивості квестовго скрипту у підсумкових скриптах. Це одна з найскладніших речей, та як тільки ви зрозумієте, що відбувається, то одразу збагнете її суть. Спершу зверніть увагу на приклад нижче, згодом ми пояснимо вам що до чого.

 ; Нехай ми маємо квестовий скрипт з наступним змістом:
 scriptName MQ01Script extends Quest
 int property deadCount auto 

 ; Та підсумковий скрипт (ви можете спостерігати його у квесті MQ01):
 MQ01Script myQuest                        ; Оголошуємо змінну "myQuest" типу MQ01Script
 myQuest = GetOwningQuest() as MQ01Script  ; надаємо змінній myQuest значення батьківського квесту як типу, відповідно, MQ01Script
 float myDeadCount                         ; оголошуємо змінну "myDeadCount" 
 myDeadCount = myQuest.deadCount           ; та надаємо їй значення властивості з квестового скрипту
 ; також ви маєте можливість змінювати значення властивості квестового скрипту.
 myQuest.deadCount = 10


Маємо властивість "deadCount", що знаходиться у скрипті "MQ01Script", який долучено до квесту MQ01. Ми також маємо скрипт, що належить квесту MQ01 (може бути підсумковим, результатом пакету, або скриптом, що долучено до alias).

У підсумковому скрипті ми оголосили змінну, що відкриває нам доступ до скрипту, який містить властивість, значення якої нам необхідне (у цьому випадку властивість "DeadCount", що належить скрипту MQ01Script). Слід зазначити, що нашу змінну myQuest оголошено, як MQ01Script тому, що, створивши наш квестовий скрипт "scriptName MQ01Script extends Quest", ми, фактично, створили новий тип об'єкту - об'єкту MQ01Script. GetOwningQuest повертає об'єкт квесту (до того, як його було розширено). Отже нам також необхідно привести об'єкт типу Quest, що повернула функція GetOwningQuest як новий об'єкт "myQuest = GetOwningQuest() as MQ01Script". Таким чином ми відкриваємо доступ до розширених властивостей. Якщо ж ми не приведемо отриманий об'єкт до типу MQ01Script, то матимемо доступ лише до властивостей та функцій об'єкту типу Quest, що не містить необхідної нам властивості.

In other words, when we created MQ01Script which extended the Quest script, unless we cast the object returned by GetOwningQuest AS our new script, it won't have our new properties declared in our new script.

З використанням спеціальної змінної kmyQuest[edit | edit source]

Ви можете отримати спрощений доступ до властивостей скрипту, що призначено спеціальній змінній kmyQuest, у підсумковому скрипті наступним шляхом: kmyQuest.<Ім'я_властивості>.

Приклад:

 float myDeadCount
 myDeadCount = kmyQuest.deadCount ; отримання значення властивості
 kmyQuest.deadCount = 10 ; присвоєння значення властивості

Пам'ятайте, що ви можете призначити змінній kmyQuest лише один зі скриптів, які долучені до квесту, вибравши його у випадаючому списку на вкладці Papyrus Fragment у розділі Quest Stages меню Quest

From Within a Magic Effect Script[edit | edit source]

Розглянемо приклад, коли скриптове закляття отримує доступ до квестових властивостей:

Scriptname myQuestNameScript extends Quest

Int Property PublicInt Auto		; Значення властивості може бути змінене з будь-якого іншого скрипту

Int PrivateInt = 30			; Значення властивості є приватним і не доступне для інших скриптів
Function DamageTargBasedOnPublic(Actor akTarget)
	;This code will damage the akTarget for PublicInt damage
	akTarget.DamageAV("Health", PublicInt)
EndFunction

Function DamageTargBasedOnPrivate(Actor akTarget)
	;This code will damage the akTarget for PrivateInt damage
	akTarget.DamageAV("Health", PrivateInt)
EndFunction

Тепер, коли ми визначили квестовий скрипт та створили доступну властивість, ми можемо контролювати її ззовні.

Scriptname mySpellEffectScript extends activemagiceffect

myQuestNameScript Property myQuestRef auto

Event OnEffectStart(Actor akTarget, Actor akCaster)
	myQuestRef.PublicInt = 20				; Зміна значення властивості призведе до зміни ураження функцією DamageTargBasedonPublic
	myQuestRef.DamageTargBasedOnPublic(akTarget)		; Ви можете маніпулювати значенням ураження функцією DamageTargBasedonPublic шляхом зміни значення властивості PublicInt
	myQuestRef.DamageTargBasedOnPrivate(akTarget)		; Величину ураження цієї функції можна змінити тільки у скрипті myQuestNameScript
EndEvent

Отримання доступу до властивостей будь-якого іншого скрипту[edit | edit source]

Ви можете отримати доступ до будь-якого скрипту тим самим чином, що наведено у прикладі вище. Для цього ви маєте оголосити властивість у вашому скрипті типу об'єкту, до якого ви бажаєте отримати доступ. Якщо до вашого об'єкту долучено обидва скрипти: і той, до якого слід отримати доступ, і той, з якого слід отримати доступ, то тип властивості має збігатися з іменем скрипту, до якого ви хочете отримати доступ. У такому випадку слід бути обережним, щоб тип властивості не збігався з іменем об'єкту. До усіх об'єктів може бути долучено декілька скриптів, тому слід вказувати саме ім'я скрипту, до якого ви бажаєте отримати доступ. Список базових об'єктів, що можна використовувати у якості типів, ви можете переглянути за цим посиланням (en)

Попередження[edit | edit source]

Слід бути обережним із змінними та авто-властивостями скрипту, що розширюється іншим скриптом, особливо коли якийсь скрипт десь у іншому місці має властивість, що посилається на базовий скрипт, або вона зводиться до його типу. У такому випадку може існувати дві копії скрипту, що долучено до одного об'єкту, що, у свою чергу, призведе до існування двох комплектів однакових змінних та властивостей. У цьому разі скрипт, що посилатиметься до базового скрипту буде навмання обирати, до якої з копій звертатися.

Це удвічі вірогідніше зі скриптами, у яких оголошено рідні (native) функції, бо гра може автоматично долучити їх до об'єкту у разі необхідності, а це, у власну чергу, призведе до створення іще однієї копії тих самих змінних та властивостей.

Примітки[edit | edit source]

  • Перелік властивостей у списку властивостей оновлюється лише у випадку додавання нової властивості або після компілювання скрипту у вбудованому редакторі скриптів.

Дивіться також[edit | edit source]