Thread Tools Display Modes
05-11-09, 10:37 PM   #1
Dgrimes
A Black Drake
 
Dgrimes's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 89
Animations on unit frame elements

Is it possible to add animations to textures of a unit frame with a scripted shader?

Edit: Never mind figured it out.

Edit2: Seems it wont autoloop... is that normal?

Edit3: It seems like even with my lockout code the animation is always re-starting itself when the frame updates.

The code I am using is if not anim:IsPlaying() then anim:Play() else return; end
__________________
What was is, what will be was.

Last edited by Dgrimes : 05-11-09 at 11:42 PM.
  Reply With Quote
05-12-09, 07:11 PM   #2
Dgrimes
A Black Drake
 
Dgrimes's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 89
Ok so I got my animation working. The only problem I am running into is having it start automatically. I believe this is an RDX issue not the animation. Here is the code I am using for it (btw you can use this in game and it works)

Code:
RDX.RegisterFeature({
    name = "animation_rotation"; version = 1;
    title = i18n("Animation: Rotation"); category = i18n("Animations");
    multiple = true;
    IsPossible = function(state)
        if not state:Slot("UnitFrame") then return nil; end
        if not state:Slot("Base") then return nil; end
        return true;
    end;
    ExposeFeature = function(desc, state, errs)
        if not desc then VFL.AddError(errs, i18n("No Descriptor.")); return nil; end
        if not (desc.owner) or (not state:Slot("Tex_" .. desc.owner)) then
            VFL.AddError(errs, i18n("Invalid texture")); return nil;
        end        
        return true;
    end;
    ApplyFeature = function(desc, state)
        local fname = "frame.Tex_" .. desc.owner;
        local createCode =
fname .. [[_animation = ]] .. fname .. [[:CreateAnimationGroup(); 
]] .. fname .. [[_animation:SetLooping("REPEAT");
]] .. fname .. [[_rotation = ]] .. fname .. [[_animation:CreateAnimation("ROTATION"); 
]] .. fname .. [[_rotation:SetDegrees(]] .. desc.degrees .. [[); 
]] .. fname .. [[_rotation:SetDuration(]] .. desc.duration .. [[);
]] .. fname .. [[_rotation:SetOrigin(']] .. desc.origin .. [[', 0, 0); 
]] .. fname .. [[_animation:Play(); 
]];
        local paintCode = [[
if not ]] .. fname .. [[_animation:IsPlaying() then ]] .. fname .. [[_animation:Play(); else return; end
]];
        state:Attach(state:Slot("EmitPaint"), true, function(code) code:AppendCode(paintCode); end);
        state:Attach(state:Slot("EmitCreate"), true, function(code) code:AppendCode(createCode); end);
    end;
    UIFromDescriptor = function(desc, parent, state)
        local ui = VFLUI.CompoundFrame:new(parent);
        
        local owner = RDXUI.MakeSlotSelectorDropdown(ui, i18n("Target texture"), state, "Tex_", nil);
        if desc and desc.owner then owner:SetSelection(desc.owner); end

        local duration = VFLUI.LabeledEdit:new(ui, 50);
        duration:SetText(i18n("Duration"));
        duration:Show();
        if desc and desc.duration then duration.editBox:SetText(desc.duration); end
        ui:InsertFrame(duration);
        
        local degrees = VFLUI.LabeledEdit:new(ui, 50);
        degrees:SetText(i18n("Degrees"));
        degrees:Show();
        if desc and desc.degrees then degrees.editBox:SetText(desc.degrees); end
        ui:InsertFrame(degrees);
        
        --Origin
        local er = RDXUI.EmbedRight(ui, i18n("Origin"));
        local origin = VFLUI.Dropdown:new(er, RDXUI.AnchorPointSelectionFunc);
        origin:SetWidth(100); origin:Show(); origin:SetSelection("CENTER");
        er:EmbedChild(origin); er:Show();
        ui:InsertFrame(er);
        
        --local edy = VFLUI.LabeledEdit:new(ctr, 75); edy:SetText(i18n("Offset X/Y:")); edy:Show();
        --local edx = VFLUI.Edit:new(edy); edx:Show();
        --edx:SetHeight(24); edx:SetWidth(75); edx:SetPoint("RIGHT", edy.editBox, "LEFT");
        --edy.Destroy = VFL.hook(function() edx:Destroy(); end, edy.Destroy);
        --ui:InsertFrame(edy);
        
        function ui:GetDescriptor()
            return {
                feature = "animation_rotation"; version = 1;
                name = "Rotation";
                owner = owner:GetSelection();
                duration = duration.editBox:GetText();
                degrees = degrees.editBox:GetText();
                origin = origin:GetSelection();
            };
        end
        
        return ui;
    end;
    CreateDescriptor = function()
        return {
            feature = "animation_rotation", version = 1,
            name = "Rotation", owner = "Base", duration = 10, degrees = 360,
            origin = "CENTER",
        };
    end;
});
Like I said above, the animation won't automatically start for some reason. Might be my own ignorance? Who knows. If you activate a frame re-paint (ie health/power change) it will start it and then continue going till the window is closed. This code is beta still. Not all the options are implemented and there is no destroy code yet to stop the animation when the window is closed. Use at own risk.

Edit: This animation WILL NOT MOVE IF YOU UNLOCK THE DESKTOP. You will need to re-open the window under a situation where you are not prompting a frame update.

These include a change in health/power, buff gained, buff loss, (I do not believe buff duration will prompt a frame update), roster change(not tested but it might).

Sorry but I am going to talk to Sigg about adding a general AnimationGroup to each unitframe either in the form of a feature or pre-built into the unitframe.
__________________
What was is, what will be was.

Last edited by Dgrimes : 05-12-09 at 08:10 PM.
  Reply With Quote
05-12-09, 08:53 PM   #3
Dgrimes
A Black Drake
 
Dgrimes's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 89
Here is a beta scaling, that bounces back to its original size.

Code:
RDX.RegisterFeature({
    name = "animation_scale"; version = 1;
    title = i18n("Animation: Scale"); category = i18n("Animations");
    multiple = true;
    IsPossible = function(state)
        if not state:Slot("UnitFrame") then return nil; end
        if not state:Slot("Base") then return nil; end
        return true;
    end;
    ExposeFeature = function(desc, state, errs)
        if not desc then VFL.AddError(errs, i18n("No Descriptor.")); return nil; end
        if not (desc.owner) or (not state:Slot("Tex_" .. desc.owner)) then
            VFL.AddError(errs, i18n("Invalid texture")); return nil;
        end        
        return true;
    end;
    ApplyFeature = function(desc, state)
        local fname = "frame.Tex_" .. desc.owner;
        local createCode =
fname .. [[_animation = ]] .. fname .. [[:CreateAnimationGroup(); 
]] .. fname .. [[_animation:SetLooping("BOUNCE");
]] .. fname .. [[_rotation = ]] .. fname .. [[_animation:CreateAnimation("SCALE"); 
]] .. fname .. [[_rotation:SetScale(]] .. desc.xscale .. [[, ]] .. desc.yscale .. [[); 
]] .. fname .. [[_rotation:SetDuration(]] .. desc.duration .. [[);
]] .. fname .. [[_rotation:SetOrigin(']] .. desc.origin .. [[', 0, 0); 
]] .. fname .. [[_animation:Play();
]];
        local paintCode = [[
if not ]] .. fname .. [[_animation:IsPlaying() then ]] .. fname .. [[_animation:Play(); else return; end
]];
        state:Attach(state:Slot("EmitPaint"), true, function(code) code:AppendCode(paintCode); end);
        state:Attach(state:Slot("EmitCreate"), true, function(code) code:AppendCode(createCode); end);
    end;
    UIFromDescriptor = function(desc, parent, state)
        local ui = VFLUI.CompoundFrame:new(parent);
        
        local owner = RDXUI.MakeSlotSelectorDropdown(ui, i18n("Target texture"), state, "Tex_", nil);
        if desc and desc.owner then owner:SetSelection(desc.owner); end

        local duration = VFLUI.LabeledEdit:new(ui, 50);
        duration:SetText(i18n("Duration"));
        duration:Show();
        if desc and desc.duration then duration.editBox:SetText(desc.duration); end
        ui:InsertFrame(duration);
        
        local xscale = VFLUI.LabeledEdit:new(ui, 50);
        xscale:SetText(i18n("X Scale"));
        xscale:Show();
        if desc and desc.xscale then xscale.editBox:SetText(desc.xscale); end
        ui:InsertFrame(xscale);
        
        local yscale = VFLUI.LabeledEdit:new(ui, 50);
        yscale:SetText(i18n("Y Scale"));
        yscale:Show();
        if desc and desc.yscale then yscale.editBox:SetText(desc.yscale); end
        ui:InsertFrame(yscale);
        
        --Origin
        local er = RDXUI.EmbedRight(ui, i18n("Origin"));
        local origin = VFLUI.Dropdown:new(er, RDXUI.AnchorPointSelectionFunc);
        origin:SetWidth(100); origin:Show(); origin:SetSelection("CENTER");
        if desc and desc.origin then origin:SetSelection(desc.origin); end
        er:EmbedChild(origin); er:Show();
        ui:InsertFrame(er);
        
        --local edy = VFLUI.LabeledEdit:new(ctr, 75); edy:SetText(i18n("Offset X/Y:")); edy:Show();
        --local edx = VFLUI.Edit:new(edy); edx:Show();
        --edx:SetHeight(24); edx:SetWidth(75); edx:SetPoint("RIGHT", edy.editBox, "LEFT");
        --edy.Destroy = VFL.hook(function() edx:Destroy(); end, edy.Destroy);
        --ui:InsertFrame(edy);
        
        function ui:GetDescriptor()
            return {
                feature = "animation_scale"; version = 1;
                name = "Scale";
                owner = owner:GetSelection();
                duration = duration.editBox:GetText();
                xscale = xscale.editBox:GetText();
                yscale = yscale.editBox:GetText();
                origin = origin:GetSelection();
            };
        end
        
        return ui;
    end;
    CreateDescriptor = function()
        return {
            feature = "animation_scale", version = 1,
            name = "Scale", owner = "Base", duration = 10, xscale = 1, yscale = 1,
            origin = "CENTER",
        };
    end;
});
This has the same issue with moving unit frames as the rotation code I posted above.
__________________
What was is, what will be was.
  Reply With Quote
05-22-09, 01:19 PM   #4
sigg
Featured Artist
 
sigg's Avatar
Featured
Join Date: Aug 2008
Posts: 1,251
Add into 7.2 line RDX

Blizzard animation to Unitframes.

Step 1, declare Animation Group on the following components:
- Frame (and subframe)
- Texture
- Font



RDX : Only one animation Group can be created per element (restriction)
For each animation group, select NONE, REPEAT or BOUNCE type.

After Creating one Animation Group, add an animation (TRANSLATION, SCALE, ROTATION, ALPHA)



Condition variable : when to play the animation

Attached Thumbnails
Click image for larger version

Name:	ScreenShot001.jpg
Views:	919
Size:	38.7 KB
ID:	2689  Click image for larger version

Name:	ScreenShot002.jpg
Views:	908
Size:	33.4 KB
ID:	2690  
  Reply With Quote
05-22-09, 01:58 PM   #5
Dgrimes
A Black Drake
 
Dgrimes's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 89
Sigg from my testing with the animations multiple groups are able to be applied to the same region. I do not know the reason you are restricting the regions to allow only one animation group. Also about starting the individual animations, this part becomes tricky. Personally I would say start the animation group based on a condition not the individual animation or remove the order api from the features since the order only applies when the group is played versus the actual animation. Just my 2 cents.

Edit: Also playing an animation on a status bar has undesirable side effects from my personal testing. I haven't seen the code for your animations yet so I will just have to wait till then. I have not tried animations on text that is dynamic (ie: health/mana) yet and I do not know if that will have the same adverse side effects as a status bar would.
__________________
What was is, what will be was.

Last edited by Dgrimes : 05-22-09 at 02:00 PM.
  Reply With Quote
05-22-09, 02:36 PM   #6
sigg
Featured Artist
 
sigg's Avatar
Featured
Join Date: Aug 2008
Posts: 1,251
Yes, it is possible to create many AnimationGroups for one region.
Unfortunately, it is not possible to delete them (or changing parent).
When you are creating a AG, it is forever link to that region. (erf Blizzard)

That mean, when closing windows, I can't use frame:Destroy() method without having strange behaviours and generating memory leak. That also mean, you must use reloadUI command. This is not acceptable.

By restricted only one AG, it is possible to manage and recycle it. So no need to do any reloadUI.

I have also created pools animation objects, you can aquired any animations and then release them in the pool.

I will release the new version soon, and you will be able to test the animation system. The engine is still open for any suggestions.
  Reply With Quote
05-22-09, 05:37 PM   #7
Dgrimes
A Black Drake
 
Dgrimes's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 89
Sigg what about using this to create and destroy the animation groups
Code:
local createCode = [[
frame._a = ]] .. tname .. [[:CreateAnimationGroup();
_a:SetLooping(]] .. desc.loop .. [[);
frame.]] .. objname .. [[ = _a;
]];

local destroyCode = [[
frame.]] .. objname .. [[:Stop();
frame.]] .. objname .. [[ = nil;
]];
It seems to work fine for me on my warlock, not getting any weird side effects that I can tell that I used to get before without called the "frame.objname = nil;" in the destroy code. Just another 2 cents. Who knows I might be completely wrong here but it seems to be working fine for my unit frames that have 2 animation groups for 2 textures.

The reason I wish to be able to have more then one animation on more then one region is due to the fact that the animation group controls the looping state of its child animations. So if I wanted to have a bounce effect on on animation and a repeat effect on another I have to create more then one animation group. (I blame blizzard!)

Hope this helps.
__________________
What was is, what will be was.
  Reply With Quote
05-23-09, 03:15 AM   #8
sigg
Featured Artist
 
sigg's Avatar
Featured
Join Date: Aug 2008
Posts: 1,251
Code:
frame.titi = nil;
This doesn't mean destroy your object, just delete the link from the table, but your object is still here. And like frame object, I am not sure the Garbage collector can take it. Memory leak

Sigg
  Reply With Quote
05-25-09, 08:07 PM   #9
Dgrimes
A Black Drake
 
Dgrimes's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2008
Posts: 89
How does one go about finding if there is a memory leak sigg?
__________________
What was is, what will be was.
  Reply With Quote

WoWInterface » Featured Projects » OpenRDX » OpenRDX Community » OpenRDX: Community Chat » Animations on unit frame elements


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