Results 1 to 9 of 9
  1. #1

    Default Displaying Steam Avatars with friends list in Scaleform

    Hey everyone!

    I'm working on an updating friends list component that displays the player's steam friends with each friends steam avatar portrait. I've run into an issue passing the texture read in from ReadOnlineAvatar to scaleform or even test HUD elements with DrawTile.

    I want to be able to display multiple portraits at once, although each time I read one from Steamworks, it overwrites the previous texture results.

    How can I store or copy the texture, so I can save the older results while still reading in new results?

    Here is an image of the friends list displaying the duplicate avatars:

  2. #2
    MSgt. Shooter Person
    Join Date
    Jul 2011
    Posts
    56

    Default

    Forgive me if this sounds incredibly understated, but can't you just initialize a Texture2D from ReadOnlineAvatar and store it in an array of textures?

    At the same time you can be storing their steam name in another array so that you can use it as a key value like a hash table.

    Obviously psuedo-code
    Code:
    var array<Texture2D> avatars;
    var array<string> names;
    
    
    for( i = 0; i < Steam.FriendsCount; i++)
    {
          names[i] = Steam.Friends[i];
          avatars[i] = Steam.ReadAvatar
    }
    
    function int IndexOfFriend(string name)
    {
          for(int i  = 0; i < 0; i++)
                  if(names[i] == name) return i;
    
         return -1;
    }
    
    Texture2D avatar = avatars[IndexOfFriend("friend name")];
    GFxMoviePlayerVar.SetFriendPic(IndexOfFriend("friend name"), avatar);
    
    SetFriendPic could be an ActionScriptVoid

  3. #3

    Default

    That is essentially what I'm doing, I create a copy of the passed in Texture2D (parameter name Avatar) with the following:
    Code:
    AllAvatarInfos[index].avatarTexture = new class'Texture2D' (Avatar);
    This creates a new texture, but unfortunately doesn't allocate new texture space. It shares memory and simply has a pointer to the original texture data. Copying a Texture2D just copies the reference to the original data. I pass Scaleform the source address so I can load the texture from a custom AS3 UILoader.

    Code:
    AllAvatarInfos[index].avatarSource = "img://" $ AllAvatarInfos[index].avatarTexture.GetPackageName() $ "." $ AllAvatarInfos[index].avatarTexture.Name;
    Here are the textures it creates, although they all are linked to the original when rendered.



    I know this a uScript issue, since I've been testing using DrawTiles (pure Canvas, no Scaleform) and it has the same results. I've even tried storing bitmap copies in AS3, but with no luck. I'm really just looking for a way to deep copy and duplicate textures so that I can display multiple avatars!

  4. #4
    MSgt. Shooter Person
    Join Date
    Jul 2011
    Posts
    56

    Default

    Are you using this?

    Code:
    delegate OnReadOnlineAvatarComplete(const UniqueNetId PlayerNetId, Texture2D Avatar);
    There's no need to create a "new" Texture2D for this. It's going to create a duplicate by assignment it to an array, you're not passing a pointer.

    do it like this
    Code:
    AllAvatarInfos[index].avatarTexture = Avatar;
    If that changes nothing, could you please post all relevant code from the time steam subsys is created and you've assigned that delegate to a function to when you render the image in your HUD?

  5. #5

    Default

    Code:
    AllAvatarInfos[index].avatarTexture = Avatar;
    This results in no new 'textures' being created (at least according to the listtextures console command). All the AvatarInfos have a texture reference to the exact same texture (Transient.Avatar_2147483647). Using the new keyword passing in a reference to the original texture, new textures are created but they simply link back to the original. I haven't been able to find a method for deep copying the texture data so I can read and display multiple avatars at the same time.


    Here's the code block that creates the AvatarInfo for a player:

    Code:
    // if we haven't read the avatar for this player
    if( FindAvatarInfo( AllOnlineFriends[currentAvatarUpdateIndex].UniqueId ) == None)
    {
    	NewAvatarInfo = new class'GrAvatarInfo';
    	NewAvatarInfo.netID = AllOnlineFriends[currentAvatarUpdateIndex].UniqueId;
    	NewAvatarInfo.hasAvatar = false;
    	NewAvatarInfo.FriendOwner = AllOnlineFriends[currentAvatarUpdateIndex];
    	NewAvatarInfo.avatarID = GetAvatarID();
    	AllAvatarInfos[NewAvatarInfo.avatarID] = NewAvatarInfo;
    	OnlineSubSteam.ReadOnlineAvatar( AllOnlineFriends[currentAvatarUpdateIndex].UniqueId, 64, OnReadOnlineAvatarComplete );
    }

    Non-scaleform test HUD code that displays the textures:
    Code:
    foreach AllAvatarInfos(AvatarInfo)
    {
    	Canvas.SetPos(XPos, YPos);
    	YPos += 64.0f;
    	Canvas.SetDrawColor(255,255,255,255);
    	Canvas.DrawTile(AvatarInfo.avatarTexture, 64, 64, 0, 0, 64, 64);
    }
    Heres the delegate that receives the avatar texture from the Steamworks OnlineSubsystem:
    Code:
    simulated function OnReadOnlineAvatarComplete(const UniqueNetId PlayerNetId, Texture2D Avatar)
    {
    	local int index;
    
    	for(index = 0; index < AllAvatarInfos.Length; index++)
    	{
    		if(AllAvatarInfos[index].netID.Uid.A == PlayerNetId.Uid.A && AllAvatarInfos[index].netID.Uid.B == PlayerNetId.Uid.B)
    		{	
    			AllAvatarInfos[index].avatarTexture = new class'Texture2D' (Avatar);
    			AllAvatarInfos[index].avatarSource = "img://" $ AllAvatarInfos[index].avatarTexture.GetPackageName() $ "." $ AllAvatarInfos[index].avatarTexture.Name;
    			AllAvatarInfos[index].hasAvatar = true;
    			break;
    		}
    	}
    
    	currentAvatarUpdateIndex++;
    	bReadyForNextFriendUpdate = true;
    }
    Last edited by prestons; 04-30-2012 at 02:09 PM.

  6. #6
    MSgt. Shooter Person
    Join Date
    Jul 2011
    Posts
    56

    Default

    For debug purposes, you could create a HUD function that renders the argument Avatar from your delegate function rather than in a foreach statement.

    I would create a function that renders Avatar & one that renders avatarTexture in a column to the right.

    Nothing jumps out at me in your code.

  7. #7

    Default

    Through timed testing I know can read all of the avatars and render them independently, the issue appears whenever I call ReadOnlineAvatar it overwrites the previous texture with the latest. Since the texture copy I created is still referencing the original texture, when it is overwritten the copy is overwritten as well. I just need to find a way to copy the contents of the result texture from ReadOnlineAvatar into a separate texture buffer, so that when I read the next player avatar the copy remains unchanged. Looking through the Epic and other Unreal 3 documentation, I've been unable to find a method to accomplish this. Also it seems that SetExternalTexture seems to be getting an update in the next version of UDK, it may hold a potential solution.

  8. #8
    Redeemer
    Join Date
    Sep 2002
    Location
    Ireland
    Posts
    1,158

    Default

    This seems to be down to an odd bug in the engine; the textures are named 'Avatar_x' with x being a number (the players UID), but internally, the engine splits the 'Avatar' and '_x' parts because of how it handles names (so that means 'Avatar_0' is the same as 'Avatar_1', hence it only ever uses one texture).

    I have this fixed locally, but it requires C++ changes, so you'll need to wait for a future UDK to get the fixed code. I don't know if there is a way to copy textures in the meantime.

  9. #9

    Default

    Quote Originally Posted by Shambler View Post
    This seems to be down to an odd bug in the engine; the textures are named 'Avatar_x' with x being a number (the players UID), but internally, the engine splits the 'Avatar' and '_x' parts because of how it handles names (so that means 'Avatar_0' is the same as 'Avatar_1', hence it only ever uses one texture).

    I have this fixed locally, but it requires C++ changes, so you'll need to wait for a future UDK to get the fixed code. I don't know if there is a way to copy textures in the meantime.
    Alright, thanks for the info. It's nice to know why this was happening and that there is a chance that a fix will be implemented in a future UDK. I'll just work on other features until it's fixed!


 

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Copyright ©2009-2011 Epic Games, Inc. All Rights Reserved.
Digital Point modules: Sphinx-based search vBulletin skin by CompletevB.com.