HeroEngine Forums
Welcome, Guest. Please login or Register for HeroCloud Account.

Author Topic: character portrait  (Read 1604 times)

Thazager

  • General Accounts
  • *
  • Posts: 1138
  • Never stop learning
    • View Profile
    • Heroes and Villains MMORPG
character portrait
« on: Mar 09, 13, 07:59:03 PM »

Intermediate level script, beginner level GUI

This will display an animated picture of your character.  It seems to stop animating after 10-20 mins, so another timer to restart it might be used. When you make updates to the character (like a hat) make sure to call update again.

In the DOM, create a new (clientside) class
name = TMP_Portrait
archtype = guicontrol
add a parent to the class, _GUIBaseWindow

click open script

In new script TMP_Portrait
Create new picture based on character
save it to repository
load and display this picture
add a light


Code: [Select]

// main function to call
shared function UpdateCharacterPortrait()
  stageName as String = GetStageName()
  StageDestroy(stageName)
  if (DoesPropBucketExist(stageName))
    DestroyPropBucket(stageName)
  .
  DoCustomPortrait()
.

// stage name (used many functions)
function GetStageName() as String
  return "tmpPortrait"
.

// set up background loading
function DoCustomPortrait()
  portraitTimer as NodeRef of Class genericTimer = CreateNodeFromClass("genericTimer")
  portraitTimer.myTimer.fireRate = 0:00:00.2
  portraitTimer.myTimer.script = SYSTEM.EXEC.THISSCRIPT
  portraitTimer.timerData = 1
  portraitTimer.myTimer.start()
  println(SYSTEM.EXEC.THISFUNCTION+"; "+"started portraitTimer:"+ portraitTimer)
.

// timer to keep things from being called to early
function myTimer_tick()
  where me is kindof genericTimer
    data as List of String
    SplitBy(me.timerData, ",", data)
    part as Integer = data[1]
    when part
      is 1
        CreatePortraitVirtualStage()
        me.timerData = 2
      .
      is 2
        assetID as ID = CreateBillboard()
        me.timerData = 3
        me.timerData += ","+ assetID
      .
      is 3
        if (data.length >= 2 and StringIsID(data[2]))
          if (IsAssetSpecReady(GetStageName(), data[2]))
            AssetSpecReady(data[2])
          else
            println("AssetSpec "+ data[2] +" NOT ready")
            return
          .
        else
          println("data.length:"+ data.length +", timerData:"+ me.timerData)
        .
        me.timerData = 4
      .
      is 4
        SavePortraitVirtualStageToTexture()
        me.timerData = 5
      .
      is 5
        MakePortraitStageWindow()     // moving pic
        DestroyNode(me)
      .
      default
      .
    .
  .
.

//setup the virtual stage
function CreatePortraitVirtualStage()
  stageName as String = GetStageName()
  stageSizeX as Integer = 128
  stageSizeY as Integer = 128
  bStageCreated as Boolean = StageCreate(stageName, stageSizeX, stageSizeY)
  stageChar as NodeRef of Class HBNode = CopyCharacterIntoVirtualStage(GetPlayerCharacterNode(), stageName)
  bStageSetZoom as Boolean = StageSetZoom(stageName,0.055)    // zoom in/out
  StageSetRotation(stageName, (0,175,0))    // rotate around character

  // position character on panel
  position as Vector3 = stageChar["Position"]
  position.y = position.y - 0.175     // camera up/down
  position.x = position.x - 0.012     // camera left/right
  stageChar["Position"] = position
  StageSetAutoCenterOnObjects(stageName, true)
  StageSetBackdropColor(stageName, "#0.5,0.5,0.5,0")  // background color RGBA
  Lights()
.

function CreateBillboard() as ID
  CreatePropBucket(GetStageName())
  assetSpec as NodeRef of Class HBSpec = AddAssetSpecToPropBucket(GetStageName(), "\engine\billboard.bil")
  return assetSpec
.

function AssetSpecReady(assetID as ID)
  stageName as String = GetStageName()
  assetSpec as NodeRef of Class HBSpec = assetID
  billboard as NodeRef of Class HBNode = CreateInstanceFromPropBucket(stageName, assetSpec)
  billboard["TextureName"] = "/gui/character_selection_background_1.dds"
  SetNodePosition(billboard, (0,0,0))
  ActivateInstance(billboard, stageName)
.

// get the texture data from the virtual stage and save it to the local repository
function SavePortraitVirtualStageToTexture()
  stageName as String = GetStageName()
  stageTexData as RawData = StageGetTextureAsRawData(stageName,"dds")
  texFQN as String = GetCharacterPortraitFQN()
  bSavedTexData as Boolean = SaveLocalRepositoryAsRawData(texFQN, SYSTEM.EXEC.THISSCRIPT, stageTexData)
  externalRef as String = GetExternalReferenceForLocalRepositoryFQN(texFQN)
.

// display the texture
function MakePortraitStageWindow()
  stageName as String = GetStageName()
  stageSizeX as Integer = 128
  stageSizeY as Integer = 128
  stageWindow as NodeRef of Class GUIControl = FindGUIControlByName(None, "TMP_Portrait.PortraitPanel")
  stageWindow.texture  = ":" + stageName
.

// get picture from repository
function GetCharacterPortraitFQN() as String
  portraitFQN as String = "/portraits/character.dds"
  account as NodeRef = GetPlayerCharacterNode()
  if (account != None)
    where account is kindof _PlayerAccount
      character as NodeRef = account.GetMyCharacter()
      if (character != None)
        where character is kindof _PlayerCharacter
          charName as String = character.name
          strutils:stripAllSpaces(charName)
          portraitFQN = "/portraits/" + charName + ".dds"
        .
      .
    .
  .
  return portraitFQN
.

// make it lighter
function Lights()
  SYSTEM.EXEC.CPULIMIT = 0:0:10 // Increase if needed
  assetPath as String = "\world\segment\demoland\resources\light.lit"
  TempAsset as NodeRef of Class HBSpec
  CreatePropBucket("propBucketName")
  TempAsset = AddAssetSpecToPropBucket("propBucketName", assetPath)
  if TempAsset == None
    println("Could not add asset spec to propbucket")
    return
  .

  instanceID as ID
  instanceID = CreateInstanceFromPropBucket("propBucketName",TempAsset)
  if ActivateInstance(instanceID,GetStageName()) == false
    println("Failed to activate instance")
    return
  .
  println("Light Instance is " + instanceID)
 
  instance as NodeRef of Class HBNode = instanceID
  instance["Range"] = "5"
  instance["Intensity"] = "2"
  pos as Vector3 = "(0,0,-1)"
  SetNodePosition(instance,pos)
.


In the GUI editor create a new GUI
name = TMP_Portrait
inherited from = _movepanel
class = TMP_Portrait

In the properties section of TMP_Portrait
set pos to 50, 200
set size to 140, 140
set defaultStatePresentation  color to 0,1,1,0.5     // semi-transparent

add 1 _panel

Set name of _panel to PortraitPanel
set alpha mask size to 256, 256          // size of the alpha (not the picture)
set alpha mask material to GUI\alphaCircle256.dds   // makes a round picture
set pos to 6, 6
set size to 128, 128

In (clientside) script E_PlayerAccountClassMethods under the chatwindow

Code: [Select]
        // Portrait - tutorial
      portrait as NodeRef of Class TMP_Portrait = FindGUIControlByName(None, "TMP_Portrait")
      if portrait != None
        destroynode(portrait)
      .
      portrait = CreateNodeFromPrototype("TMP_Portrait")
      portrait.build = true
      portrait.owner = 0


      TMP_PortraitClassMethods:UpdateCharacterPortrait()    // start it


Logged

PN-Dwight

  • General Accounts
  • *
  • Posts: 465
    • View Profile
    • Pirates' Nest
Re: character portrait
« Reply #1 on: Mar 10, 13, 06:27:00 AM »

Quite a handy tutorial!

Though I remember some discussions going on about using virtual stages (you are rendering the character twice the entire time basically, performance hit). A better way would be to display the characterparts, instead of using a virtual stage.

I believe Hero Journey is using it for their inventory system :)

Thazager

  • General Accounts
  • *
  • Posts: 1138
  • Never stop learning
    • View Profile
    • Heroes and Villains MMORPG
Re: character portrait
« Reply #2 on: Mar 10, 13, 10:16:12 PM »

Ok, thanks.
Logged