Thread Tools Display Modes
02/04/23, 03:18 PM   #1
Anumaril
AddOn Author - Click to view addons
Join Date: Sep 2018
Posts: 14
Blur Effect in XML/LUA

Riding off the back of my previous help thread, the last thing I'm interested in doing in my addon is creating a blur effect around the edges of the screen, almost identical to this video where it's done in Skyrim: https://www.youtube.com/watch?v=GlTeTdFAaaU (skip to timestamp 0:23 when Boethiah speaks to the player)

I've poked around various documentations for XML and haven't found anything at all relating to blur effects, much less targeted blur effects that leave a clear circle in the centre of the screen. Does anyone know for certain if this is (not) possible?

Thanks again! You guys are great
  Reply With Quote
02/05/23, 05:58 AM   #2
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
The blur effect are scene fragments. You just need to add one of those to the scene.
For example FRAME_TARGET_BLUR_CENTERED_FRAGMENT
There are a few others. Check the eso ui source for "blur".
  Reply With Quote
02/05/23, 11:28 AM   #3
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,914
Wiki about fragment state change (OnShow, OnHide) and how to add a fragment to an exisitng scene (e.g. the HUD scene for your purpose):
https://wiki.esoui.com/Fragments_in_...t_state_change
  Reply With Quote
02/08/23, 10:07 AM   #4
Anumaril
AddOn Author - Click to view addons
Join Date: Sep 2018
Posts: 14
Hmm, I'll have to test this out some more. At the moment I'm getting an error where no other window is allowed to be opened, so I can't access the notification window to even see what's wrong

This is what I've got so far:

Code:
local blurFragment = ZO_HUDFadeSceneFragment:New("BlurUI")

HUD_SCENE:AddFragment(blurFragment)
HUD_UI_SCENE:AddFragment(blurFragment)

local function OnBlurFragmentStateChange(oldState, newState)
	if newState == SCENE_FRAGMENT_SHOWN then
 		if staminaPercent <= 0.9 then -- at 90% stamina, begin to blur the screen
 			BlurUI:SetAlpha((1.0 / 0.9) * (0.9 - staminaPercent))
 		else
 			BlurUI:SetAlpha(0.0)
 		end
 	elseif newState == SCENE_FRAGMENT_HIDDEN then
 		BlurUI:SetAlpha(0.0)
 	end
end
The basic idea being to create a TopLevelControl in XML, attach the blur fragment to it, then determine the control's alpha using the player's stamina (staminaPercent is defined elsewhere in the code).
  Reply With Quote
02/08/23, 10:16 AM   #5
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,914
If you use ZO_HUDFadeSceneFragment:New be sure to pass in all 3 paramaters espeically the last one with 0 else there might be errors on the UI because of the "fade" of the fading fragment.
I do not know what exactly was the problem here but I remember it could happen, if the value 0 is missing or does not equal 0.

Or you need to use another scenefragment type instead, like a normal ZO_SceneFragment


Lua Code:
  1. local staminaPercent = 0.8
  2.  
  3. local function OnBlurFragmentStateChange(oldState, newState)
  4.     if newState == SCENE_FRAGMENT_SHOWN then
  5.         if staminaPercent <= 0.9 then -- at 90% stamina, begin to blur the screen
  6.             BlurUI:SetAlpha((1.0 / 0.9) * (0.9 - staminaPercent))
  7.         else
  8.             BlurUI:SetAlpha(0)
  9.         end
  10.     elseif newState == SCENE_FRAGMENT_HIDDEN then
  11.         BlurUI:SetAlpha(0)
  12.     end
  13. end
  14.  
  15. local blurFragment = ZO_SceneFragment:New("BlurUI")  -- or ZO_HUDFadeSceneFragment:New("BlurUI", nil, 0)
  16.  
  17. HUD_SCENE:AddFragment(blurFragment)
  18. --HUD_UI_SCENE:AddFragment(blurFragment)
  19. blurFragment:RegisterCallback("StateChange", OnBlurFragmentStateChange)

HUD_SCENE should be enough btw to show your fragment or do you want to blur the normal inventory if opened (HUD_UI_SCENE) too?

And:
This StateChange only happens if the scene fragment is shown or hidden! So it does not update the BlurUI everytime as your stamina updates! You need to take care of that at the event where the stamina updates could be tracked with (event power update or similar).
The fragment will get to state hidden as you open another scene where the fragment was not added to, that's why only adding it to HUD_SCENE makes sense here, so if HUD_UI_SCENE is shown your not-there-added-fragment will be hidden automatically, making the SCENE_FRAGMENT_HIDDEN trigegr and BlurUI:SetAlpha(0) trigger.

Last edited by Baertram : 02/08/23 at 10:27 AM.
  Reply With Quote
02/11/23, 09:29 AM   #6
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
Originally Posted by Anumaril View Post
Hmm, I'll have to test this out some more. At the moment I'm getting an error where no other window is allowed to be opened, so I can't access the notification window to even see what's wrong
https://www.esoui.com/downloads/info...bugLogger.html may helps you recording the error and check it later.
  Reply With Quote
03/16/23, 12:47 PM   #7
Anumaril
AddOn Author - Click to view addons
Join Date: Sep 2018
Posts: 14
Thanks for the help guys! I'm still struggling quite a bit, but I've made some progress on making the scene/fragment work. Because I was having so much trouble getting the fragment to appear *at all*, I decided to scrap the fading thing for now until I can get the scene and fragment to work as intended.

The code I'm using right now to create the scene and fragment is:
Code:
ZO_CharacterFramingBlur = ZO_NormalizedPointFragment:Subclass()

function OnNormalizedPointChanged(normalizedX, normalizedY)
    SetFullscreenEffect(FULLSCREEN_EFFECT_CHARACTER_FRAMING_BLUR, normalizedX, normalizedY)
end

function ZO_CharacterFramingBlur:New(normalizedPointCallback)
    fragment = ZO_NormalizedPointFragment.New(self, normalizedPointCallback, OnNormalizedPointChanged)
    return fragment
end

function CalculateCenteredFramingTarget()
	screenWidth, screenHeight = GuiRoot:GetDimensions()
	return screenWidth / 2, .55 * screenHeight
end

IO_BLUR_FRAGMENT = ZO_CharacterFramingBlur:New(CalculateCenteredFramingTarget)

local IO_BLUR_SCENE = ZO_Scene:New("IO_BLUR_SCENE", SCENE_MANAGER)
IO_BLUR_SCENE:AddFragment(IO_BLUR_FRAGMENT)
And then I call on that code in the following "if" block, which I put under an EVENT_POWER_UPDATE block to track when stamina changes:

Code:
if staminaPercent <= 0.9 then
	SCENE_MANAGER:Show("IO_BLUR_SCENE")
else
        SCENE_MANAGER:Hide("IO_BLUR_SCENE")
end
With this code my blur effect is appearing in-game, but not very consistently. Instead of simply appearing when under 90% stamina, it seemingly appears when around 10-25% stamina, and then never goes away at all unless I open a menu to change the scene.

But the scene itself is probably the bigger problem for me, because I can't find information on how to change the settings of a scene. When my custom scene appears I can't use abilities anymore, open menus, or turn the camera. I can only use the movement keys. I *think* this is because I need to set the scene's settings to be more like the HUD_SCENE, which obviously allows all of that stuff because that's the base scene that appears when you don't have a window open.

Does anyone happen to know how to change a custom scene's settings? Ideally I'd like for my custom scene to be identical in functionality as the HUD_SCENE, except for it not to disappear when opening other windows (or at least for those to layer on top if that's possible).

I'm only using a custom scene in the first place because I want to limit incompatibility and/or error messages, and also to avoid being locked into using HUD_SCENE's settings, which have it set to disappear while opening menus, etc.
  Reply With Quote
03/16/23, 02:11 PM   #8
votan
 
votan's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 577
Originally Posted by Anumaril View Post
Thanks for the help guys! I'm still struggling quite a bit, but I've made some progress on making the scene/fragment work. Because I was having so much trouble getting the fragment to appear *at all*, I decided to scrap the fading thing for now until I can get the scene and fragment to work as intended.

The code I'm using right now to create the scene and fragment is:
Code:
ZO_CharacterFramingBlur = ZO_NormalizedPointFragment:Subclass()

function OnNormalizedPointChanged(normalizedX, normalizedY)
    SetFullscreenEffect(FULLSCREEN_EFFECT_CHARACTER_FRAMING_BLUR, normalizedX, normalizedY)
end

function ZO_CharacterFramingBlur:New(normalizedPointCallback)
    fragment = ZO_NormalizedPointFragment.New(self, normalizedPointCallback, OnNormalizedPointChanged)
    return fragment
end

function CalculateCenteredFramingTarget()
	screenWidth, screenHeight = GuiRoot:GetDimensions()
	return screenWidth / 2, .55 * screenHeight
end

IO_BLUR_FRAGMENT = ZO_CharacterFramingBlur:New(CalculateCenteredFramingTarget)

local IO_BLUR_SCENE = ZO_Scene:New("IO_BLUR_SCENE", SCENE_MANAGER)
IO_BLUR_SCENE:AddFragment(IO_BLUR_FRAGMENT)
And then I call on that code in the following "if" block, which I put under an EVENT_POWER_UPDATE block to track when stamina changes:

Code:
if staminaPercent <= 0.9 then
	SCENE_MANAGER:Show("IO_BLUR_SCENE")
else
        SCENE_MANAGER:Hide("IO_BLUR_SCENE")
end
With this code my blur effect is appearing in-game, but not very consistently. Instead of simply appearing when under 90% stamina, it seemingly appears when around 10-25% stamina, and then never goes away at all unless I open a menu to change the scene.

But the scene itself is probably the bigger problem for me, because I can't find information on how to change the settings of a scene. When my custom scene appears I can't use abilities anymore, open menus, or turn the camera. I can only use the movement keys. I *think* this is because I need to set the scene's settings to be more like the HUD_SCENE, which obviously allows all of that stuff because that's the base scene that appears when you don't have a window open.

Does anyone happen to know how to change a custom scene's settings? Ideally I'd like for my custom scene to be identical in functionality as the HUD_SCENE, except for it not to disappear when opening other windows (or at least for those to layer on top if that's possible).

I'm only using a custom scene in the first place because I want to limit incompatibility and/or error messages, and also to avoid being locked into using HUD_SCENE's settings, which have it set to disappear while opening menus, etc.
You have to add /remove the fragment to/from the base-scene (HUD_SCENE). If you open your own scene, the game will return to base-scene as soon as you move.
  Reply With Quote
03/16/23, 03:16 PM   #9
Baertram
Super Moderator
 
Baertram's Avatar
WoWInterface Super Mod
AddOn Author - Click to view addons
Join Date: Mar 2014
Posts: 4,914
It should be enough to create your IO_BLUR_FRAGMENT fragment and add it to HUD_SCENE once
Code:
HUD_SCENE:AddFragment(IO_BLUR_FRAGMENT)
Attention: This will make it show as soon as you close a menu, or move, as the HUD_SCENE will be shown then.
To prevent this you'd have to either remove the fragment from the HUD_SCENE if it should not show, or add some condition at the
OnStateChange callback (see one of my last posts about it): As the FRAGMENT_STATE_SHOWING occurs -> check the actual stamina and if it's above the threshold hide the fragment again!
Shoudl be possible via IO_BLUR_FRAGMENT:Hide()

For your stamina OnPowerUpdate checks:
Scene fragments should use the base class ZO_HideableSceneFragmentMixin, and that class provides a function
:SetHiddenForReason()
Code:
ZO_HideableSceneFragmentMixin:SetHiddenForReason(reason, hidden, customShowDuration, customHideDuration)
So you could use that function to show/hide the fragment based on the stamina percentage:
Lua Code:
  1. IO_BLUR_FRAGMENT:SetHiddenForReason("StaminaThresholdChecks_FreeTextAfaik", (staminaPercent > thresholdValue and true) or false, 0, 0)



Edit:
Example code
Lua Code:
  1. local function hideTLCIfNotStaminaThresholdMet()
  2.  return currentPlayerStamina > thresHoldStamina --return true = hide, if stamina is high enough
  3. end
  4.  
  5. local fragment = ZO_HUDFadeSceneFragment:New(TestTLC, nil, 0)
  6.     local function OnTestTLCFragmentStateChange(oldState, newState)
  7.         if newState == SCENE_FRAGMENT_SHOWING then
  8. d("[TestTLC]Fragment showing")
  9.             fragment:SetHiddenForReason("ShouldntShow", hideTLCIfNotStaminaThresholdMet(), 0, 0)
  10.         --elseif newState == SCENE_FRAGMENT_HIDDEN then
  11.         end
  12.     end
  13.     fragment:RegisterCallback("StateChange", OnTestTLCFragmentStateChange)
  14.     --Hide in menus/Show at fighting UI
  15.     HUD_SCENE:AddFragment(fragment)

Last edited by Baertram : 03/16/23 at 06:35 PM.
  Reply With Quote

ESOUI » Developer Discussions » Lua/XML Help » Blur Effect in XML/LUA

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