Difference between revisions of "Variables and Properties"

From the CreationKit Wiki
Jump to navigation Jump to search
imported>Evernewjoy
imported>Marth
 
(37 intermediate revisions by 13 users not shown)
Line 1: Line 1:
=Description=
==Description==


Variables and Properties are similar things, they both "hold" values and objects. A variable is "private" meaning that only that script is aware of them, can set their contents, and get their contents.  A Property is essentially a variable that other scripts can access, their contents can be set and get by a other scripts.
Variables and Properties are similar things, they both "hold" values and objects. A variable is "private" meaning that only that script is aware of them, can set their contents, and get their contents.  A Property is essentially a variable that other scripts can access, their contents can be set and get by a other scripts. If a variable or property holds a numeric value, like an integer, get/set returns its value. If a variable or property holds an object, you can access that object's properties and functions. (This is analogous to a reference variable from the old scripting system.)


If a variable or property holds a numeric value, like an integer, get/set returns its value. If a variable or property holds an object, you can access that object's properties and functions. (This is analogous to a reference variable from the old scripting system.)


=Declaring Variables=
==Declaring Variables==
<source lang="papyrus">
<source lang="papyrus">
  float myFloat
  float myFloat
Line 11: Line 10:
</source>
</source>


MyFloat starts at 0, myOtherFloat starts at 13.5 and can be set by scripting in it's own script, but nothing else.
MyFloat starts at 0, myOtherFloat starts at 13.5 and can be set by scripting in its own script, but nothing else.


=Declaring Properties=
==Declaring Properties==
==Full Property==
===Full Property===
To define a property, you first write the type, then "property", then the name of the property. You then define two functions, a get which returns the property's value, and a set which takes a new value for the property. And then you cap it off with "EndProperty"
To define a property, you first write the type, then "property", then the name of the property. You then define two functions, a get which returns the property's value, and a set which takes a new value for the property. And then you cap it off with "EndProperty"


Line 76: Line 75:
The above property is write-only. Scripts outside of this one cannot read the value. It also uses an if to make sure the value is never below 0.
The above property is write-only. Scripts outside of this one cannot read the value. It also uses an if to make sure the value is never below 0.


==Auto Properties==
If a full property has its value set in the Creation Kit, its ''set'' function will be called when the object is initialized, just before its [[OnInit]] event is called.
 
===Auto Properties===
An auto property is one that writes the above get and set functions for you, behind the scenes. There are also some minor optimizations in the VM that speed up auto properties slightly. To make an auto property, simply omit the functions and endProperty and add "auto" to the end of the property definition. You can set the property's initial value using the "= <value>" syntax.
An auto property is one that writes the above get and set functions for you, behind the scenes. There are also some minor optimizations in the VM that speed up auto properties slightly. To make an auto property, simply omit the functions and endProperty and add "auto" to the end of the property definition. You can set the property's initial value using the "= <value>" syntax.


Line 84: Line 85:
</source>
</source>


==Auto Read-only Properties==
 
===Auto Read-only Properties===
An auto read-only property is an auto property that can never have its value changed. This can be convenient if certain numbers mean different things in your script and you want to use a name instead of a number to represent it. You specify these by using "AutoReadOnly" instead of "Auto". These properties ''must'' have their initial value set using "= <value>" syntax.
An auto read-only property is an auto property that can never have its value changed. This can be convenient if certain numbers mean different things in your script and you want to use a name instead of a number to represent it. You specify these by using "AutoReadOnly" instead of "Auto". These properties ''must'' have their initial value set using "= <value>" syntax.


Line 92: Line 94:
</source>
</source>


==Conditional Properties==
 
===Conditional Properties===
Properties cannot be declared as conditional. Auto properties can be defined as conditional because what they actually do is define the hidden variable they create as conditional. This is why you see mangled auto property names when you select a Papyrus variable in the condition system - you're selecting from a list of hidden variables.
Properties cannot be declared as conditional. Auto properties can be defined as conditional because what they actually do is define the hidden variable they create as conditional. This is why you see mangled auto property names when you select a Papyrus variable in the condition system - you're selecting from a list of hidden variables.


Line 100: Line 103:
</source>
</source>


More information on the conditional keyword can be found in the [[Papyrus_Introduction#Writing_Custom_Functions|Papyrus Introduction]]
More information on the conditional keyword can be found in the [[Papyrus_Introduction#Writing_Custom_Functions|Papyrus Introduction]] and in the [[Flag_Reference|Flag reference]]
 


=Getting Properties of a quest script=
==Getting Properties of a Quest Script==
==From result script owned by the same quest==
===From Result Script Owned by the Same Quest===
Often you will need to get a property of a quest script, and use it in a result script somewhere else. This is one of the more tricky things, but once you understand what's happening, it makes sense. First look at the example, then we'll describe what's happening.
Often you will need to get a property of a quest script, and use it in a result script somewhere else. This is one of the more tricky things, but once you understand what's happening, it makes sense. First look at the example, then we'll describe what's happening.


Line 125: Line 129:
In the result script, we create a variable that represents the quest script that has the property we want (in this case MQ01Script's "DeadCount" property). Note our variable myQuest is declare as MQ01Script. This is because when we made our quest script "scriptName MQ01Script extends Quest" we've essentially created a new type of object... a MQ01Script object. GetOwningQuest returns a quest object (before we extended it). So we also need to ''cast'' the quest returned by GetOwningQuest AS that new object "myQuest = GetOwningQuest() as MQ01Script" so we have access to it's extended properties. If we didn't cast it as a MQ01Script it would only have the functions and properties of a Quest object, which wouldn't contain our deadCount property.
In the result script, we create a variable that represents the quest script that has the property we want (in this case MQ01Script's "DeadCount" property). Note our variable myQuest is declare as MQ01Script. This is because when we made our quest script "scriptName MQ01Script extends Quest" we've essentially created a new type of object... a MQ01Script object. GetOwningQuest returns a quest object (before we extended it). So we also need to ''cast'' the quest returned by GetOwningQuest AS that new object "myQuest = GetOwningQuest() as MQ01Script" so we have access to it's extended properties. If we didn't cast it as a MQ01Script it would only have the functions and properties of a Quest object, which wouldn't contain our deadCount property.


In otherwords, 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.
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.


===With kmyQuest===
====With kmyQuest====
If the fragment you are using has a "kmyquest" drop down, you can select a script attached to the quest owning that fragment, and then use the kmyQuest "magic variable" to refer to quest script without casting it.
If the fragment you are using has a "kmyquest" drop down, you can select a script attached to the quest owning that fragment, and then use the kmyQuest "magic variable" to refer to quest script without casting it.


Line 134: Line 138:
  float myDeadCount
  float myDeadCount
  myDeadCount = kmyQuest.deadCount ;getting property
  myDeadCount = kmyQuest.deadCount ;getting property
  kmyQuest.deadCount = 5 ;setting property
  kmyQuest.deadCount = 10 ;setting property
</source>
</source>


==From a non-owned fragment / other quest script==
===From Within a Magic Effect Script===
Need to write this... basic gist: You need to define a property in your script (and set it through the editor interface to be the other quest whose properties you want access to), then you can access that property's properties. In other words, your script has a property of the other quest; then you access that property's properties.


[[User:Evernewjoy|Evernewjoy]]
Let's look at an example where a scripted spell accesses a quest's properties:
<source lang="papyrus">
Scriptname myQuestNameScript extends Quest


----
Int Property PublicInt Auto ; This value is defined as a property and can be accessed from outside this script


'''Accessing a Script's Variables From Another Script'''
Int PrivateInt = 30 ; This value is private to the script and cannot be accessed from outside this script


----
Function DamageTargBasedOnPublic(Actor akTarget)
 
;This code will damage the akTarget for PublicInt damage
''Here are the steps to using a variable from one script in another script, please note the script could be of any type, not just a quest script.''
akTarget.DamageAV("Health", PublicInt)
 
EndFunction
'''1.''' Define the variable you want to pass to other scripts as a property as explained above.
 
Here is a full script containing a property / publicly-available variable


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




Now that we have defined our quest script and created an accessible property, we can control it from the outside.
<source lang="papyrus">
<source lang="papyrus">
Scriptname RamaJRMasterScript extends ObjectReference
Scriptname mySpellEffectScript extends activemagiceffect
 
;this value is private to the script and cannot be
;accessed
int hiddenInt = 144 ;initialized value
 
;the name of the property/var you want to use in
;other scripts, which is just a wrapper for the
;hidden var


int property publicInt
myQuestNameScript Property myQuestRef auto
int function get()
return hiddenInt
endFunction


function set(int value)
Event OnEffectStart(Actor akTarget, Actor akCaster)
hiddenInt = value
myQuestRef.PublicInt = 20 ; This will change the damage for the DamageTargBasedonPublic Function
endFunction
myQuestRef.DamageTargBasedOnPublic(akTarget) ; You can manipulate this damage by changing PublicDamage Prior to calling it
endProperty
myQuestRef.DamageTargBasedOnPrivate(akTarget) ; This will always do 30 damage unless the quest changes the private variable
EndEvent
</source>
</source>


After this point, you will need to go to the properties window for whatever your script is attached to (in this case, the script properties windows of the script for mySpellEffectScript) and then set the property for myQuestRef to the Quest associated with the quest script.


==Getting Properties From Any Other Script==
You can access the properties of any script attached to any object not just those attached to quests. But you will be accessing a specific script attached to a specific object.


(code above was essentially copied from earlier in this article, but this is a complete running script)
'''Example:'''
<source lang="papyrus">
ScriptName ScriptA extends ObjectReference


'''2.''' In the other script, where you want to access the variable from the script above, you must define the following:
int Property count Auto
float Property weight Auto
</source>


A. the script that contains the variable you want to access, you must define the script as a property, note that the type of the property is the name of the script that contains the variable you want.
B. a variable that is going to be used to refer to the script property in A (above)
Here is a working script with some especially important lines emphasized.
Note that the message used in this script must be created by you if you want to use this script example, use the %.0f twice in your message to accommodate the two variables I am passing. I pass one variable just so you have a way to know your message itself is working properly:


If both scripts are attached to the same game object (Quest, Perk, ObjectReference, etc.) accessing the variables from the other script is simply a matter of casting self to the correct type.


'''Example:'''
<source lang="papyrus">
<source lang="papyrus">
Scriptname RamaWorkingSCRIPT extends ObjectReference
ScriptName ScriptB extends ObjectReference


;you must set these "property" values outside this
Event OnInit()
;script.
    ScriptA me = self as ScriptA
;see number 3 in article (below)
    me.count = 1
    me.weight = 12.9


message property msg auto
    (self as ScriptA).count += 7  ; this in-line method works too
EndEvent
</source>




;***
If the other script is attached to some other object then you'll need a way to access that object. The most common way is a property but you might also get access through some Event argument instead.
RamaJRMasterScript property masterScript auto
RamaJRMasterScript scriptVar
;***


;the scriptVar above is very important because you
'''Example:'''
;cannot directly access a property script, you must
<source lang="papyrus">
;use a variable that is private to this script.
ScriptName ScriptB extends ObjectReference
 
 
bool done = false ;ensures switch runs only once
int test = 2
 
;any event could be used here, like onTriggerEnter,
;make a trigger volume in the editor and attach
;this script to it and use onTriggerEnter for
;easy testing
 
;this example works with an activator of some kind
;like a button or door
 
EVENT onActivate (objectReference triggerRef)
 
if (!done)


  ;only run if player is the one activating this
ScriptA Property remoteObject Auto
  ;object
  if(triggerRef == game.getplayer())
      done = true  ;makes button run only once
;--- External Variable Script Section Begins


;***
Event OnInit()
scriptVar = masterScript
    remoteObject.count = 1
;***
    remoteObject.weight = 12.9
EndEvent


;this line above is VERY important, you have to
Event OnActivate(ObjectReference akActionRef)
;set the script var within the script itself,
    if (akActionRef as ScriptA)
;to the script-as-a-property that contains the
        (akActionRef as ScriptA).count += 7
;the variable you want to access
    endif
 
EndEvent
scriptVar.publicInt += 1
 
;you can now manipulate the other script's hidden
;var via its public property name and functions,
;using the scriptVar
 
msg.show(scriptVar.publicInt,test)
 
;a sample message to prove you have accessed the
;other script correctly, should get a value of 10
;for the script var when it is displayed
  endif
endif
 
endEVENT
</source>
</source>


'''3.''' Final steps, setting the properties
You must have an object in the game for each script.
You need an instance of the script that has your variable that you want, in this case RamaJRMasterScript.
A. Once you create the object, could be an activator of any kind or an actor, or anything really, attach the RamaJRMasterScript script.
B. Name this object something clear, like "sampleReferenceWithScriptInstance"
C. Now make the switch object, I used a dwarven button, you can use any activator you want.
D. Now attach the script RamaWorkingSCRIPT to the button/activator.
E. '''Now set the properties of the button/activator:'''
msg = your sample message that you create that contains two %.f for use with the variables
masterScript = point this to the INSTANCE/Object of the script that you have, the name will appear as the fancy name you created above.
Plus it is very likely to be the only option the list
If you do not make an instance of the script that contains the variable you want to access, you cannot use the variable, you must have an object with the variable-reservoir script attached to itself.
And remember to set the scriptVar to the script-as-a-property, the highlighted line in the script itself.
If you follow all these steps you will now be able to access and modify variables from one script in another script.
'''Example uses:
'''
1. keeping track of a total of enemies killed, where each enemy has a death script to increment a value in a master script
2. keeping track of number of switches activated, where each switch increments a master script variable


3. basically infinity different very important and wonderful things, hee hee!
For a list of objects you can use as a type that are already within the game, visit the [[Script Objects]] page.


'''See Also: [[Function_Reference#Accessing_Functions_From_Other_Scripts|Accessing Functions From Other Scripts]]'''


Rama
==Warnings==
Be careful with variables and auto properties on "base" scripts, which are extended by multiple other scripts. This is because it would be possible to have multiple scripts containing the same variable or auto property attached to the same object, and the game may not reliably select the appropriate instance of the variable or property.


PS: Infinite ♥ and thank you's to our friends at Bethesda for giving us such an awesome game as Skyrim and such an beautiful editor as the Creation Kit!
For example, consider the following 3 short scripts:<source lang="papyrus">ScriptName Base extends ObjectReference


Int Property MyValue Auto</source>
<source lang="papyrus">ScriptName Derived1 extends Base</source>
<source lang="papyrus">ScriptName Derived2 extends Base</source>
Because both Derived1 and Derived2 extend Base, they each inherit its MyValue property.


The Creation Kit is incredibly stable, robust, and a joy to use.
Now, imagine that an object is created and the scripts Derived1 and Derived2 are both attached to it. Trying to access the value of MyValue by casting this object to Base will not reliably return the same value:<source lang="papyrus">(MyObjectReference as Base).MyValue</source>


This is doubly-true of variables and auto properties declared in [[:Category:Script_Objects|native script objects]], such as the [[Actor Script]]. This is because the game can attach these to in-game objects at any time if it needs to, thereby creating another copy of the variable or auto property.


Thank you!
In order to avoid these problems, avoid editing native script objects, and in the case where a single object has multiple scripts attached to it that inherit the same property, make sure you cast it to its most derived form before attempting to access that property. In the above example, that would mean using syntax like this:<source lang="papyrus">(MyObjectReference as Derived1).MyValue</source>
 
End [[User:Evernewjoy|Evernewjoy]]
 
=Warnings=
Be careful with variables and auto properties on scripts that are extended by other scripts - especially where some script somewhere else may have a property pointing to the base script, or trying to cast to the base script. This is because it would be possible to have two copies of a script attached to the same object, thereby creating two copies of the variable/auto property - and the other scripts that refer to the base script may randomly pick which one to talk to.
 
This is doubly-true of scripts with native functions, as the game can attach these to in-game objects at any time if it needs to, thereby creating another copy of the variable or auto property.


==Notes==
==Notes==
*The list of properties in properties dialog is only updated after adding a new property or after compiling the script with the build-in editor.
*The list of properties in properties dialog is only updated after adding a new property or after compiling the script with the build-in editor.


=See Also=
*You should avoid adding or removing Properties to a base item's script if one or more of its child ObjectReference's is already baked into a current save game.
 
==See Also==
*[[Variable Reference]]
*[[Property Reference]]
*[[Property Reference]]
*[[Default Value Reference]]
*[[Cast Reference]]


[[Category: Papyrus]]
[[Category: Papyrus]]
[[Category: Papyrus Tutorials]]
[[Category: Papyrus Tutorials]]
{{Languages}}

Latest revision as of 18:28, 12 February 2017

Description[edit | edit source]

Variables and Properties are similar things, they both "hold" values and objects. A variable is "private" meaning that only that script is aware of them, can set their contents, and get their contents. A Property is essentially a variable that other scripts can access, their contents can be set and get by a other scripts. If a variable or property holds a numeric value, like an integer, get/set returns its value. If a variable or property holds an object, you can access that object's properties and functions. (This is analogous to a reference variable from the old scripting system.)


Declaring Variables[edit | edit source]

 float myFloat
 float myOtherFloat = 13.5

MyFloat starts at 0, myOtherFloat starts at 13.5 and can be set by scripting in its own script, but nothing else.

Declaring Properties[edit | edit source]

Full Property[edit | edit source]

To define a property, you first write the type, then "property", then the name of the property. You then define two functions, a get which returns the property's value, and a set which takes a new value for the property. And then you cap it off with "EndProperty"

Example:

int myInt_Var = 0   ; Where the property's value is stored
int property myInt
  int function get()
    return myInt_Var
  endFunction
  function set(int value)
    myInt_Var = value
  endFunction
endProperty

If you leave out the get function, the property is write-only - other people can set the value, but no one can read it. The local script, of course, can read the actual variable the property works with. If you leave out the set function, the property is read-only - other people can see the value, but they can't change it. Again, the local script can always set the variable that the property returns.

You don't have to just have the property return and set the value like you see above - the functions could do anything. You could, for example, put some if statements in the set function to ensure that the value is never outside a certain range. Or you could even play an animation when a certain value is set. Heck, you don't have to actually have a variable at all - it could be a calculated value or a constant.

Example:

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

The above property hides the Lock and IsLocked ObjectReference functions so that you can lock and unlock this object by simply setting Locked to true or false.

Example:

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

The above property is read-only. Scripts outside of this one cannot change the value, but the script itself can change the value of the variable.

Example:

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

The above property is write-only. Scripts outside of this one cannot read the value. It also uses an if to make sure the value is never below 0.

If a full property has its value set in the Creation Kit, its set function will be called when the object is initialized, just before its OnInit event is called.

Auto Properties[edit | edit source]

An auto property is one that writes the above get and set functions for you, behind the scenes. There are also some minor optimizations in the VM that speed up auto properties slightly. To make an auto property, simply omit the functions and endProperty and add "auto" to the end of the property definition. You can set the property's initial value using the "= <value>" syntax.

Example:

int property myInt = 5 auto


Auto Read-only Properties[edit | edit source]

An auto read-only property is an auto property that can never have its value changed. This can be convenient if certain numbers mean different things in your script and you want to use a name instead of a number to represent it. You specify these by using "AutoReadOnly" instead of "Auto". These properties must have their initial value set using "= <value>" syntax.

Example:

int property myReadOnlyInt = 20 autoReadOnly


Conditional Properties[edit | edit source]

Properties cannot be declared as conditional. Auto properties can be defined as conditional because what they actually do is define the hidden variable they create as conditional. This is why you see mangled auto property names when you select a Papyrus variable in the condition system - you're selecting from a list of hidden variables.

Example:

int property myVar auto conditional

More information on the conditional keyword can be found in the Papyrus Introduction and in the Flag reference


Getting Properties of a Quest Script[edit | edit source]

From Result Script Owned by the Same Quest[edit | edit source]

Often you will need to get a property of a quest script, and use it in a result script somewhere else. This is one of the more tricky things, but once you understand what's happening, it makes sense. First look at the example, then we'll describe what's happening.

 ;I have a quest script with this in it:
 scriptName MQ01Script extends Quest
 int property deadCount auto 

 ;I have a result script (OWNED by MQ01) with this in it:
 MQ01Script myQuest                        ;declares a variable "myQuest" which is a TYPE of MQ01Script
 myQuest = GetOwningQuest() as MQ01Script  ;sets the myQuest variable to it's owning quest as the type MQ01Script
 float myDeadCount                         ;declaring the variable "myDeadCount" 
 myDeadCount = myQuest.deadCount           ;setting local variable to be the quest's property value
 ;you can also set the quest property thusly:
 myQuest.deadCount = 10

What's happening here is that we have a property "deadCount" that is in the script "MQ01Script" attached to MQ01. We also have a script that is owned by MQ01 (could be dialogue result, package result, or script attached to an alias).

In the result script, we create a variable that represents the quest script that has the property we want (in this case MQ01Script's "DeadCount" property). Note our variable myQuest is declare as MQ01Script. This is because when we made our quest script "scriptName MQ01Script extends Quest" we've essentially created a new type of object... a MQ01Script object. GetOwningQuest returns a quest object (before we extended it). So we also need to cast the quest returned by GetOwningQuest AS that new object "myQuest = GetOwningQuest() as MQ01Script" so we have access to it's extended properties. If we didn't cast it as a MQ01Script it would only have the functions and properties of a Quest object, which wouldn't contain our deadCount property.

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.

With kmyQuest[edit | edit source]

If the fragment you are using has a "kmyquest" drop down, you can select a script attached to the quest owning that fragment, and then use the kmyQuest "magic variable" to refer to quest script without casting it.

the above would be simplified to just:

 float myDeadCount
 myDeadCount = kmyQuest.deadCount ;getting property
 kmyQuest.deadCount = 10 ;setting property

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

Let's look at an example where a scripted spell accesses a quest's properties:

Scriptname myQuestNameScript extends Quest

Int Property PublicInt Auto		; This value is defined as a property and can be accessed from outside this script

Int PrivateInt = 30			; This value is private to the script and cannot be accessed from outside this script

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


Now that we have defined our quest script and created an accessible property, we can control it from the outside.

Scriptname mySpellEffectScript extends activemagiceffect

myQuestNameScript Property myQuestRef auto

Event OnEffectStart(Actor akTarget, Actor akCaster)
	myQuestRef.PublicInt = 20				; This will change the damage for the DamageTargBasedonPublic Function
	myQuestRef.DamageTargBasedOnPublic(akTarget)		; You can manipulate this damage by changing PublicDamage Prior to calling it
	myQuestRef.DamageTargBasedOnPrivate(akTarget)		; This will always do 30 damage unless the quest changes the private variable
EndEvent

After this point, you will need to go to the properties window for whatever your script is attached to (in this case, the script properties windows of the script for mySpellEffectScript) and then set the property for myQuestRef to the Quest associated with the quest script.

Getting Properties From Any Other Script[edit | edit source]

You can access the properties of any script attached to any object not just those attached to quests. But you will be accessing a specific script attached to a specific object.

Example:

ScriptName ScriptA extends ObjectReference

int Property count Auto
float Property weight Auto


If both scripts are attached to the same game object (Quest, Perk, ObjectReference, etc.) accessing the variables from the other script is simply a matter of casting self to the correct type.

Example:

ScriptName ScriptB extends ObjectReference

Event OnInit()
    ScriptA me = self as ScriptA
    me.count = 1
    me.weight = 12.9

    (self as ScriptA).count += 7  ; this in-line method works too
EndEvent


If the other script is attached to some other object then you'll need a way to access that object. The most common way is a property but you might also get access through some Event argument instead.

Example:

ScriptName ScriptB extends ObjectReference

ScriptA Property remoteObject Auto

Event OnInit()
    remoteObject.count = 1
    remoteObject.weight = 12.9
EndEvent

Event OnActivate(ObjectReference akActionRef)
     if (akActionRef as ScriptA)
         (akActionRef as ScriptA).count += 7
     endif
EndEvent


For a list of objects you can use as a type that are already within the game, visit the Script Objects page.

See Also: Accessing Functions From Other Scripts

Warnings[edit | edit source]

Be careful with variables and auto properties on "base" scripts, which are extended by multiple other scripts. This is because it would be possible to have multiple scripts containing the same variable or auto property attached to the same object, and the game may not reliably select the appropriate instance of the variable or property.

For example, consider the following 3 short scripts:

ScriptName Base extends ObjectReference

Int Property MyValue Auto
ScriptName Derived1 extends Base
ScriptName Derived2 extends Base

Because both Derived1 and Derived2 extend Base, they each inherit its MyValue property.

Now, imagine that an object is created and the scripts Derived1 and Derived2 are both attached to it. Trying to access the value of MyValue by casting this object to Base will not reliably return the same value:

(MyObjectReference as Base).MyValue

This is doubly-true of variables and auto properties declared in native script objects, such as the Actor Script. This is because the game can attach these to in-game objects at any time if it needs to, thereby creating another copy of the variable or auto property.

In order to avoid these problems, avoid editing native script objects, and in the case where a single object has multiple scripts attached to it that inherit the same property, make sure you cast it to its most derived form before attempting to access that property. In the above example, that would mean using syntax like this:

(MyObjectReference as Derived1).MyValue

Notes[edit | edit source]

  • The list of properties in properties dialog is only updated after adding a new property or after compiling the script with the build-in editor.
  • You should avoid adding or removing Properties to a base item's script if one or more of its child ObjectReference's is already baked into a current save game.

See Also[edit | edit source]


Language: English  • français