WoWInterface

WoWInterface (https://www.wowinterface.com/forums/index.php)
-   General Authoring Discussion (https://www.wowinterface.com/forums/forumdisplay.php?f=20)
-   -   Race Icon Portrait (https://www.wowinterface.com/forums/showthread.php?t=58896)

Nagí 08-20-21 12:02 PM

Race Icon Portrait
 
1 Attachment(s)
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?

SDPhantom 08-20-21 08:08 PM

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);

Ketho 08-20-21 08:47 PM

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)



Nagí 08-21-21 02:08 PM

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 =

Ketho 08-21-21 09:45 PM

Quote:

Originally Posted by Nagí (Post 339727)
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)

Nagí 08-24-21 08:08 PM

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)
Quote:

Originally Posted by Ketho (Post 339730)
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.

Nagí 08-24-21 08:41 PM

1 Attachment(s)
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?

Nagí 01-17-22 07:49 PM

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.

Ketho 01-20-22 10:33 AM

Glad to see you solved your framerate drop issue


All times are GMT -6. The time now is 06:05 PM.

vBulletin © 2024, Jelsoft Enterprises Ltd
© 2004 - 2022 MMOUI