View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0001830 | NoesisGUI | C++ SDK | public | 2020-11-05 18:28 | 2020-11-11 19:37 |
| Reporter | steveh | Assigned To | sfernandez | ||
| Priority | normal | Severity | feature | ||
| Status | resolved | Resolution | no change required | ||
| Product Version | 3.0.6 | ||||
| Target Version | 3.0.8 | Fixed in Version | 3.0.8 | ||
| Summary | 0001830: Feature Request: Generic notification support within storyboards | ||||
| Description | Hi guys, this is following on from this thread and our discussion: https://www.noesisengine.com/forums/viewtopic.php?f=3&t=2066&p=11532#p11532 So the suggested workaround regarding a float instead of a boolean works for triggering the notification multiple times within a looping storyboard, but it doesn't work if we attempt to trigger a notify a single time multiple times, e.g: <Storyboard> It would be nice if there was a supported extension to add triggers within a storyboard. We would use this features in a couple of places:
<TextBlock x:Name="OldLevel" Text="{Binding Level, Converter={StaticResource SubtractionConverter}, ConverterParameter=1}" Visibility="Visible" /> Then half-way through the storyboard, we change the visibility of the elements so the new value comes through: <Storyboard> It would be nice to be able to trigger a generic event at time 0.5 seconds in this example where I could update the binding for Level so we only had to have 1 textblock. Hopefully this makes sense and you can see why we might want the ability to trigger generic notifications. | ||||
| Platform | Any | ||||
|
Regarding the limitation you mentioned about triggering the notification multiple times within a looping storyboard, there is way to make it work with only a single key frame. <Storyboard x:Key="anim" Duration="0:0:1" RepeatBehavior="3x"> In that example, if the default value of CustomTrigger.Trigger property is -1, it will call the property changed callback for 0.5, -1, 0.5, -1, 0.5, -1. And you can use it for changing the text in the middle of an animation too. For example, you can do: <Storyboard x:Key="anim" Duration="0:0:1"> Does that make sense? |
|
|
Hi Sergio, Yes that makes sense. I've just given this a test and it works. The only downside is that there is no way to set the fill behaviour via the GUI in Blend, and our artists / designers tend to primarily use the GUI to edit the storyboards. I've spent a little while Googling around and the only way to change the fill behaviour from what I can see is by editing the XAML. I may be able to set the fillbehavior when we use our custom export tool to convert the xaml source files into our image data, so I can probably programmatically set this property on all animations which affect the CustomTrigger.Trigger property. Cheers, -Steven |
|
|
Just to update you on this. So we've almost got it to a place where the audio designers are happy with this. So now I've got 2 DependencyProperties on our trigger: TriggerProperty which is a bool The reason we have kept both is that the audio designers like having a checkbox on the GUI instead of having to type in a number. I suggested that I could create an enum so they got a drop down selection, but they didn't like that idea. So we decided to create 2 properties and make the repeatable trigger in the "Advanced" section of the editor so it's hidden by default, but they still have the ability to fire the same trigger multiple times in the same storyboard. With regards to the FillBehaviour, I added this functionality into our export pipeline and it works great. We have a tool where we feed in the .xaml files and it writes out a .xaml file in a slightly different format. This allows us to tag certain parts of the UI and they wont appear in the final build, e.g. we have meta data tags like the following: <Grid x:Name="foo_console" Sumo.MetaData="Platform=xbox,ps4"> The first grid will be completely removed from our PC package data, and the second grid will be completely removed from the PS4 and Xbox packages. We use this for a variety of things, but this is just 1 example. If we find a CustomTrigger.Trigger or CustomTrigger.TriggerRepeating as the target property of a storyboard, we automatically add a FillBehaviour Stop attribute in. This doesn't appear in Blend, but it does appear in our package data and it works as expect. Right now we feel like we have enough workarounds to put this bug to bed. It'd be nice to have a fully supported feature which integrates nicely with Blend, but for now what we have is reasonable and it seems to work in all cases. Cheers, -Steven |
|
|
Hi Steve, I added a suggestion to Visual Studio feedback to remark FillBehavior cannot be edited using the GUI of Blend: Do you think we can close this ticket? |
|
|
Hi Sergio, yes, I think our pipeline is much better now and it seems to work great. I'll await Microsoft's response but I'm not expecting anything any time soon, so for now our programmatic solution to automatically set the fill behaviour property works fine :) Cheers! |
|
|
Hi Sergio, Sorry, just reopening this ticket. We've found 1 case this doesn't work: https://www.noesisengine.com/xamltoy/573cc06a07416b5d38f99392d6122cb8 Every time the value flips between -1 and 1 it'll fire an event internally, and this works great. But if the keyframe is at time 0, i.e:
Then this doesn't seem to have a frame to reset the value, the timeline instantly loops round without stopping and thus resetting the value back to -1. This means that we can't fire audio events on a looping animation from the very first frame. Is there any way to get WPF to forcibly clear the value as soon as it loops so we always get the dependency changed events through? Cheers, -Steven |
|
|
Hi, no problem at all. Before going with the issue just want to remark you can specify the duration of the animation without adding another KeyFrame: <StringAnimationUsingKeyFrames FillBehavior="Stop" Storyboard.TargetName="Value" Storyboard.TargetProperty="Text" RepeatBehavior="Forever" Duration="0:0:1"> Yes, it seems KeyFrames placed at time 0 are used when looping without passing through the default value, and I verified that WPF is also doing the same. Advancing the time of the initial KeyFrame a bit (to 0:0:0.01 for example) allows the animation system to set the default value on each loop, but it seems a bit hacky. <StringAnimationUsingKeyFrames FillBehavior="Stop" Storyboard.TargetName="Value" Storyboard.TargetProperty="Text" RepeatBehavior="Forever" Duration="0:0:1"> I found another way of reseting the value for "looping" animations: https://stackoverflow.com/questions/2667836/how-to-trigger-a-event-handler-when-wpf-animation-repeated The idea is to play the animation just one time instead of Forever, and then listen to the Completed event to fire the animation again: <Storyboard x:Key="anim"> This way the property is always set to the default value after each iteration. Any thoughts on this? |
|
|
Hey, so the duration sounds ideal, unfortunately this trigger object is intended to be used by audio designers who work specifically with the WYSWIG Blend GUI, and I don't think the GUI exposes any of these properties via the interface. This might be one of those cases though where if they need support for it I can write the XAML for them. With regards to the interaction trigger, that could work, but I feel it might complicate matters, right now animation is being stopped via some external C++ code (this is a countdown animation which loops every second and plays a 'blip' until we stop the animation). We could move all this logic to the XAML but that would require exposing extra properties and additional conditionals to the trigger to ensure that it doesn't continuously loop forever, it only loops whilst we're in the "game ending" phase: <i:Interaction.Triggers> This just seems quite a bit more complex than the C++ code which just does something like this: void OnPhaseChanged(EPhase ePhase) And it also doesn't get around the issue of having a nice simple interface for audio designers to go in and just drag and drop these triggers in, this still requires code support to expose this data and setup all the bindings. I'll keep these solutions in mind for the future. Right now we've gone with the solution of just triggering the audio at 0.01 seconds like you mentioned. This is a solution that audio designers can do without editing the XAML and it also doesn't require additional code to expose extra properties to data bind to. |
|
|
I think you can still Stop the storyboard from code only because that will prevent the Completed event to be triggered so it won't loop again. |
|
|
Ah, I wasn't aware of that, I thought Stopping via code would still trigger the completed trigger, I don't know why I thought that. If that's the case then I think the looping in XAML could be a solution for us. Thank you for your help and suggestion Sergio! I'm sorry thinks aren't as simple as they usually are as we have artists and designers using Blend and they're used to flashy editors like Unreal and the Adobe suite :) I think we can re-close this now, I think I have enough to go on and we have workarounds for the looping issue. Cheers! |
|
|
It is good to have these conversations because one of our goals is to make life easier for designers and avoid as much as possible the intervention of programmers for designing the UI. |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2020-11-05 18:28 | steveh | New Issue | |
| 2020-11-05 18:29 | steveh | Description Updated | |
| 2020-11-06 10:43 | sfernandez | Assigned To | => sfernandez |
| 2020-11-06 10:43 | sfernandez | Status | new => assigned |
| 2020-11-06 10:58 | sfernandez | Status | assigned => feedback |
| 2020-11-06 10:58 | sfernandez | Note Added: 0006714 | |
| 2020-11-06 17:16 | steveh | Note Added: 0006715 | |
| 2020-11-06 17:16 | steveh | Status | feedback => assigned |
| 2020-11-06 17:16 | steveh | Note Edited: 0006715 | |
| 2020-11-06 22:29 | steveh | Note Added: 0006716 | |
| 2020-11-10 18:50 | sfernandez | Status | assigned => feedback |
| 2020-11-10 18:50 | sfernandez | Note Added: 0006718 | |
| 2020-11-10 18:59 | steveh | Note Added: 0006719 | |
| 2020-11-10 18:59 | steveh | Status | feedback => assigned |
| 2020-11-10 19:39 | sfernandez | Status | assigned => resolved |
| 2020-11-10 19:39 | sfernandez | Resolution | open => no change required |
| 2020-11-10 19:39 | sfernandez | Fixed in Version | => 3.0.8 |
| 2020-11-10 19:39 | sfernandez | Target Version | => 3.0.8 |
| 2020-11-11 13:24 | steveh | Status | resolved => feedback |
| 2020-11-11 13:24 | steveh | Resolution | no change required => reopened |
| 2020-11-11 13:24 | steveh | Note Added: 0006724 | |
| 2020-11-11 17:44 | sfernandez | Note Added: 0006725 | |
| 2020-11-11 17:46 | sfernandez | Note Edited: 0006725 | |
| 2020-11-11 18:30 | steveh | Note Added: 0006726 | |
| 2020-11-11 18:30 | steveh | Status | feedback => assigned |
| 2020-11-11 18:31 | steveh | Note Edited: 0006726 | |
| 2020-11-11 18:31 | steveh | Note Edited: 0006726 | |
| 2020-11-11 18:39 | sfernandez | Status | assigned => feedback |
| 2020-11-11 18:39 | sfernandez | Note Added: 0006727 | |
| 2020-11-11 18:49 | steveh | Note Added: 0006728 | |
| 2020-11-11 18:49 | steveh | Status | feedback => assigned |
| 2020-11-11 19:37 | sfernandez | Status | assigned => resolved |
| 2020-11-11 19:37 | sfernandez | Resolution | reopened => no change required |
| 2020-11-11 19:37 | sfernandez | Note Added: 0006729 |