0/ 1533/ /5

1) How to implement the skill editor in the form of Timeline
2) How to get the Key under Group through Group Name for Addressable
3) How does Unity get the UV value of Sprite in Sprite Packer
4) How to get all the state names of AnimatorController under UnityEditor
5) What does Unity do for UGUI’s Mask?

Today, we continue to select a number of issues related to development and optimization for you. It is recommended that you read it for 10 minutes, and you will be rewarded after reading it carefully.


Q: The project needs to be a skill editor in the form of Timeline. How is the form of timeline realized? Are there any references for the entire skill editor?

A1: It is recommended to learn how to use Timeline and how to do it with a traditional skill editor, and then think about how to combine it. The following article can be read first: “The Production Experience Sharing of ACT Skills Editor”


A2: You can refer to the official Timeline extension. In 2017, the Unity also has a related topic:


A3: First, how is the form of the time axis realized?

You can refer to several Unity plugins:
Recommend SLATE, which is more convenient to expand: packages/tools/animation/flux-18440

Second, the idea of the skill editor.
With the above timeline frame, different types of frames are developed based on the timeline, such as: playing special effect frames, animation frames, and hit point frames.

Give an example of special effects:

  1. Skill effects are nothing more than a few parameters: special effect name, offset information, hook point, etc.;
  2. Then need to implement the specific business code how to execute when this key frame is executed, such as loading the special effect according to the special effect name parameter configured on the frame, the bias information, and the hook parameter setting Transform of the special effect;
  3. The length of the frame is the life cycle of this special effect. When the frame is executed and exited, it will be destroyed.


Q: Can Addressable obtain the Key under this Group through the Group Name?

I put the hot update at the beginning of the game. The update process is as follows: create a loading interface (the resource is an independent Group in Addressable, called startGroup), then check whether the Catalog is updated, and then get all the key values to download the resource.

There is no problem with this process. The problem lies in: if the network is interrupted during the update, Addressable seems to release the resource memory in the update list, and the loading interface resources that use all the keys to download will be lost (blackened). After testing, manually exclude the Key in the startGroup, there is no such problem. So how to get the Key under this Group through the Group Name? Or is there a good update plan to share?

A1: There is an internal function:

internal bool GetResourceLocations(object key, Type type, out IList<IResourceLocation> locations)

You can refer to the specific implementation, which is also called internally by functions like GetDownloadSizeAsync.
As for the problem of resource loss, the information is not enough to judge.


A2: You can set the labels of the resources in the startGroup to “start”, you can get the Location list through the Label, and then exclude the Key value in this list from the total list:

public static List<string> GetAllKeys(string labelName)
    var t = Addressables.ResourceLocators;
    List<string> keys = new List<string>();
    foreach (var location in  t)
        if (!(location is ResourceLocationMap)) continue;
        ResourceLocationMap locationMap = location as ResourceLocationMap;
        locationMap.Locate(labelName, typeof(object), out var startLocationList);
        foreach (var info in locationMap.Locations)
            if(info.Value.Count == 0) continue;
            string str = info.Value[0].PrimaryKey;
            bool isHas = false;
            foreach (var startLocation in startLocationList)
                if(startLocation.PrimaryKey == str)
                    isHas = true;
            if (isHas) continue;
            string key = info.Key.ToString();
            if (int.TryParse(key, out var num))
            if (!keys.Contains(key))
    /*foreach (var locator in t)
        foreach (var key in locator.Keys)
            int value = 0;
            string str = key.ToString();
            if (!int.TryParse(str, out value))
    return keys;


Q: When using Sprite Packer’s atlas, how to get the UV value of Sprite in the atlas at runtime?

A: You can try this method: Sprites.DataUtility.GetOuterUV(activeSprite)


Q: AnimatorController is placed under UnityEditor, how can I get all the state names?

A: You can refer to:

In addition, AnimatorController has been under the Editor namespace since Unity5.2.


Q: For some reason, I decompiled the Mask component of UGUI, and then copied the code and changed its name for testing.
Then it was discovered that the copied Mask did not take effect.

The original Mask realizes clipping by modifying the material on the component, it will modify the material of itself and all the child nodes, and the copied mask will only modify its own material and will not affect the child nodes at all.

Want to know, how does the Unity make Mask affect the material of all child nodes?

A1: The Mask component is just a class that notifies the component and identifies the cutting information. After the component is turned on, it notifies all the Text and Image in the child nodes (these components are inherited from MaskableGraphic) to start the cutting calculation, and the MaskableGraphic will find the most nearest Mask component in the parent node to obtain clipping information, and it is useless to simply copy a Mask.


A2: According to the code of MaskableGraphic, only the Mask component of the current node is found, but the parent node is not found. I wrote an AlphaMask component for soft clipping and found that if the parent node hangs the Mask, this component will be abnormal. After investigation, it was found that Mask replaced the material and lost the information in the original material.

Then adjust AlphaMask with reference to the realization of Mask. The main purpose is to replace the material of the child node because there are many dynamic nodes in the project, and now you need to let each dynamic node call its own code to replace the material.

Finally, I found that MaskabelGraphic obtained the information of the parent node Mask by calling MaskUtilities.GetStencilDepth, and it was useless to directly GetComponentInParent.

That’s all for today’s sharing. Of course, life may have its limit but knowledge knows no bounds. In the long development cycle, these problems you see maybe just the tip of the iceberg. We have already prepared many technical topics on the UWA blog, waiting for you to explore and share them together. You are welcome to join in, who loves progress. Perhaps your method can solve the urgent needs of others, and the “stone” of other mountains can also attack your “jade”.


UWA Website:

UWA Blog:




Related Topics

Post a Reply

Your email address will not be published.