4

如何通过Timeline的形式实现技能编辑器

 3 years ago
source link: https://blog.uwa4d.com/archives/TechSharing_228.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1)如何通过Timeline的形式实现技能编辑器
​2)Addressable如何通过Group Name获得Group下的Key
3)Unity如何获取Sprite在Sprite Packer中的UV值
4)AnimatorController在UnityEditor下,如何获取所有的状态名
5)Unity为UGUI的Mask做了怎样的处理


这是第228篇UWA技术知识分享的推送。今天我们继续为大家精选了若干和开发、优化相关的问题,建议阅读时间10分钟,认真读完必有收获。

UWA 问答社区:answer.uwa4d.com
UWA QQ群2:793972859(原群已满员)

Editor

Q:项目需要通过Timeline的形式实现做个技能编辑器,时间轴的形式是怎么实现的?​整个的技能编辑器有没有相关的参考?

A1:建议学习Timeline的使用方法以及传统技能编辑器是怎么做的,然后再想想看如何结合。下面这篇文章可以先读一读: 《ACT技能编辑器的制作经验分享》

该问答由UWA提供

A2:可参考官方的Timeline扩展,2017年Unite也有个相关的主题:

https://assetstore.unity.com/packages/essentials/default-playables-95266

感谢羽飞@UWA问答社区提供了回答

A3:第一,时间轴的形式是怎么实现的?

你可以参考几个Unity 的插件:
https://assetstore.unity.com/packages/tools/animation/cinematic-sequencer-slate-56558
推荐SLATE,扩展起来比较方便:
https://assetstore.unity.com/packages/tools/animation/flux-18440

第二,技能编辑器思路。
有了上面的时间轴框架之后就是基于时间轴去开发不同类型的帧,比如:播放特效帧、动画帧和打击点帧等等。

举个特效的例子:

  1. 技能特效不外乎几个参数:特效名、偏移信息和挂接点等等;
  2. 然后需要去实现执行到这个关键帧的时候具体怎么执行的业务代码,比如根据帧上面的配置的特效名参数加载出这个特效,偏移信息和挂接点参数设置特效的Transform;
  3. 帧的长度就是这个特效的生命周期,帧执行完退出时做下销毁工作。

感谢波波@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5fb37c2210a17c6c2b09d15e


Addressable

Q:Addressable可以通过Group Name获得这个Group下的Key吗?

我把热更新放在了游戏开始时统一做。更新流程大概是:创建一个加载界面(资源在Addressable中是独立的Group,暂且叫startGroup),接着检查Catalog是否有更新,然后拿到所有的Key值下载资源。

这个流程是没有问题的,问题出在:如果在更新时网络中断了,Addressable似乎会把更新列表里的资源内存释放掉,使用了所有Key来进行下载的加载界面资源会丢失(变黑)。经测试,手动把startGroup里的Key排除掉,就没有这个问题。所以通过Group Name如何获得这个Group下的Key?或者有好的更新方案分享吗?

A1:有一个内部函数:

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

可以参考一下具体实现,这也是类似GetDownloadSizeAsync这样的函数在内部调用的。
至于资源丢失问题信息不够不太好判断了。

感谢黄程@UWA问答社区提供了回答

A2:可以把startGroup里的资源的Label都设置成了“start”,通过Lable可以拿到Location列表,然后把这个列表中的Key值从总列表里面排除:

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;
                    break;
                }
            }
            if (isHas) continue;
            string key = info.Key.ToString();
            if (int.TryParse(key, out var num))
            {
                continue;
            }
            if (!keys.Contains(key))
            {
                keys.Add(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))
            {
                keys.Add(str);
            }
        }
    }*/
    return keys;
}

感谢大侠陈二狗@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5f96c2335d9aea5aa971986c


Texture

Q:使用了Sprite Packer的打图集,如何在运行时候获取Sprite在所在图集中的UV值?

A:可以使用以下方式:
Sprites.DataUtility.GetOuterUV(activeSprite)

感谢题主凡凡@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5fb22b8810a17c6c2b09d13d


Animation

Q:AnimatorController被放在UnityEditor下了,该怎么获取所有的状态名?

1.png

A:可以参考一下:
https://stackoverflow.com/questions/41709325/retrieve-all-animator-states-and-set-them-manually-in-code

另外,AnimatorController从Unity5.2开始就一直是Editor命名空间下的。

2.png

感谢Xuan@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5fb32fd210a17c6c2b09d156


Q:由于某些原因,我把UGUI的Mask组件反编译了,然后把代码复制一份改个名字进行测试使用。
然后发现,复制出来的Mask竟然不生效。

原生的Mask通过修改组件上的材质,实现裁剪,它会修改自己跟所有子节点的材质;而复制出来的这个Mask,只会修改自己的材质,完全不会影响子节点。

想了解下,Unity是如何实现让Mask影响所有子节点材质的?

A1:Mask组件只是一个通知组件和标识裁切信息的类,在组件开启后通知子节点中所有的Text,Image(这些组件继承自MaskableGraphic)开始裁切计算,MaskableGraphic会去找父节点中离它最近的Mask组件获取裁剪信息,单纯复制一个Mask没有用。

感谢陈祥@UWA问答社区提供了回答

A2:根据MaskableGraphic的代码,里面只有找当前节点的Mask组件,并没有寻找父节点。写了个AlphaMask组件做软裁剪,发现如果父节点挂了Mask后,这个组件会不正常。经查发现是Mask替换了材质,把原有材质里的信息搞丢了。

然后参考Mask的实现调整一下AlphaMask。主要是替换子节点材质这部分,因为在项目中有很多动态节点,现在需要让每个动态节点自己调用代码替换材质。

最终发觉,MaskabelGraphic是通过调用MaskUtilities.GetStencilDepth拿到父节点Mask的信息的,没用直接GetComponentInParent。

感谢题主Walker@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/5f8ac1899424416784ef281b

封面图来源:A Terrible Kingdom
以创造性的方式编写游戏时间轴


今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。

官网:www.uwa4d.com
官方技术博客:blog.uwa4d.com
官方问答社区:answer.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:793972859(原群已满员)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK