Thread Tools Display Modes
08-20-21, 12:02 PM   #1
Nagí
A Murloc Raider
 
Nagí's Avatar
Join Date: Oct 2020
Posts: 6
Race Icon Portrait

Hi, I'm trying to have these race icons to the portrait of my unit frames (player, target, targettarget, arena1, etc...) in the same spirit as the few addons who allow you to have the class icons to portraits. All these addons use a similar structure like this one:
Lua Code:
  1. hooksecurefunc("UnitFramePortrait_Update",function(self)
  2.         if self.portrait then
  3.                 if UnitIsPlayer(self.unit) then                        
  4.                         local t = CLASS_ICON_TCOORDS[select(2, UnitClass(self.unit))]
  5.                         if t then
  6.                                 self.portrait:SetTexture("Interface\\TargetingFrame\\UI-Classes-Circles")
  7.                                 self.portrait:SetTexCoord(unpack(t))
  8.                         end
  9.                 else
  10.                         self.portrait:SetTexCoord(0,1,0,1)
  11.                 end
  12.         end
  13. end)

I attempted some modifications by my own, of course it resulted nothing...
I presume that I should replace "CLASS_ICON_TCOORDS" by "RACE_ICON_TCOORDS", add "UnitSex" and replace "UnitClass" by "UnitRace".

Maybe it needs more changes or another structure. Honnestly I don't know, I'm lost with many questions like: UnitGUID wouldn't be better? / What about C_PlayerInfo.GetRace? Etc... I can't even figure if what I ask for is possible or not.

My knowledge are very limited in coding, I think I'm able to read and nearly understand line after line
but not to write it all by myself without some guidance. Could someone help me with this?
Attached Files
File Type: blp charactercreateicons.blp (2.00 MB, 197 views)
  Reply With Quote
08-20-21, 08:08 PM   #2
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,313
The best way I can find currently is use GetRaceAtlas() that is provided for the character creation screen. The atlas name generated can be applied using texture:SetAtlas().

Here's an example:
Lua Code:
  1. hooksecurefunc("UnitFramePortrait_Update",function(self)
  2.     if self.portrait then
  3.         if UnitIsPlayer(self.unit) then
  4.             self.portrait:SetAtlas(GetRaceAtlas(
  5.                 select(2,UnitRace(self.unit)):lower()
  6.                 ,UnitSex(self.unit)==Enum.Unitsex.Male and "male" or "female"
  7.                 ,true
  8.             ));
  9.         else
  10.             self.portrait:SetTexCoord(0,1,0,1);
  11.         end
  12.     end
  13. end);
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
08-20-21, 08:47 PM   #3
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
To expand on SDPhantom's post, you can additionally mask the texture

Lua Code:
  1. local genders = {nil, "male", "female"}
  2.  
  3. hooksecurefunc("UnitFramePortrait_Update",function(self)
  4.     if self.portrait and UnitIsPlayer(self.unit) then
  5.         local _, race = UnitRace(self.unit)
  6.         local sexID = UnitSex(self.unit)
  7.         local atlas = GetRaceAtlas(race:lower(), genders[sexID], true)
  8.         self.portrait:SetMask("Interface\\CharacterFrame\\TempPortraitAlphaMask")
  9.         self.portrait:SetAtlas(atlas)
  10.     end
  11. end)



Last edited by Ketho : 08-20-21 at 08:56 PM.
  Reply With Quote
08-21-21, 02:08 PM   #4
Nagí
A Murloc Raider
 
Nagí's Avatar
Join Date: Oct 2020
Posts: 6
Amazing! Thanks a lot to both of you for your time and your consideration. I searched a bit before dare to ask for help and I have already seen SetAtlas() while looking in the folders of the Interface with Notepad++. But I have never thought about using it.

I have tried both scripts. First the one from Ketho's post causes me massive FPS drops. When entering in combat with a training dummy everything is normal. But when in combat with a NPC who is targeting me, my FPS fall and are locked at ~20.

Then the one from SDPhantom's post works great. But after that I add the line with SetMask() from Ketho's code like this:
Lua Code:
  1. hooksecurefunc("UnitFramePortrait_Update",function(self)
  2.     if self.portrait then
  3.         if UnitIsPlayer(self.unit) then
  4.             self.portrait:SetMask("Interface\\CharacterFrame\\TempPortraitAlphaMask");
  5.             self.portrait:SetAtlas(GetRaceAtlas(
  6.                 select(2,UnitRace(self.unit)):lower()
  7.                 ,UnitSex(self.unit)==Enum.Unitsex.Male and "male" or "female"
  8.                 ,true
  9.             ));
  10.         else
  11.             self.portrait:SetTexCoord(0,1,0,1);
  12.         end
  13.     end
  14. end);

...when in combat against NPC same issue with FPS drops.

I thought this was a problem of compatibility with one of my AddOns.
At start I have downloaded AddonUsage to know the source of the issue. (*cough* I will make another post about DSM)
I check with AddOns and without AddOns

So, I presume that the problem is the use of SetMask() or the update during combat itself.

I'm quite curious to know what is the difference between SetMask() and SetPortraitToTexture() here? And if SetPortraitToTexture() would cause the same issue? (I attempted SetPortraitToTexture() but I didn't succeed to make it works, I haven't put the good informations certainly...)

Also I want to flip horizontally the portrait for the unit frame of my target and focus.
I have tried to do by myself, but I'm not too sure where to insert the elements.
I guess that I should use SetTexCoord(1, 0, 0, 1) for flip the icon, and probably assign the specific units with a new local unit =

Last edited by Nagí : 08-21-21 at 07:05 PM. Reason: After usage...
  Reply With Quote
08-21-21, 09:45 PM   #5
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Originally Posted by Nagí View Post
I have tried both scripts. First the one from Ketho's post causes me massive FPS drops. When entering in combat with a training dummy everything is normal. But when in combat with a NPC who is targeting me, my FPS fall and are locked at ~20.

Oof, I should have tested that more. I'm not that familiar with textures as you can see
This doesn't seem to give a massive FPS drop, but still gives you a 5-10 FPS hit. which is not good
Lua Code:
  1. local genders = {nil, "male", "female"}
  2.  
  3. hooksecurefunc("UnitFramePortrait_Update",function(self)
  4.     if self.portrait and UnitIsPlayer(self.unit) then
  5.         local _, race = UnitRace(self.unit)
  6.         local sexID = UnitSex(self.unit)
  7.         local atlas = GetRaceAtlas(race:lower(), genders[sexID], true)
  8.         self.portrait:SetAtlas(atlas)
  9.         if not self.portrait.hasMask then
  10.             self.portrait:SetMask("Interface\\CharacterFrame\\TempPortraitAlphaMask")
  11.             self.portrait.hasMask = true
  12.         end
  13.     end
  14. end)

Last edited by Ketho : 08-21-21 at 09:54 PM.
  Reply With Quote
08-24-21, 08:08 PM   #6
Nagí
A Murloc Raider
 
Nagí's Avatar
Join Date: Oct 2020
Posts: 6
Thanks for you reply Ketho.
I have tried what you send and it was almost as you said. (more a hit of 20-25 FPS in my case)
Originally Posted by Ketho View Post
This doesn't seem to give a massive FPS drop, but still gives you a 5-10 FPS hit.
The only source of the problem is the command SetMask() when in combat (mainly for the frame "TargetFrameToT")
I found this post when getting some information about SetMask() but unfortunately it didn't worked.

I attempted by myself some other stuff like applying mask to each specific frames at specific events
Lua Code:
  1. if event == "PLAYER_TARGET_CHANGED" then
  2. TargetFramePortrait:SetMask(("Interface\\CharacterFrame\\TempPortraitAlphaMask"))
etc... but to no avail. SetMask() still cause trouble with FPS.

Last edited by Nagí : 08-24-21 at 08:11 PM.
  Reply With Quote
08-24-21, 08:41 PM   #7
Nagí
A Murloc Raider
 
Nagí's Avatar
Join Date: Oct 2020
Posts: 6
So I keep search and I found something very interesting and it gives me an idea.
It's an AddOn called EnhancedClassIconPortraits, and this is his core:
Lua Code:
  1. local TEXTURE_NAME = "Interface\\AddOns\\EnhancedClassIconPortraits\\Textures\\%s.tga"
  2.  
  3. hooksecurefunc("UnitFramePortrait_Update", function(self)
  4.     if self.portrait then
  5.         if UnitIsPlayer(self.unit) then
  6.             local _, class = UnitClass(self.unit)
  7.             if class then
  8.                 self.portrait:SetTexture(TEXTURE_NAME:format(class))
  9.             else
  10.                 --[===[@alpha@
  11.                 print(("EnhancedClassIconPortraits Error: UnitClass returned nil for unit %q"):format(self.unit))
  12.                 --@end-alpha@]===]
  13.             end
  14.         end
  15.     end
  16. end)

If I take a similar way as above, I can avoid to call SetMask() and have the same result without performance issue. So I have extracted the textures and applied directly a mask on it. Now I have a folder with 46 icons, here is an example. Maybe the name of the textures in the folder could need to be renamed if I want to call them.

That's probably less efficient than SetAtlas(). What do you think about it? Is that possible?
Attached Files
File Type: tga bloodelf-female.tga (64.5 KB, 192 views)

Last edited by Nagí : 08-24-21 at 08:43 PM.
  Reply With Quote
01-17-22, 07:49 PM   #8
Nagí
A Murloc Raider
 
Nagí's Avatar
Join Date: Oct 2020
Posts: 6
Hey! I'm updating this post to expose my advancement on the subject.

The previous answers have helped and learned me a lot. So I would therefore like to thank them once again.

At first, I obstinately continued in the way that has been suggested. I tried to fix the issue encountered with SetMask() while in combat. But I didn't found anything pertinent in the Blizzard interface.

So I decided to try as I thought with a folder containing my textures in order to avoid SetMask().
And I achieved to something working perfectly as expected. It's like this:
Lua Code:
  1. hooksecurefunc("UnitFramePortrait_Update", function(self)
  2.     if self.portrait then
  3.       if UnitIsPlayer(self.unit) then
  4.         local race = ((select(2,UnitRace(self.unit))):lower());
  5.         local gender = (UnitSex(self.unit) == 3);
  6.         if gender then
  7.           self.portrait:SetTexture(string.format("Interface\\AddOns\\RaceIconPortrait\\Textures\\%s-%s.tga", race, "female"))
  8.         else
  9.           self.portrait:SetTexture(string.format("Interface\\AddOns\\RaceIconPortrait\\Textures\\%s-%s.tga", race, "male"))          
  10.         end
  11.       end
  12.       if UnitIsPlayer("target") then
  13.         TargetFramePortrait:SetTexCoord(1,0,0,1)
  14.       else
  15.         TargetFramePortrait:SetTexCoord(0,1,0,1)
  16.       end
  17.       if UnitIsPlayer("focus") then
  18.         FocusFramePortrait:SetTexCoord(1,0,0,1)
  19.       else
  20.         FocusFramePortrait:SetTexCoord(0,1,0,1)
  21.       end
  22.     end
  23. end)
I'm conscious that it could be better, especially with the UnitSex() and the second %s (I have particularly struggled with this, for finally end up to this). Also I have add the functionality to reverse the portrait for the target and focus frame. If you have any suggestion I'll be glad to read them.
  Reply With Quote
01-20-22, 10:33 AM   #9
Ketho
A Pyroguard Emberseer
 
Ketho's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2010
Posts: 1,026
Glad to see you solved your framerate drop issue
  Reply With Quote

WoWInterface » Developer Discussions » General Authoring Discussion » Race Icon Portrait

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off