Prop buckets

From HEWIKI
Revision as of 12:47, 2 May 2012 by AtlasCook (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

A Prop Bucket is a storage place for art assets and dynamic instances. It contains a temporary "in memory" list of assets, as opposed to the Area's permanent list of assets and their instances. This information is maintained only on the client and the server is not directly aware of these instances but you can manipulate them from scripts on the client, and those scripts can be told what to do from the server via remote calls, etc.

Description

In HeroEngine, each Area works with instances, which have been created from assets, such as graphical images and textures which are graphically rendered. Each Area has a list of assets which are available to it. These assets are loaded into memory whenever the Area is loaded or "spun up".

There are many times when you need to dynamically introduce art (or other) assets into the client at run-time without it being specified as an asset in the area (such as the components of a spell effect). HeroEngine can do this by loading these assets into a system called a Prop Bucket. A specific asset (AssetSpec) is loaded into this virtual bucket, and then instances are made of that asset. The instances are then "activated" which means that they are graphically rendered (displayed) either on a Virtual Stage (such as a popup window), or rendered in the game world itself.

For example, if a certain spell effect needs certain assets, then instead of each area being required to already contain those assets, a spell script can create a Prop Bucket and place the necessary assets within it. The first time that the spell is cast in a particular Area, it could create a Prop Bucket named "fireballBucket" and place the necessary assets within it. Then future attempts to cast the spell would also attempt to create the same Bucket, but since it was already created, would not cause any resource drain.

Note: All PropBucket functions and actions take place on the client side only.

Propbuckets can be useful for virtual stages, see also:

Related Functions

Create Prop Bucket

This function creates a new Prop Bucket. If the bucket already exists, the operation is aborted. There is nothing wrong with attempting to re-create a PropBucket that already exists. Buckets are not persistent -- when the game client is shut down, neither the bucket nor any of the instances created from it are saved.

Since a Prop Bucket only exists on a client, its instances are only displayed to that one user. If it is desired to display instances to multiple users, then a server-side script would call the client script on several different clients, instructing each one to create a Prop Bucket and the necessary instances, and display them to their respective users all at the same time.


  CreatePropBucket(bucketname as string)

Destroy Prop Bucket

Destroying a prop bucket will delete all assets and instances which are in or were created from that bucket. Attempting to destroy a bucket that does not already exist, will generate a script error.

For optimal results, a Prop Bucket should probably not be destroyed though, unless it is genuinely a one-time-use situation. If there's any chance that its instances might be needed again that day, it's better to leave it in existence.

  DestroyPropBucket(bucketname as string)

Add Asset to Bucket

This function adds a specific asset to a Prop Bucket, and returns a noderef to the added asset. An ID number is also assigned to the added asset.

AddAssetSpecToPropBucket(bucketName as string, assetSpecFQN as string) as noderef

AssetSpecFQN stands for "Asset Spec Fully Qualified Name"

If bucketName does not exist, a value of 0 is returned in the noderef.

Once added, in order to determine the ID number, create an ID variable and set it equal to the noderef. For example:

  newAsset as noderef
  newAsset = AddAssetSpecToPropBucket(FunBucket, "flower.gr2")
 
  newAssetID as ID
  newAssetID = newAsset    // Sets the ID#, based on the noderef

Notes:

Add Asset to Bucket With Callback

Rather than polling using IsAssetSpecReady(), it is often useful to use this alternative external function to add the asset spec to a prop bucket because it generates a callback to a method on a node you specify.

The callback is made to the method AssetSpecReady, passing in the spec as noderef and whether or not the loadFailed as boolean.

// requests the asset specification be loaded and calls back method AssetSpecReady( spec as NodeRef of Class HBSpec, loadFailed as Boolean).
external function AddAssetSpecToPropBucketCB( bucketName as String, assetFQN as String, callbackNode as NodeRef) as noderef

Is Asset Spec Ready

Check if an asset (either PropBucket or area-related) is loaded. Remember, assets load asynchronously... so it can take an undetermined amount of time for the asset to be ready to use. In fact, it could be that that asset needs to be (re)downloaded from the server so the interval could be many seconds in such cases.

IsAssetSpecReady(location as string, assetID as ID) as boolean

If the asset is fully loaded, the function returns a value of TRUE.

location is either null, or the name of a propBucket. If it is blank, this function will search in the active area rather than a Prop Bucket. An invalid or unknown Prop Bucket name will generate a script error.

Example:

  if (IsAssetSpecReady(FunBucket, newAssetID))
    msgArea("It's ready.")
  else
    msgArea("It's not ready yet, let it cook some more.")
  .

Is Asset Spec Broken

In some cases, an asset spec added to a prop bucket will never be ready. The most likely reason that an asset spec would be "broken" is that the FQN specified does not exist in the repository.

if IsAssetSpecBroken( "FunBucket", newAssetID )
  println("The asset spec " + newAssetID + " is broken.")
else
  println("The asset spec " + newAssetID + " is ok.")
.

Note: As an added convenience, for particle specs, the function also checks if the spec's EmitSpec is broken.

If BucketName is empty, the active area's assets will be checked rather than a PropBucket.

Remove Asset Spec From Prop Bucket

  RemoveAssetSpecFromPropBucket(bucketName as string, assetID as ID)

This function will remove an asset from the specified bucket. It will also delete any instances which were created from that asset. Attempting to call this function with an invalid ID or bucket name will generate a script error.

Create Instance from Bucket

CreateInstanceFromPropBucket(bucketName as string, assetSpec as noderef) as noderef

Creates a new instance from the given asset spec as found in the given PropBucket. Returns the node reference to the newly-created instance if successful, or 0 if the bucket or asset spec could not be found.

If bucketName is null, the new instance will be created in the Area. Otherwise it will be created inside the same bucket that the asset already exists in.

Note that when an instance is created, it still isn't displayed until it is activated.

Activate Instance

ActivateInstance(instanceID as ID, stageName as string) as boolean

For more info, see ActivateInstance()

Remove Instance from Bucket

This function deletes an instance. It also automatically deactivates or disconnects the specified instance from any parents, children, or associations, as appropriate.

RemoveInstanceFromPropBucket(bucketName as string, instance as noderef) as bool


Remove Instances from Bucket

RemoveInstancesFromPropBucket(bucketName as string, asset as noderef) as bool

Removes all instances of the specified asset from the propBucket (automatically inactivating them first, as above). Returns false if the bucket could not be found.

Note: If the asset passed in is 0, then this will remove all instances from all assets in the propbucket.

Example

This function will load the asset "flower.gr2" into a Prop Bucket called "greenhouse", and then renders (graphically displays) a few instances of the asset before then deleting everything. Note that this script would be impractical in the game world, since the instances would be rendered and deleted too fast to see! The following code is for an example only:

function displayPrettyThings()
 
  CreatePropBucket("greenhouse")
 
  flower as noderef
  flower = AddAssetSpecToPropBucket("greenhouse", "flower.gr2")
 
  flowerID as ID = flower                  // Get the ID# of the new noderef
 
  if (IsAssetSpecReady("greenhouse", flowerID))
 
 
    rose1 as noderef = CreateInstanceFromPropBucket("greenhouse", flower)
    rose2 as noderef = CreateInstanceFromPropBucket("greenhouse", flower)
    rose3 as noderef = CreateInstanceFromPropBucket("greenhouse", flower)
 
    roseID as ID = rose3
    ActivateInstance(roseID, "greenhouse")   // This rose would be rendered in the virtual stage screen
 
    roseID = rose2
    ActivateInstance(roseID , "")  // This rose would be rendered in the world/area
 
    nullNoderef as noderef 
 
    RemoveInstanceFromPropBucket("greenhouse", rose1)          // Remove rose1
    RemoveInstancesFromPropBucket("greenhouse", nullNoderef)   // Removes rose2 and rose3
    RemoveAssetSpecFromPropBucket("greenhouse", flowerID)
 
    DestroyPropBucket("greenhouse")
  else
    MsgArea("Can't create flowers yet, since the flower asset isn't loaded yet.")
  .
.


IMPORTANT

One thing that is tricky is that adding an asset to a propbucket is an asynchronous operation. Consequently, you can not actually use it until it is loaded requiring that you either poll using the IsAssetSpecReady() function until the asset loads (via a timer) or add the asset using the AddAssetSpecToPropBucketCB() external function which will perform a method callback when the asset is ready.

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox