精华内容
下载资源
问答
  • python代码翻译器-Python实现翻译软件

    千次阅读 2020-10-29 14:28:39
    前两天吃了平哥的一波狗粮,给女朋友写了一个翻译软件,自己真真切切的感受到了程序员的浪漫。在学习requests请求的时候做过类似的Demo,给百度翻译发送一个post请求可以实现任意词组的翻译,利用周六周日将那段...

    本篇文章主要讲讲述了用Python实现翻译软件,超级实用,赶紧将代码收藏起来试试吧,希望对你学习Python有所启发哦!

    前两天吃了平哥的一波狗粮,他给女朋友写了一个翻译软件,自己真真切切的感受到了程序员的浪漫。在学习requests请求的时候做过类似的Demo,给百度翻译发送一个post请求可以实现任意词组的翻译,利用周六周日将那段代码进行了进一步优化加了一个交互界面,有了今天的翻译软件。

    程序介绍

    先上图让大家感受一下

    f794fbe559d2609831c09c23d76115ac-1.png

    程序的功能很简单,可以从三个主流翻译器中选择任意的翻译器进行单词和句子的翻译,使用 PyQt5 模块实现人机交互,用requests模块发送请求,并将翻译结果返回给用户。

    具体实现

    用百度翻译来举例

    任意的进行翻译来查看页面信息。

    f794fbe559d2609831c09c23d76115ac-2.jpg

    从图片中可以发现这是一个post请求,请求头的数据在的图片中也有较清楚的显示。

    e3fa7992ebcf6144d2426394d5ca319b-3.png

    我们需要在添加上面的数据,其中 simple_means_flag 为固定量,query 代表待翻译的词,根据这些信息我们写个简单的代码测试一下。import requests

    headers={"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36"}

    post_data={

    'query': 'Ahab杂货铺',

    'from': 'zh',

    'to': 'en',

    'sign': '413120.175857',

    'token':'64d8ce70799b54833f56b43f9d6eb3b4'

    }

    post_url="https://fanyi.baidu.com/v2transapi"

    r=requests.post(post_url,data=post_data,headers=headers)

    print(r.content.decode())

    运行以后输出下面的结果:

    e3fa7992ebcf6144d2426394d5ca319b-4.png

    出现上面错误的原因就是sign和token这两个参数搞的鬼,先说token,token可以直接在百度翻译主页的源码里找到:

    e3fa7992ebcf6144d2426394d5ca319b-5.png

    因为时间戳不同步所以直接请求百度翻译的主页获取到的 token 是用不了的,只能人为地把网页当前显示的 token 值复制下来然后赋值给代码里的 token。

    sign 参数是根据翻译的内容而在前台生成的,如果发送的请求中,query 内容和 sign 不匹配,则收到的响应是 error。下面要做的就是破解百度翻译 sign。sign 是由一个 js 文件生成的,下图就是生成 sign 的 js 文件。

    e3fa7992ebcf6144d2426394d5ca319b-6.jpg

    将这个代码放在格式化工具中重新排版一下,找到 sign 执行函数的代码,再用 execjs,执行这段 js 代码,在计算过程中还需要 gtk 的值,这个值在翻译首页获取一下就可以。js = js.replace(

    上边的步骤完成以后我们就可以愉快的进行翻译了。

    图形化界面用的是 pyQt5 这个模块,实现起来不难。class Demo(QWidget):

    def __init__(self, parent=None):

    super().__init__()

    elf.setWindowTitle('翻译软件-公众号: Ahab杂货铺')

    self.Label1 = QLabel('原文')

    self.Label2 = QLabel('译文')

    self.LineEdit1 = QLineEdit()

    self.LineEdit2 = QLineEdit()

    self.translateButton1 = QPushButton()

    self.translateButton2 = QPushButton()

    self.translateButton3 = QPushButton()

    self.translateButton1.setText('百度翻译')

    self.translateButton2.setText('有道翻译')

    self.translateButton3.setText('谷歌翻译')

    self.grid = QGridLayout()

    self.grid.setSpacing(12)

    self.grid.addWidget(self.Label1, 1, 0)

    self.grid.addWidget(self.LineEdit1, 1, 1)

    self.grid.addWidget(self.Label2, 2, 0)

    self.grid.addWidget(self.LineEdit2, 2, 1)

    self.grid.addWidget(self.translateButton1, 1, 2)

    self.grid.addWidget(self.translateButton2, 2, 2)

    self.grid.addWidget(self.translateButton3, 3, 2)

    self.setLayout(self.grid)

    self.resize(400, 150)

    self.translateButton1.clicked.connect(lambda : self.translate(api='baidu'))

    self.translateButton2.clicked.connect(lambda : self.translate(api='youdao'))

    self.translateButton3.clicked.connect(lambda : self.translate(api='google'))

    self.bd_translate = baidu()

    elf.yd_translate = youdao()

    self.gg_translate = google()

    def translate(self, api='baidu'):

    word = self.LineEdit1.text()

    if not word:

    return

    if api == 'baidu':

    results = self.bd_translate.translate(word)

    elif api == 'youdao':

    results = self.yd_translate.translate(word)

    elif api == 'google':

    results = self.gg_translate.translate(word)

    else:

    raise RuntimeError('Api should be or or ...')

    for result in results:

    self.LineEdit2.setText(result)

    以上就是Python实现翻译软件的详细内容,更多请关注php中文网其它相关文章!

    本文转载于:CSDN,如有侵犯,请联系a@php.cn删除

    展开全文
  • 这篇文章里面完全是中文翻译,不含英文,只是为了不熟悉英文又想快速了解AnimMontage的朋友,由于水平有限,里面一些翻译掺杂了我个人的理解,如果有任何问题欢迎提出,我会及时修改的~同时这里需要声明一点,官方的...

    这篇文章里面完全是中文翻译,不含英文,只是为了不熟悉英文又想快速了解AnimMontage的朋友,由于水平有限,里面一些翻译掺杂了我个人的理解,如果有任何问题欢迎提出,我会及时修改的~同时这里需要声明一点,官方的中文文档已经有很久没有更新(当前文档的版本应该是4.7以前的),如果需要的话,我可能会将当前的英文官方文档(当前是4.9版本)翻译出来。



    这里对AnimMontage动画系统稍作解释,蒙太奇现在一般是指一种拍摄手法。在UE4里面一般是用来更好的融合与衔接角色不同动作的动画。他可以让你的角色在上半身开枪的同时执行下半身的跑步动作,也可以让你的角色更为顺畅从静止状态切换到任意一个动作并实现任意次数的动作播放。总之,AnimMontage确实是一个很方便又很强大的动画辅助系统。

    AnimMontage(动画剪辑:蒙太奇)


    Overview(综述

    动画剪辑系统(简称Montage)是一种通用的工具,他可以将多种动画效果(Animation)传递给那些用代码或者蓝图所实现的动画控制器。他也可以被用来创建诸如动画的智能循环,基于逻辑的动画转换,根节点运动处理等等各种各样的动画(Animation)。(注:Montage即蒙太奇,法语是“剪接”的意思。现在普遍指一种表现电影的拍摄手法,表示对电影镜头的组合运用)

    动画剪辑是一个动画集合,可以在内容浏览器被创建并保存。这些集合可以实时的直接插入到*动画编辑图AnimGraph 中并且你可以任意的修改他的状态。例如,你可以切换不同的动画部分并且重新链接他们。动画剪辑大量应用于代码控制的动画或者一次性的动画。例如,格斗攻击动画,需要你来控制触发器,按照你的意愿随时停止或者改变状态(是否循环)。(参考下面的图片)

    Montage_Screen2.png

    上面的图片展示了一个拥有三部分的攻击动画 [开始,循环,结束]。当玩家点击鼠标左键时,就会在你调用动画剪辑 的时候默认触发开始的动画部分。现在我们看到中间部分是被设置为循环的。当开始动画播放结束后,就会过度到中间的循环部分并一直循环下去。如果玩家释放了鼠标左键,循环就会停止。但是你应该不想让动画在播放到一半的时候就突然中断。你可能更想让循环部分播放后再链接到结束动画部分,这样就可以让中间部分渐渐的淡入结尾部分并完成整套动作的播放。(注:这样看起来效果更好)

    一些针对动画剪辑的其他用法:

    • 可以使用蓝图的事件图(EventGraph)来控制播放动画

    • 把多个不同的动画序列链接成一个单独的动画

    • 通过蓝图或代码,局部的循环播放一个或多个动画的特定部分

    • 通过蓝图或代码,处理基于事件的多种复杂动画的切换

    • 恰当的处理“操作对象”的根节点动作

    • 把复杂的动画序列分配给不同的被命名的插槽(注:理解为序列中的任意位置都可以定义一个插槽)

    • 通过蓝图或代码,精确的把不同的动画序列连接到一起

     所以,我们就会发现,在动画剪辑中我们可以自由地去做很多事情。这使动画剪辑理所当然的成为一个出色的系统。当然,如果非要去总结一下的话,动画剪辑系统就是把所有的动画展示给我们的代码和蓝图,从而让我们能自由的控制。就凭这一点,我们几乎就可以做出一切我们想要的效果。

         想尝试动画剪辑如何运用到角色身上的话也可以参考例子 Animation Content Examples 的1.5章节。

    System Caveats(系统说明)

    关于动画剪辑系统有几点需要说明一下:

    • 同一时刻只能播放一个Montage(注:为了叙述简洁,后面一些地方直接使用英文)动画。如果你开启了另一个Montage动画,第一个就会停止。
    • 动画播放的一刻,根节点的动作将会被复制到服务器上,但是动画剪辑的内容不会被复制。这也就是说,用户执行根节点动作时需要确保动画剪辑的状态通过网络传输到服务器或者其他玩家客户端(如坐标,玩家状态等)。(注:如果客户端服务器状态不统一,会导致二者计算结果不同,游戏的效果也就不同)


    Montage Properties(动画剪辑的特性)

    下面图片是动画剪辑自身属性的分类展示。这些属性可以在打开角色视图(注:包括骨骼,Mesh,动作等文件)的动画剪辑中看到,当然你也可以在文件浏览器中通过右击一个动画剪辑文件并选择属性菜单来查看。

    MontageProperties.png

    Montage Properties(动画剪辑属性)

    Montage

    Blend In Time

    混合切入时间

    This is an amount of time at the beginning of Montage playback during which the character will blend in from its current pose.

    这是在Montage动画开始播放时,从当前动作状态过度到新动作所消耗的时间。(注:该时间为0,则没有过度;时间越大,新动作越不明显,当超过一定值时,几乎没有变化)

    Blend Out Time

    混合切出时间

    This is an amount of time at the end of Montage playback during which the character will blend back to its original pose.

    这是在Montage动画结束播放前,动作切换到原始状态所消耗的时间。

    Root Motion(根节点动作)

    Enable Root Motion Translation

    可以编辑根节点位移变换

    Enables handling of root motion translation, cancelling out any translation applied to the root so that it can then be applied back to the character's collision capsule. Please see 根骨骼运动 for more details.

    (勾选的话)可以编辑处理根节点的动作(位移)变换,(不勾选)取消任何对根节点的位移操作。这样就可以决定是否使人物使用角色本身的碰撞胶囊。想查看更多细节请参考根骨骼运动

    Enable Root Motion Rotation

    可以编辑根节点的旋转变换

    Enables handling of root motion rotation, cancelling out any rotation applied to the root so that it can then be applied back to the character's collision capsule. Please see 根骨骼运动 for more details.

    勾选的话可以编辑处理根节点的动作(角度)变换,(不勾选)取消任何对根节点的旋转操作。这样就可以决定是否使人物使用角色本身的碰撞胶囊。想查看更多细节请参考根骨骼运动

    Additive Settings(附加设置)

    Preview Base Pose

    预览基本动作

    Sets a base preview pose used for additive Blend Spaces.

    为附加的动作混合窗口设置一个基本动作的预览。(注:其实就是你这个Montage的一个动画预览,默认的为空显示的就是你编辑后的结果,所以一般不用设置)

    Animation(动画)

    Rate Scale

    比率

    A multiplier value for how fast the Montage will play back. Default is 1.0.

    一个因数值来表示Montage动画播放的速率,默认为1。

    Skeleton

    骨骼

    Contains the skeleton associated with this Montage. Cannot be changed in the editor

    .包含了和Montage动画相关的骨骼。在编辑器里面不能修改


    Montage UI(动画剪辑系统UI)

    当我们在角色窗口查看动画剪辑系统时,很有必要去知道每一块区域是做什么的:

    MontageUI.png

    1. Montage Area                剪辑Montage)区域

    2. Sections Area                片段(Section)区域

    3. Element Timing Area   元素时间(Element Timing)区域(当前中文文档也就是4.7版本以前没有该项)

    4. Notifies Area                  通知(Notifies)区域

    5. Curves Area                   曲线(Curves)区域


    Montage Area(剪辑区域)

    动画剪辑区域分解示意图如下:(后面会解释为什么只有两个部分)

    MontageArea.png

    1. 片段轨道 - 显示所有为Montage动画所定义的动画片段。这些片段可以用鼠标左键拖到时间轴的任意位置上。
    2. 插槽轨道 - 显示当前的插槽并且在插槽右边显示其名称。这个插槽轨道可以按你的意愿插入任意数量的动画。他们会按照时间轴的顺序播放。需要注意不同的动画需要交替的出现在插槽轨迹上,就是按照第一个在上,第二个在下,第三个又在上的顺序交替。这会帮助你区分不同的动画片段。
    3. 分支点轨道 - 显示所有为Montage动画定义的分支点。分支点可以被鼠标左键拖到时间轴上的任意位置。(已经去除该功能)
                        你会有你所期望的任意数量的插槽轨道,每一个都有自己的名字并且包含自己特有的动画。但是,在一个Montage动画里面你只能拥有一个片段(section)轨道和一个分支点轨道。

    (注:这里很多朋友可能有疑问,因为我们根本找不到Branch Point Track这个轨道。我在4.8.3版本里面就已经没有这个轨道了,而在比较早的版本(可能是4.5以前)是有的。原因是中文的官方文档没有及时更新,而英文的版本已经去除了Branch Point Track轨道,但是Branch Point的功能仍然是有的,在添加Notifier时,这个消息的Event属性——Montage Tick Type里可以选择到Branch,所以想使用这个功能的朋友可以使用Notifies来代替,并改变这个属性。

    关于一般的Notifier与Branch的区别:Notifier是异步的,不能很及时的响应,想要在某一帧的上直接改变动作不能使用Notifier。这时候可以使用Branch来及时的响应。


    Sections(片段)

    Montage动画系统的片段轨道提供了一种可以打破正常 插槽播放顺序 的方式。每一个片段有一个名字并且处于插槽时间轴的一个位置。用这个名字,你可以在当前动画部分播放完成后直接跳到一个指定的片段或队列并接着播放。在蓝图中,你可以查询当前的片段,切换到任意一个片段,或是设置下一个需要播放的片段。

    让我们打个比方,片段就像一个音乐播放列表的歌曲一样,每一个插槽轨道就是一个专辑,里面有很多的现代流行歌手的歌。当一首歌结束时,你可以选择下一首播放什么或者直接跳到你想听的那一首歌来播放。

    点击鼠标右键在片段轨道上选择新建新的剪辑片段New Montage Section就可以创建一个片段了


    Slots(插槽)

    在动画剪辑中,插槽就是一条可以容纳无数动画的存储轨道。你可以命名每个插槽轨道,并且通过轨道的名称来调用之前选定的融合到一起的动画序列。举一个合适的例子,假设你有一个角色需要执行为武器重装弹药的动画。同一个动作可能会有很多不同的版本,比如在站立时,蹲着时,匍匐时都有所差别。只要三个动画用同样的使用同样长度的时间,你就可以在Montage系统里把他们分别放在单独的插槽轨道里。这几个轨道可以分别命名为站立,蹲下,匍匐。然后在你的动画蓝图的角色状态图(AnimGraph)中,你可以根据你人物角色的当前状态决定使用你的插槽轨道。当角色站立时,就可以使用站立的插槽轨道。当他匍匐时,就可以使用匍匐插槽轨道来播放匍匐的更换弹药的动作。

    有一点很重要,我们要知道虽然大部分的Montage动画控制会在蓝图的事件图中进行,但是插槽部分却是被AnimGraph所控制的。这部分功能通过带有名字的插槽节点来控制实现。将一个插槽节点放在一个有战略意义的位置上来执行,你就可以利用相同的插槽节点创造出丰富的动画剪辑效果。


    Sections Area(片段区域)

    在片段区域,你可以根据Montage系统区域定义不同的片段来创建不同的剪辑动画关系。例如,你可能需要一个特定的片段动画,或是一组动画来按顺序或者循环播放。

    SectionsArea.png


    1. 创建默认清除按钮 - 创建默认按钮创建按照所有片段的默认顺序接连的将各个动画片段排成一个序列。清除键则将他们完全分开,不在有任何联系。
    2. 片段按钮 - 这这个区域,你将会看到你在剪辑区域定义的所有片段。选择下面第3部分的一个轨道上存在的片度并接着点击区域2其中的一个按钮,你就可以把区域2的片段添加到下面的轨道上。例如,在上面的图片里,我们把Swing2连接到Swing1上。这个顺序就变成了Swing1,Swing2,Swing1,Swing2这样循环的播放下去。关于循环的细节,下面一段会继续阐述。
    3. 片段关系逻辑轨道 - 在这个区域,你可以看到并预览所有动画片段的执行关系。点击预览按钮,你就可以看到每个独立轨道的的播放效果。也点击预览所有,查看所有片段的循环播放。
       (注:暂时我的理解是,对于区域3的每一个section,只有第一条的轨道才是角色真正运行的动画序列。上面的Montage区域目的就是为了给每一个动作定义一个section从而可以在Section区域自由的控制Montage的播放顺序。)


    Looping(循环)


    片段可以被设置为无限循环的播放,这无疑对你想要重复的动作是非常有用的。通过在轨道上把同一个片段添加两次,你就可以得到一个循环。如果进入循环状态,这个动画片段的颜色就会变成蓝色。举个例子,假设一个角色正在给枪或者炮弹装填弹药。你可以只选择这一动画部分插入到装弹的状态并且循环播放。之后,通过动画通知功能(下面有讲解),你可以在蓝图中创建响应信息的事件在每次装弹时增加这个弹药的数量并多次播放这个动作。一旦弹药到达一定数量(满弹药),你就能停止接收消息切换到平时的待机状态。


    Notifies Area(动画通知区域)

    NotifiesArea.png

    动画通知(简称AnimNotifies或通知)使得动画相关的程序员可以设置在动画序列的特定点处发生的事件。通知通常用于这样的特效,比如走动时的脚步声、跑动动画或在动画中产生一个粒子特效。然而,它有很多种不同的用途,因为您可以使用自定义的通知类型来扩展该系统,从而满足任何类型游戏的需求。

    For more information, see 动画通知 (通知).

    Curves Area

    CurvesArea.png

    曲线提供了在动画正在播放过程中改变材质参数或顶点变形目标的方法。 其工作流程非常简单,只需要您简单地指定您要修改的资源(一个材质或顶点变形目标),相应地命名该曲线,然后调整动画播放期间的关键帧的值。

    For more information, see 动画曲线.


    Montage Practical Example(动画剪辑系统使用实例)

    在这个例子中,我们想创建一个可以向各个方向自由移动的角色,这个角色还可以在上半身播放一个攻击的动画。这个攻击动作包含多个可以在执行过程中播放的动画。这是一个能非常完美地展现Montage动画系统功能的方式,同时也可以展示如何在事件图控制它,以及如何在AnimGraph中将Montage与其他动画混合播放。

    不过,在开始之前我们要提前做好几点准备工作:

    • 已经建立了一个行动的状态机。这个状态机与第三人称游戏模板工程的状态机一样。
    • 已经有了美术人士提供的相关的可以加入Montage系统的动画素材。(注:UE4一般使用FBX文件)
    • 已经创建了角色蓝图来接收输入信息。 
                  ○ 例如:创建一个名为是否攻击(ISAttacking)的布尔变量,当点击鼠标左键时设置为哦true,松开时设置为false。


    CharacterBlueprint.png


    Creating the Montage(创建动画剪辑)

    创建一个Montage动画系统很容易。只要在内容浏览器右键鼠标选择 动画->动画剪辑Animation > Animation Montage)就创建成功了。你也可以在内容菜单里一个存在的动画序列上右键鼠标并选择创建Montage动画剪辑(Create Montage)。这样就会以这个动画作为默认的动画插槽创建一个新的Montage动画剪辑。

    MakeMontage.png

    Montage Setup(动画剪辑的创建)

    我们第一件要做的事情就是给插槽(Slot)命名。在一个动画剪辑中,一般只需要有一个插槽,而且既然我们想让这个Montage只影响角色的上半身,不妨就把这个插槽命名为UpperBody吧。之后,把我们需要的动画拖到这个插槽里面。需要的动画有下面4个:

    • 从右向左挥动锤子
    • 从左向右挥动锤子
    • 从右向左挥动锤子结束动作(衔接到待机状态)

    • 从左向右挥动锤子结束动作(衔接到待机状态)

           这两个挥动的动画会在一个结束时播放另一个。这就意味着这两个动画可以循环交替的播放下去,看起来就行角色在不停的反复进行 挥动锤子

    其实顺序并不是很重要,不过使前两个动画在序列的开始并挨在一起就会让后面的操作简单不少。

    MontageSetup.png


    Section Creation(片段创建)

    下一步操作就是给每个动画制作片段,这样我们在蓝图或代码中就可以方便的查询与使用他们。步骤也很简单,在片段那条轨道上(Montage区域的最上面)右键鼠标选择添加Montage片段(Add New Montage Section)。

    我们直接给每个片段命名。注意要把之前创建Montage的默认片段给替换掉。(创建一个新的片段并且右击默认片段选择删除片段)你可以在轨道上随意的拖动这些片段而且如果你在两个动画衔的接位置松开,他们会自动对其。好好利用这点。

    AddNewSections.png


    Defining Section Relationships(给片段确定关系)

    一旦我们的片段都已经创建好了,我们就可以在片段区域给他们随意的定义关系。比如,我们可以定义一个联系让Swing1和Swing2循环交替的播放。这对我们来说非常有用。点击清除按钮可以擦除我们定义的任何关系。操作很简单,就是在轨道上点击Swing1,然后在片段顶部区域点击绿色的Swing2按钮。这样就会把Swing2轨道移除,并把Swing2片段移动到Swing1轨道的后面。

    Swing2Track.png

    如果想重复某一个动作,点击第一个轨道上刚刚创建的Swing2片段然后在点击区域上方的Swing1按钮,系统就会认为你正在创建一个循环,并且这个循环的片段部分就会变成蓝色。这就意味着Swing1和Swing2片段想成为一个循环。他们就会一直的重复播放下去。

    LoopingTracks.png


    Setting Up the AnimGraph(设置动画图)

    现在,我们的Montage动画已经建立好了。我们接下来需要创建我们动画图(AnimGraph)好让他去把Montage动画融入到我们的这个人物的动作里。这一步很简单,但是他会提醒我们去仔细思考一下我们的流程是什么样的。动画图一开始的效果是下图所示的样子,我们只能看到状态机所展示的结果。

    StateMachineResult.png

    因为我们现在只想Montage动画从Spine_01骨骼(腰部)开始播放,所以需要一个名为 骨骼层混合(Layered Blend per Bone) 的节点。给混合动作0(Blend Pose 0)设置比重为1。同时我们也把混合动作设置绑定到Spine_01骨骼上。之后引入一个插槽节点并设置为UpperBody(我们之前所命名的Slot)。然而,你会发现,现在出现了一个问题:

    SlotAndBlend.png

    一旦Montage动画执行完成,这个插槽节点需要一个动作来源来恢复之前的动作。没有这个动作来源,角色在Montage动画执行完毕后就会回到最开始的T型姿态的样子(注:就是模型最原始的无任何动作的状态)。然而,我们不能把状态机的节点同时链接到插槽节点(Slot)骨骼层混合节点(Layered Blend per Bone)。那么如何解决这个问题呢?答案是使用一个缓存节点Cache )。我们可以暂时把状态机的结果存储为一个变量,这样你就可以在各个地方重复的使用了。举例来说,我们把这个节点命名为动作缓存LocoCache),按照下图的样子使用。

    CachedLocomotion.png

    现在我们的动画图已经完成了。一旦UpperBody插槽节点收到了Montage动画发送的任何消息(你可以使用任何你创建的Montage,只要他有一个叫做UpperBody的插槽就可以),他就会执行混合动画。如果停止接收消息,角色就会恢复状态机里的动画状态。

    Setting Up the Event Graph(设置事件图)

    事件图的设置非常重要。使用蓝图动画更新事件(Event Blueprint Update Animation) 节点作为开始并创建一个获取玩家角色(Get Player Character)的节点,我们就可以把角色蓝图强制转换为我们自定义的角色(这里我们定义的角色名为MyCharacter)同时获取角色里面定义的变量和方法(想获取更多关于蓝图交互的信息请看Blueprint Communications章节)。

    我们要做的第一件事接收检查一下我们角色蓝图中的IsAttacking变量是否是正确的,如果是true的话再检查一下Montage动画是否正在播放。如果是,就不需要再去播放一遍;如果没有在播放,那么就让他去播放。这样可以防止动画从Montage播放到一半的时候直接切换到开头并再次播放动画。

    EndLoopEventGraph.png

    那么一切都已经搞定了。如果我们开始编译,我们就会看到角色随着鼠标按钮的按下不断的挥舞着他的锤子并且在鼠标按钮放下时播放结束动画作为衔接!

    展开全文
  • 在前面的一篇文章如何用python“优雅的”调用有道翻译中咱们清楚的写过如何一层一层的解开有道翻译的面纱,并且笔者说过那只是脑洞的开始。现在笔者又回来了。Teach you how to flirt gracefully with code。 设计...

    前言

    在前面的一篇文章如何用python“优雅的”调用有道翻译中咱们清楚的写过如何一层一层的解开有道翻译的面纱,并且笔者说过那只是脑洞的开始。现在笔者又回来了。当你遇到一些外国小哥哥小姐姐很心动、想结识交流,但英语水平或其他水平还在提升阶段,这个小工具可以帮你渡过难关!Teach you how to flirt gracefully with code。在本文中,我将详细讲解这个翻译的具体实现!对于实现的主要功能:通过微信聊天监听一些关键的口令,开启自己说的话的翻译模式和对面说的话的翻译模式!

    在这里插入图片描述
    设计思路:前面有了调用翻译,我们可以和翻译接口微信的api结合起来做一些有趣的事情,主要就是利用微信api对自己发的消息进行监测,然后有些关键字判断作为开关、修改翻译语言等等(逻辑可以自己设置),接着去请求有道翻译,利用程序自动发送翻译的话给对方。然后再假装把自己当成一无所知的萌新------看你怎么操作了(手动滑稽)

    当然,如果你有个韩国朋友,他说的话自动翻成中文,发给你,你说的话自动翻成韩文再发给他。有本事有资源的小哥哥小姐姐可以去试试洋妞洋娃娃
    在这里插入图片描述

    详细设计

    既然前面的思路很明确了,那么咱么一步一步来,如何攻克其中的种种问题。主要两个方面,一个是单独的微信api和单独的请求有道翻译一些其他规则另一方面是将两者整合起来,可以让人人性化的操作!

    当然解决了这两项之后,你就可以自己实现一些逻辑开关,而我就用我的逻辑简单的实现了一下!

    环境:win/linux
    编译器:pycharm
    额外模块:itchat、requests

    微信api

    微信方公开了微信网页版的api。python中的itchat模块就可以直接使用。当然摸索起来也是需要时间。有些必要的学习步骤我就放上了。

    1 . 对于itchat模块的扫码登录。后面可以不加参数,但是加了这个hotReaload之后短期内可以不需要扫码,不然每次启动扫码耽误效率。

    import itchat
    itchat.auto_login(hotReload=True)
    

    2 . 至于还有一个发消息的api也很简单,后面的userName是用户的唯一的被加密的字段,当然,文件传输助手有专门id,还有其他搜索好友名通过返回的json串也可以获得用的该id。总之这个字段很好获得。

    itchat.send("你好",toUserName = userName)
    

    3 . 最重要的就是消息的监听了,对于消息监听,大部分百度到的结果都是将程序做成机器人,监听对面消息然后自动回复,但是笔者要的不是这个效果,我是想监听自己移动端微信发的消息然后进行分析啥啥啥的。

    对于正常的监听都是这样的

    # 注册消息响应事件,消息类型为itchat.content.TEXT,即文本消息。也可以监听多种类型可自行百度
    @itchat.msg_register(itchat.content.TEXT)
    def text_reply(msg):
       return msg['Text']#return “字符串” 当接受到对面消息时候,就会发过去充当机器人 
    itchat.run()
    

    但是,如果你如果再其中print(msg).你会发现你自己发的消息也会被监听到,这里的就是from you send to he/she。所以可以获取里面内容自己利用itchat发送sendapi主动发送消息。当然,你发送的内容主体等各种信息都在里面,py正好也很方便操作字典。
    在这里插入图片描述
    那么这部分的最终设计是这样的:
    其中如果是对面发来的消息我们直接return 字符串就会发送,如果是自己发的消息,自己send调用发送信息即可!

    # 注册消息响应事件,消息类型为itchat.content.TEXT,即文本消息
    @itchat.msg_register(itchat.content.TEXT)
    def text_reply(msg):
         #xxxxx 逻辑处理如果自己发
         itchat.send(transtr, toUserName=msg['ToUserName'])#将字符串transtr发给你发的人
         #xxxxx 逻辑处理如果ta发
         return transtr#这个加上是如果对面发消息的监听。也就是对面发消息过来你直接return就会自动发送
    itchat.run()
    

    有道api

    对于其他的前面已经分析过,这里需要注意的是翻译成的语言,比如中翻译英(en)、日语(ja)、韩语(ko)等等。所以你点几个典型的放到逻辑处理里面就好了。
    在这里插入图片描述

    整体逻辑

    当然,我想写个逻辑可以控制发送翻译的开始、结束。所以我监听用两个个Boolean类型控制整个开始和暂停,其中jud用来判断自己是否开启自己说的话的装(b)翻译模式。而参数isreturn用来控制判断是否翻译洋娃娃说的话。关键词这里我选开始作为开始,停止作为结束控制自己说的话。而翻译模式停止翻译则用来控制开始和停止说的话。英语、日语、韩语、法语、等作为翻译语言更改的关键词。

    那么,一旦程序跑起来,一切都在我们的掌控之中,当然,测试过效率,虽然那个itchat,和有道翻译的数据都是通过http传输的,但是其实效率还行,对于聊天来说传输效率是可以接受的。延迟不算很大,能满足基本需求。但是切记不要太快太频繁哈,防止有道把你的ip封了你就无法请求了。

    代码和运行结果

    就这样,我把项目的代码完整的供出来。

    项目github地址(微信模块):https://github.com/javasmall/python
    欢迎star!

    #更多请关注公众号:bigsai
    import itchat
    import requests
    import hashlib
    import time
    import urllib.parse
    
    jud=False#默认是先不开启
    isreturn=False#是否回复
    To='en'#翻译成的语言默认是英语
    
    def nmd5(str):#md5加密
        m = hashlib.md5()
        b = str.encode(encoding='utf-8')
        m.update(b)
        str_md5 = m.hexdigest()
        return  str_md5
    def formdata(transtr):
        # 待加密信息
        global To
        headerstr = '5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'
        bv=nmd5(headerstr)
        ts=str(round(time.time()*1000))
        salt=ts+'90'
        strexample='fanyideskweb'+transtr+salt+'n%A-rKaT5fb[Gy?;N5@Tj'
        sign=nmd5(strexample)
        i=len(transtr)
        dict={'i':transtr,'from':'AUTO','to':To,'smartresult': 'dict',
              'client':'fanyideskweb',
              'salt':salt,
              'sign':sign,
              'ts':ts,
              'bv':bv,
              'doctype':'json',
              'version':'2.1',
              'keyfrom':'fanyi.web',
              'action':'FY_BY_REALTlME'
        }
        return dict
    url='http://fanyi.youdao.com/translate_o?smartresult=dict&smartresult=rule'
    header={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36',
     'Referer':'http://fanyi.youdao.com/',
     'Origin': 'http://fanyi.youdao.com',
     'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8',
     'X-Requested-With':'XMLHttpRequest',
     'Accept':'application/json, text/javascript, */*; q=0.01',
     'Accept-Encoding':'gzip, deflate',
     'Accept-Language':'zh-CN,zh;q=0.9',
     'Connection': 'keep-alive',
     'Host': 'fanyi.youdao.com',
     'cookie':'_ntes_nnid=937f1c788f1e087cf91d616319dc536a,1564395185984; OUTFOX_SEARCH_USER_ID_NCOO=; OUTFOX_SEARCH_USER_ID=-10218418@11.136.67.24; JSESSIONID=; ___rl__test__cookies=1'
     }
    itchat.auto_login(hotReload=True)#登录
    
    
    # 注册消息响应事件,消息类型为itchat.content.TEXT,文本消息
    @itchat.msg_register(itchat.content.TEXT)
    def text_reply(msg):
        # 返回信息调用信息
        global jud
        global To
        global  isreturn
        text=msg['Text']
        dict = formdata(text)
        if "翻译模式" in text:
            isreturn =True
        elif "停止翻译" in text:
            isreturn=False
        if  "开始" in text:
            jud=True
        elif  "停止" in text:
            jud=False
        elif "英语" in text:
            To = 'en'
        elif "日语" in text:
            To = 'ja'
        elif "韩语" in text:
            To = 'ko'
        elif "法语" in text:
            To = 'fr'
        if jud:#说明需要运行
            dict['to']=To
            dict['from']= 'AUTO'
            dict = urllib.parse.urlencode(dict)
            dict = str(dict)
            req = requests.post(url, timeout=1, data=dict, headers=header)
            val = req.json()
            transtr = val['translateResult'][0][0]['tgt']
            print(msg)
            itchat.send(transtr, toUserName=msg['ToUserName'])
        ##返回监听对面说的话
        if isreturn:
            dict['from']='AUTO'
            dict['to']='zh-CHS'##翻译成中文
            dict = urllib.parse.urlencode(dict)
            # dict = str(dict)
            req = requests.post(url, timeout=1, data=dict, headers=header)
            val = req.json()
            transtr = val['translateResult'][0][0]['tgt']
            print(msg)
            return 'ta说:'+str(transtr)#这个加上是如果对面发消息的监听。比如你是双向翻译可以尝试下
    # 绑定消息响应事件后,让itchat运行起来,监听消息
    itchat.run()
    
    

    鉴于笔者真没有洋娃娃所以只能模拟了
    简单运行测试结果(拿队友手机自导自演)
    在这里插入图片描述

    结语

    当然,这或许可能很有趣,又或许可能很无聊很简单,只是不同的人可能有不同的看法,不同的时间段、不同的交际都可能有不同的看法,所以请各位大佬不喜勿喷,当然,如果有改进的建议,还请指出!
    python相关仓库和项目github地址https://github.com/javasmall/python/tree/master/%E7%88%AC%E8%99%AB/Include/%E5%BE%AE%E4%BF%A1,(微信文件目录)有兴趣的可以玩玩,star star!如果感觉还行还请各位动动小手点点收藏、点点赞👍!

    欢迎关注公众号:bigsai 长期奋战输出!

    展开全文
  • 最近学习UE4的使用,发现这篇官方文档没有中文翻译,就想着翻译一下给大家参考参考吧。由于水平有限,里面一些翻译掺杂了我个人的理解,如果有任何问题欢迎提出,我会及时修改的~同时这里需要声明一点,官方的中文...



    近学习UE4的使用,发现这篇官方文档没有中文翻译,就想着翻译一下给大家参考参考吧。由于水平有限,里面一些翻译掺杂了我个人的理解,如果有任何问题欢迎提出,我会及时修改的~同时这里需要声明一点,官方的中文文档已经有很久没有更新(当前文档的版本应该是4.7以前的),如果需要的话,我可能会将当前的英文官方文档(当前是4.9版本)翻译出来。

    AnimMontage(动画剪辑:蒙太奇)


    Overview(综述

    AnimMontages (or just Montages for short) are a multipurpose tool that allows for a wide variety of animation effects, primarily related to exposing animation controls within code or Blueprint. It can also be used to create a wide variety of animation effects including intelligent loops of animation, logic-based animation switching, root motion handling, and much more.

    动画剪辑系统(简称Montage)是一种通用的工具,他可以将多种动画效果(Animation)传递给那些用代码或者蓝图所实现的动画控制器。他也可以被用来创建诸如动画的智能循环,基于逻辑的动画转换,根节点运动处理等等各种各样的动画(Animation)。(注:Montage即蒙太奇,法语是“剪接”的意思。现在普遍指一种表现电影的拍摄手法,表示对电影镜头的组合运用)

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------

    AnimMontages are animation assets that can be created and exist within the Content Browser. These assets can then be plugged directly into the AnimGraph in run-time and you can modify any state of it. For example, you can jump to different sections or you can re-link different sections. This is mostly for code driven animations or one-off animations such as melee attacks, allowing you to control triggers, stop when you want, or change state (looping or non-looping) between (see the image below).

    动画剪辑是一个动画集合,可以在内容浏览器被创建并保存。这些集合可以实时的直接插入到*动画编辑图AnimGraph 中并且你可以任意的修改他的状态。例如,你可以切换不同的动画部分并且重新链接他们。动画剪辑大量应用于代码控制的动画或者一次性的动画。例如,格斗攻击动画,需要你来控制触发器,按照你的意愿随时停止或者改变状态(是否循环)。(参考下面的图片)

    Montage_Screen2.png

    The image above is a melee attack with 3 sections [start, loop, and end]. When the player left-clicks, it triggers the start section by default when you ask to play the montage. Now the middle section is set to loop. When the start is done, it will transition to loop, and will loop there forever. If the player lets the mouse button go, it will stop, but you do not want to stop right away since the animation will pop in the middle of the loop. You would like to relink the loop to the end, where it will then transition out to the end and finish the animation.

    上面的图片展示了一个拥有三部分的攻击动画 [开始,循环,结束]。当玩家点击鼠标左键时,就会在你调用动画剪辑 的时候默认触发开始的动画部分。现在我们看到中间部分是被设置为循环的。当开始动画播放结束后,就会过度到中间的循环部分并一直循环下去。如果玩家释放了鼠标左键,循环就会停止。但是你应该不想让动画在播放到一半的时候就突然中断。你可能更想让循环部分播放后再链接到结束动画部分,这样就可以让中间部分渐渐的淡入结尾部分并完成整套动作的播放。(注:这样看起来效果更好)

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Some additional uses for Montages include:

    • The ability to play an animation from within an AnimBlueprint's EventGraph.

    • Chaining together a complex sequence of animations that you want to think of as a single animation.

    • Looping only a specific portion of animation or animations based on code or Blueprint script.

    • Handling event-based switching of multiple animations based on code or Blueprint script.

    • Proper handling of Root Motion for your characters.

    • The ability to assign complex animation sequences to named slots that can be switched between in code or Blueprints.

    • Precise switching between various AnimSequences based on code or Blueprint script.

    一些针对动画剪辑的其他用法:

    • 可以使用蓝图的事件图(EventGraph)来控制播放动画

    • 把多个不同的动画序列链接成一个单独的动画

    • 通过蓝图或代码,局部的循环播放一个或多个动画的特定部分

    • 通过蓝图或代码,处理基于事件的多种复杂动画的切换

    • 恰当的处理“操作对象”的根节点动作

    • 把复杂的动画序列分配给不同的被命名的插槽(注:理解为序列中的任意位置都可以定义一个插槽)

    • 通过蓝图或代码,精确的把不同的动画序列连接到一起

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------

    So, as you can see, there are a lot of different things you can do with Montages. This can easily make Montages seem overwhelming as a system. However, if you really boil it down, the key point of Montages is to expose animation controls to code or Blueprints. Nearly everything else the system can do follows from that single point.

    An example of an Animation Montage applied to a character can also be seen on the Animation Content Examples page under section 1.5.

     所以,我们就会发现,在动画剪辑中我们可以自由地去做很多事情。这使动画剪辑理所当然的成为一个出色的系统。当然,如果非要去总结一下的话,动画剪辑系统就是把所有的动画展示给我们的代码和蓝图,从而让我们能自由的控制。就凭这一点,我们几乎就可以做出一切我们想要的效果。

         想尝试动画剪辑如何运用到角色身上的话也可以参考例子 Animation Content Examples 的1.5章节。
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    System Caveats(系统说明)

    There are a few details to keep in mind regarding AnimMontages:

    • Only one Montage can play back at a time. If you start playing a second one, it will stop the first.

    • At this time, root motion is replicated across the server. However the AnimMontage is not. That means that users utilizing root motion will need to make sure they are replicating the state of the AnimMontage across the network. (Position, play rate, etc.).

    关于动画剪辑系统有几点需要说明一下:

    • 同一时刻只能播放一个Montage(注:为了叙述简洁,后面一些地方直接使用英文)动画。如果你开启了另一个Montage动画,第一个就会停止。
    • 动画播放的一刻,根节点的动作将会被复制到服务器上,但是动画剪辑的内容不会被复制。这也就是说,用户执行根节点动作时需要确保动画剪辑的状态通过网络传输到服务器或者其他玩家客户端(如坐标,玩家状态等)。(注:如果客户端服务器状态不统一,会导致二者计算结果不同,游戏的效果也就不同)

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------

    Montage Properties(动画剪辑的特性)

    The following is a breakdown of the AnimMontage asset properties. These are available in Persona when looking at a Montage, and can also be accessed by right-clicking on a Montage within the Content Browser and choosing Properties from the context menu.

    下面图片是动画剪辑自身属性的分类展示。这些属性可以在打开角色视图(注:包括骨骼,Mesh,动作等文件)的动画剪辑中看到,当然你也可以在文件浏览器中通过右击一个动画剪辑文件并选择属性菜单来查看。

    MontageProperties.png

    Montage Properties(动画剪辑属性)

    Montage

    Blend In Time

    混合切入时间

    This is an amount of time at the beginning of Montage playback during which the character will blend in from its current pose.

    这是在Montage动画开始播放时,从当前动作状态过度到新动作所消耗的时间。(注:该时间为0,则没有过度;时间越大,新动作越不明显,当超过一定值时,几乎没有变化)

    Blend Out Time

    混合切出时间

    This is an amount of time at the end of Montage playback during which the character will blend back to its original pose.

    这是在Montage动画结束播放前,动作切换到原始状态所消耗的时间。

    Root Motion(根节点动作)

    Enable Root Motion Translation

    可以编辑根节点位移变换

    Enables handling of root motion translation, cancelling out any translation applied to the root so that it can then be applied back to the character's collision capsule. Please see 根骨骼运动 for more details.

    (勾选的话)可以编辑处理根节点的动作(位移)变换,(不勾选)取消任何对根节点的位移操作。这样就可以决定是否使人物使用角色本身的碰撞胶囊。想查看更多细节请参考根骨骼运动

    Enable Root Motion Rotation

    可以编辑根节点的旋转变换

    Enables handling of root motion rotation, cancelling out any rotation applied to the root so that it can then be applied back to the character's collision capsule. Please see 根骨骼运动 for more details.

    勾选的话可以编辑处理根节点的动作(角度)变换,(不勾选)取消任何对根节点的旋转操作。这样就可以决定是否使人物使用角色本身的碰撞胶囊。想查看更多细节请参考根骨骼运动

    Additive Settings(附加设置)

    Preview Base Pose

    预览基本动作

    Sets a base preview pose used for additive Blend Spaces.

    为附加的动作混合窗口设置一个基本动作的预览。(注:其实就是你这个Montage的一个动画预览,默认的为空显示的就是你编辑后的结果,所以一般不用设置)

    Animation(动画)

    Rate Scale

    比率

    A multiplier value for how fast the Montage will play back. Default is 1.0.

    一个因数值来表示Montage动画播放的速率,默认为1。

    Skeleton

    骨骼

    Contains the skeleton associated with this Montage. Cannot be changed in the editor

    .包含了和Montage动画相关的骨骼。在编辑器里面不能修改

    Montage UI(动画剪辑系统UI)

    When looking at a Montage in Persona, it is useful to know what each area is and what it does:

    当我们在角色窗口查看动画剪辑系统时,很有必要去知道每一块区域是做什么的:

    MontageUI.png

    1. Montage Area                剪辑Montage)区域

    2. Sections Area                片段(Section)区域

    3. Element Timing Area   元素时间(Element Timing)区域(当前中文文档也就是4.7版本以前没有该项)

    4. Notifies Area                  通知(Notifies)区域

    5. Curves Area                   曲线(Curves)区域


    Montage Area(剪辑区域)

    The Montage Area breaks down like so:

    动画剪辑区域分解示意图如下:(后面会解释为什么只有两个部分)

    MontageArea.png

    1. Section Track - Shows any Sections that have been defined for this Montage. Sections can be dragged to different positions along the timeline with the left mouse button.

    2. Slot Track - Shows the current Slot, along with the Slot name on the right. This Slot may be filled with as many animations as you desire; they will be played back in order. Notice that multiple animations will have alternating positions in the Slot Track - top, then bottom, then top again, and so on. This is to help you differentiate between different animations.

    3. Branch Point Track - Shows any Branch Points that have been defined for this Montage. Branch Points can be dragged to different positions along the timeline with the left mouse button.

    You may have as many Slot Tracks as you like within a single Montage, each with their own name and containing their own unique animations. However, you may only have one Section Track and one Branch Point track for each Montage.

    1. 片段轨道 - 显示所有为Montage动画所定义的动画片段。这些片段可以用鼠标左键拖到时间轴的任意位置上。
    2. 插槽轨道 - 显示当前的插槽并且在插槽右边显示其名称。这个插槽轨道可以按你的意愿插入任意数量的动画。他们会按照时间轴的顺序播放。需要注意不同的动画需要交替的出现在插槽轨迹上,就是按照第一个在上,第二个在下,第三个又在上的顺序交替。这会帮助你区分不同的动画片段。
    3. 分支点轨道 - 显示所有为Montage动画定义的分支点。分支点可以被鼠标左键拖到时间轴上的任意位置。(已经移至Notifier的一个属性选项里面)
                        你会有你所期望的任意数量的插槽轨道,每一个都有自己的名字并且包含自己特有的动画。但是,在一个Montage动画里面你只能拥有一个片段(section)轨道和一个分支点轨道。

    (注:这里很多朋友可能有疑问,因为我们根本找不到Branch Point Track这个轨道。我在4.8.3版本里面就已经没有这个轨道了,而在比较早的版本(可能是4.5以前)是有的。原因是中文的官方文档没有及时更新,而英文的版本已经去除了Branch Point Track轨道,但是Branch Point的功能仍然是有的,在添加Notifier时,这个消息的Event属性——Montage Tick Type里可以选择到Branch,所以想使用这个功能的朋友可以使用Notifies来代替,并改变这个属性。

    关于一般的Notifier与Branch的区别:Notifier是异步的,不能很及时的响应,想要在某一帧的上直接改变动作不能使用Notifier。这时候可以使用Branch来及时的响应。

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Sections(片段)

    Montage Sections provide a way to break a Slot up into multiple portions of animation. Each Section has a name and location in the Slot's timeline. Using the name, you can either jump directly to a particular Section or queue it to play next, when the current segment is complete. In Blueprint, you can query the current Section, jump to a Section, or set the next Section that will play.

    It may help to think of Sections like songs on a music playlist, with Slots being the albums. Just like with many modern media players, you can choose which song will play next when the current one finishes, or just jump to the one you want to hear right now.

    Sections are created by right-clicking on the Section track and choosing New Montage Section.

    Montage动画系统的片段轨道提供了一种可以打破正常 插槽播放顺序 的方式。每一个片段有一个名字并且处于插槽时间轴的一个位置。用这个名字,你可以在当前动画部分播放完成后直接跳到一个指定的片段或队列并接着播放。在蓝图中,你可以查询当前的片段,切换到任意一个片段,或是设置下一个需要播放的片段。

    让我们打个比方,片段就像一个音乐播放列表的歌曲一样,每一个插槽轨道就是一个专辑,里面有很多的现代流行歌手的歌。当一首歌结束时,你可以选择下一首播放什么或者直接跳到你想听的那一首歌来播放。

    点击鼠标右键在片段轨道上选择新建新的剪辑片段New Montage Section就可以创建一个片段了

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Slots(插槽)

    Within a Montage, a Slot is just a single track that can hold any number of animations. You can name this Slot, and then blend to those specific animations by calling the Slot name. A great example is having a character with a weapon reload animation. You may have different versions of the reload for when the player is standing, crouching, and lying prone. So long as all 3 of the animations used the same timing, you could place each one within a separate Slot in your Montage; the Slots could be named StandingCrouching, and Prone. In your Animation Blueprint's AnimGraph, you can use the Slot node to determine which one you want to play based on your character's current state. When they are standing, you can use the result of the animation in the Standing Slot. When they are prone, you can see the result of the ProneSlot.

    It is an important point to keep in mind that although much of your Montage control will take place in the Animation Blueprint's Event Graph, Slots are actually handled within the Anim Graph. This is done by way of the Slot node, which simply takes in the name for a Slot. By positioning this node at a strategic point along your AnimGraph's execution, you can have multiple Montages that utilize the same Slot name.

    在动画剪辑中,插槽就是一条可以容纳无数动画的存储轨道。你可以命名每个插槽轨道,并且通过轨道的名称来调用之前选定的融合到一起的动画序列。举一个合适的例子,假设你有一个角色需要执行为武器重装弹药的动画。同一个动作可能会有很多不同的版本,比如在站立时,蹲着时,匍匐时都有所差别。只要三个动画用同样的使用同样长度的时间,你就可以在Montage系统里把他们分别放在单独的插槽轨道里。这几个轨道可以分别命名为站立,蹲下,匍匐。然后在你的动画蓝图的角色状态图(AnimGraph)中,你可以根据你人物角色的当前状态决定使用你的插槽轨道。当角色站立时,就可以使用站立的插槽轨道。当他匍匐时,就可以使用匍匐插槽轨道来播放匍匐的更换弹药的动作。

    有一点很重要,我们要知道虽然大部分的Montage动画控制会在蓝图的事件图中进行,但是插槽部分却是被AnimGraph所控制的。这部分功能通过带有名字的插槽节点来控制实现。将一个插槽节点放在一个有战略意义的位置上来执行,你就可以利用相同的插槽节点创造出丰富的动画剪辑效果。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面的Branch Point在4.7以后的引擎中已经去除,所以这里不再翻译了

    Branch Points

    Branch Points allow you to create events that coincide with animation playback. These Branch Point Events can be used in code or Blueprint to cause other things to happen, but specifically, Branch Points are useful for switching to other animation Sections within a Montage.

    If you are already familiar with Animation Notifies, you may notice a strong similarity between the two systems, as they both expose events that can be leveraged in script. The key difference is that Notifies are asynchronous, while Branch Points are synchronous. What this means to the end user is that Branch Points come with a much higher degree of precision for where they will take place along the animation timeline.

    High precision is important when you need to jump to a specific animation at a very precise moment in time. While you could use a Notify to do the same job, the asynchronous nature of Notifies means that the Notify Event could be fired at the incorrect animation frame, which can lead to hitches and jumps in your motion.

    Due to their synchronous nature and the precision resulting from it, Branch Points are more performance expensive than Notifies. You should only use them when an event must be fired at a precise moment along the animation timeline, such as jumping directly to another animation that matches up frame-to-frame. If being off by a frame - or some percentage of one - is not important, you should use Notifies instead.

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Sections Area(片段区域)

    The Sections area is where you can establish relationships between the Sections you define in the Montage Area. For instance, you may want a certain Section of animation - or group of Sections - to play in a specific sequence, or even loop.

    在片段区域,你可以根据Montage系统区域定义不同的片段来创建不同的剪辑动画关系。例如,你可能需要一个特定的片段动画,或是一组动画来按顺序或者循环播放。

    SectionsArea.png

    1. Create Default and Clear Buttons - Create Default creates default associations between all Sections, stringing them together one after the other. Clear wipes out all associations.

    2. Section Buttons - In this area, you will see a button for each of the Sections you define in the Montage area. By choosing an existing Section and then clicking the one of these buttons, you associate the Section for that button with the selected track. For instance, in the image above, we have associated Swing2 with Swing1. The order actually goes Swing1Swing2, and then Swing1 again, which causes a loop. See the Looping section below for details.

    3. Section Association Tracks - This is where you can visualize and preview the relationships between animation Sections. By clicking on the Preview buttons, you can see the result of each individual track, or click the Preview All Sections button and see all Sections play back one after the other.


    1. 创建默认清除按钮 - 创建默认按钮创建按照所有片段的默认顺序接连的将各个动画片段排成一个序列。清除键则将他们完全分开,不在有任何联系。
    2. 片段按钮 - 这这个区域,你将会看到你在剪辑区域定义的所有片段。选择下面第3部分的一个轨道上存在的片度并接着点击区域2其中的一个按钮,你就可以把区域2的片段添加到下面的轨道上。例如,在上面的图片里,我们把Swing2连接到Swing1上。这个顺序就变成了Swing1,Swing2,Swing1,Swing2这样循环的播放下去。关于循环的细节,下面一段会继续阐述。
    3. 片段关系逻辑轨道 - 在这个区域,你可以看到并预览所有动画片段的执行关系。点击预览按钮,你就可以看到每个独立轨道的的播放效果。也点击预览所有,查看所有片段的循环播放。
       (注:暂时我的理解是,对于区域3的每一个section,只有第一条的轨道才是角色真正运行的动画序列。上面的Montage区域目的就是为了给每一个动作定义一个section从而可以在Section区域自由的控制Montage的播放顺序。)

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------


    Looping(循环)

    Sections can be set up to loop indefinitely, which is extremely useful for any action that you need to repeat. By associating the same Section more than once in a Section Association Track, you cause that association to run in a loop. The section will turn blue to show this. As an example, consider an animation in which a character is reloading a shotgun, one shell at a time. You could take just the section in which the character inserts a shell, and loop it. Then, by using Notifies, you could create Notify Events in Blueprint that increment the ammo count each time the animation plays through. Once that count reaches a set number (full ammo), you could then switch to an animation of the character closing the receiver and returning to idle.

    片段可以被设置为无限循环的播放,这无疑对你想要重复的动作是非常有用的。通过在轨道上把同一个片段添加两次,你就可以得到一个循环。如果进入循环状态,这个动画片段的颜色就会变成蓝色。举个例子,假设一个角色正在给枪或者炮弹装填弹药。你可以只选择这一动画部分插入到装弹的状态并且循环播放。之后,通过动画通知功能(下面有讲解),你可以在蓝图中创建响应信息的事件在每次装弹时增加这个弹药的数量并多次播放这个动作。一旦弹药到达一定数量(满弹药),你就能停止接收消息切换到平时的待机状态。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------


    Notifies Area(动画通知区域)

    NotifiesArea.png

    动画通知(简称AnimNotifies或通知)使得动画相关的程序员可以设置在动画序列的特定点处发生的事件。通知通常用于这样的特效,比如走动时的脚步声、跑动动画或在动画中产生一个粒子特效。然而,它有很多种不同的用途,因为您可以使用自定义的通知类型来扩展该系统,从而满足任何类型游戏的需求。

    For more information, see 动画通知 (通知).

    Curves Area

    CurvesArea.png

    曲线提供了在动画正在播放过程中改变材质参数或顶点变形目标的方法。 其工作流程非常简单,只需要您简单地指定您要修改的资源(一个材质或顶点变形目标),相应地命名该曲线,然后调整动画播放期间的关键帧的值。

    For more information, see 动画曲线.


    Montage Practical Example(动画剪辑系统使用实例)

    In this example, we want to have a character that can freely run in all directions, with an attack animation that only plays on the upper body. This attack will have multiple animations that could take place during its course. This is a perfect way to show the assembly of a Montage, as well as how to control it in the Event Graph and blend into it within the AnimGraph.

    在这个例子中,我们想创建一个可以向各个方向自由移动的角色,这个角色还可以在上半身播放一个攻击的动画。这个攻击动作包含多个可以在执行过程中播放的动画。这是一个能非常完美地展现Montage动画系统功能的方式,同时也可以展示如何在事件图控制它,以及如何在AnimGraph中将Montage与其他动画混合播放。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------


    However, there are few things we have set up in advance:

    • We already have a State Machine defining locomotion. This is just like the one used in the Third Person Project Template.

    • We have several animations provided by an artist that we would like to string together to make the Montage.

    • We have created a Character Blueprint Class that we can get input information from.

      • For this example: an IsAttacking Boolean that is set to TRUE when the Left Mouse Button is pressed and set to FALSE when it is  released.

    不过,在开始之前我们要提前做好几点准备工作:

    • 已经建立了一个行动的状态机。这个状态机与第三人称游戏模板工程的状态机一样。
    • 已经有了美术人士提供的相关的可以加入Montage系统的动画素材。(注:UE4一般使用FBX文件)
    • 已经创建了角色蓝图来接收输入信息。 
                  ○ 例如:创建一个名为是否攻击(ISAttacking)的布尔变量,当点击鼠标左键时设置为哦true,松开时设置为false。


    CharacterBlueprint.png

    Creating the Montage(创建动画剪辑)

    Making a Montage is as easy as right-clicking in the Content Browser and choosing Animation > Animation Montage. You can also right-click on an existing Animation Sequence and choose Create Montage from the context menu. This will automatically create a new Montage with the selected AnimSequence already set up in the default Slot.

    创建一个Montage动画系统很容易。只要在内容浏览器右键鼠标选择 动画->动画剪辑Animation > Animation Montage)就创建成功了。你也可以在内容菜单里一个存在的动画序列上右键鼠标并选择创建Montage动画剪辑(Create Montage。这样就会以这个动画作为默认的动画插槽创建一个新的Montage动画剪辑。

    MakeMontage.png

    Montage Setup(动画剪辑的创建)

    Our first order of business was to name our Slot. We only need one in this Montage, and since we want our attack to only affect the upper body, the name Upper Body seemed perfect. We then drag/dropped the animations we would need into this slot. The animations we have do the following:

    • Right-to-left hammer swing

    • Left-to-right hammer swing

    • Go from the end of the right-to-left swing back to Idle

    • Go from the end of the left-to-right swing back to Idle

    The two swinging animations both end on the same pose as the other begins. This means that the two animations can play back to back in a loop and the character will seamlessly swing the hammer back and forth.

    While order is not extremely important, having the first two animations at the beginning and back to back will simplify things later.


    我们第一件要做的事情就是给插槽(Slot)命名。在一个动画剪辑中,一般只需要有一个插槽,而且既然我们想让这个Montage只影响角色的上半身,不妨就把这个插槽命名为UpperBody吧。之后,把我们需要的动画拖到这个插槽里面。需要的动画有下面4个:

    • 从右向左挥动锤子
    • 从左向右挥动锤子
    • 从右向左挥动锤子结束动作(衔接到待机状态)

    • 从左向右挥动锤子结束动作(衔接到待机状态)

           这两个挥动的动画会在一个结束时播放另一个。这就意味着这两个动画可以循环交替的播放下去,看起来就行角色在不停的反复进行 挥动锤子

    其实顺序并不是很重要,不过使前两个动画在序列的开始并挨在一起就会让后面的操作简单不少。

    MontageSetup.png

    Section Creation(片段创建)

    Our next step is to section out the animations in our Montage so that we can query them and call them up when needed in our Blueprint code. This is as easy as right-clicking and choosing Add New Montage Section while clicking on the Section Track at the top of the Montage Area.

    We used fairly straightforward names for each Section. Note that we replaced the Default section that came along with the Montage (made a new one and deleted the Default by right-clicking and choosing Delete Montage Section). You can drag these Sections along the Section Track if you need to, and you will notice that they snap a bit at the boundary between two animation segments when you release the mouse. Use this to your advantage.

    下一步操作就是给每个动画制作片段,这样我们在蓝图或代码中就可以方便的查询与使用他们。步骤也很简单,在片段那条轨道上(Montage区域的最上面)右键鼠标选择添加Montage片段(Add New Montage Section)。

    我们直接给每个片段命名。注意要把之前创建Montage的默认片段给替换掉。(创建一个新的片段并且右击默认片段选择删除片段)你可以在轨道上随意的拖动这些片段而且如果你在两个动画衔的接位置松开,他们会自动对其。好好利用这点。

    AddNewSections.png

    Defining Section Relationships(给片段确定关系)

    Now that our Sections are created, we can now define any special relationships between them using the Sections Area. For instance, we can define a relationship between the Swing1 and Swing2 sections so that they play back to back in a loop. This is very useful for us. We start by clicking the Clear button to wipe out any default relationships. Then it is just a matter of selecting the track with Swing1 in it, and clicking the green button labeled Swing2 near the top of the Sections Area. This will remove the Swing2 track and add Swing2 to the Swing1 track.

    一旦我们的片段都已经创建好了,我们就可以在片段区域给他们随意的定义关系。比如,我们可以定义一个联系让Swing1和Swing2循环交替的播放。这对我们来说非常有用。点击清除按钮可以擦除我们定义的任何关系。操作很简单,就是在轨道上点击Swing1,然后在片段顶部区域点击绿色的Swing2按钮。这样就会把Swing2轨道移除,并把Swing2片段移动到Swing1轨道的后面。

    Swing2Track.png

    If we repeat the process, clicking the new Swing2 segment and then clicking the Swing1 button, the system detects that you are creating a loop and the track turns blue. This means that the Swing1 and Swing2 segments are considered a looping Section. They will play back to back, repeating indefinitely.

    如果想重复某一个动作,点击第一个轨道上刚刚创建的Swing2片段然后在点击区域上方的Swing1按钮,系统就会认为你正在创建一个循环,并且这个循环的片段部分就会变成蓝色。这就意味着Swing1和Swing2片段想成为一个循环。他们就会一直的重复播放下去。

    LoopingTracks.png

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------

    下面的Branch Point在4.7以后的引擎中已经去除,所以这里不再翻译了

    Setting Up Branch Points

    We will now set up some Branch Points to test whether to continue with the loop or jump to one of two possible endings for our attack animation. All we have to do is right-click in the Branch Point Track and choose New Branch Point. We chose the names Swing_1_Endand Swing_2_End for our Branch Points. We also zoomed very closely in with the mouse wheel to make sure that each one fires right at the last possible moment of its corresponding section. This means it is placed very slightly to the left of the border between the two.

    BranchPointsSetUp.png

    A similar system could be set up in which you use Notifies instead of Branch Points, but they would need to fire a little earlier along the timeline, and your Animation Blueprint Event Graph would be queuing the appropriate ending animation using the Montage Set Next Section node, rather than doing a direct switch with the Montage Jump to Section node, as we will be doing. Doing it with Notifies would be slightly cheaper on performance, as Notifies are asynchronous. Our example is academic, but we wanted to make sure to mention the other method, as well.

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------


    Setting Up the AnimGraph(设置动画图)

    At this point, our Montage is all set up. We now need to establish our AnimGraph so that it can read in the result of our Montage. This is a pretty simple process, but it does cause us to have to think carefully about how we proceed. Our AnimGraph starts off looking something like this, where we are only seeing the result of our State Machine:

    现在,我们的Montage动画已经建立好了。我们接下来需要创建我们动画图(AnimGraph)好让他去把Montage动画融入到我们的这个人物的动作里。这一步很简单,但是他会提醒我们去仔细思考一下我们的流程是什么样的。动画图一开始的效果是下图所示的样子,我们只能看到状态机所展示的结果。

    StateMachineResult.png

    We only want the Montage to play back from the Spine_01 bone (the waist) up, so we will be using a Layered Blend per Bone node. We add a Blend Pose to it set the weight to 1. We also associate this Blend Pose with Spine_01 in the properties for the node. We then bring in a Slot node and set it to UpperBody, the name of our slot. But now we run into a problem:

    因为我们现在只想Montage动画从Spine_01骨骼(腰部)开始播放,所以需要一个名为 骨骼层混合(Layered Blend per Bone) 的节点。给混合动作0(Blend Pose 0)设置比重为1。同时我们也把混合动作设置绑定到Spine_01骨骼上。之后引入一个插槽节点并设置为UpperBody(我们之前所命名的Slot)。然而,你会发现,现在出现了一个问题:

    SlotAndBlend.png

    The Slot node needs a Source connection to fall back on once the Montage is done playing. Without it, the character will return to the T-pose from the waist up after the Montage completes. However, we cannot connect the State Machine to both the Base Pose of the Layered Blend per Bone as well as the Source for the Slot node. The solution? Use a Cache node! We can store the result of the State Machine into a Cache node, and then create Cached Pose nodes to connect to both our required inputs. This is somewhat similar to storing the result of the State Machine into a variable so you can use it in multiple places. For this example, we named the Cache LocoCache.

    一旦Montage动画执行完成,这个插槽节点需要一个动作来源来恢复之前的动作。没有这个动作来源,角色在Montage动画执行完毕后就会回到最开始的T型姿态的样子(注:就是模型最原始的无任何动作的状态)。然而,我们不能把状态机的节点同时链接到插槽节点(Slot)骨骼层混合节点(Layered Blend per Bone。那么如何解决这个问题呢?答案是使用一个缓存节点Cache )。我们可以暂时把状态机的结果存储为一个变量,这样你就可以在各个地方重复的使用了。举例来说,我们把这个节点命名为动作缓存LocoCache),按照下图的样子使用。

    CachedLocomotion.png

    Our AnimGraph is done. As soon as the UpperBody Slot node receives data from any AnimMontage (you can use any Montage, so long as it has a Slot named UpperBody), it will blend it in. As soon as it is no longer receiving data, it will fall back on the result of the State Machine.

    现在我们的动画图已经完成了。一旦UpperBody插槽节点收到了Montage动画发送的任何消息(你可以使用任何你创建的Montage,只要他有一个叫做UpperBody的插槽就可以),他就会执行混合动画。如果停止接收消息,角色就会恢复状态机里的动画状态。

    -------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Setting Up the Event Graph(设置事件图)

    Our Event Graph setup is very basic. Using the Event Blueprint Update Animation node and dragging off the out pin of a Get Player Character node, we can Cast To our Character Blueprint (MyCharacter in this example) to access the variables and functions from that Blueprint (see Blueprint Communications for more info on communicating between Blueprints).

    事件图的设置非常重要。使用蓝图动画更新事件(Event Blueprint Update Animation) 节点作为开始并创建一个获取玩家角色(Get Player Character的节点,我们就可以把角色蓝图强制转换为我们自定义的角色(这里我们定义的角色名为MyCharacter)同时获取角色里面定义的变量和方法(想获取更多关于蓝图交互的信息请看Blueprint Communications章节)。

    The first thing we do is check if the IsAttacking variable from our Character Blueprint is TRUE and if it is, we then check if the Montage is already playing. If the Montage is playing, we do not want to play it again; however if it is not playing, then we play the Montage. This prevents the system from restarting the animation in the middle of playback, which would look bad.

    Dragging off the IsAttacking node which extends from the Cast To node, we see if the mouse button is still down, and if not, we jump to the appropriate ending animation, depending on which half of the loop is playing. Creating the Branch Point Events is done by right-clickingand choosing the appropriate event under Add Montage Branching Point Event.

    我们要做的第一件事接收检查一下我们角色蓝图中的IsAttacking变量是否是正确的,如果是true的话再检查一下Montage动画是否正在播放。如果是,就不需要再去播放一遍;如果没有在播放,那么就让他去播放。这样可以防止动画从Montage播放到一半的时候直接切换到开头并再次播放动画。

    EndLoopEventGraph.png

    And that is it! If we compile, we will now see that the character continues to swing as long as the mouse button is down, and performs an intelligent end animation when the mouse button is released!

    那么一切都已经搞定了。如果我们开始编译,我们就会看到角色随着鼠标按钮的按下不断的挥舞着他的锤子并且在鼠标按钮放下时播放结束动画作为衔接!


    展开全文
  • Google翻译接口调用

    千次阅读 2019-09-05 16:22:16
    最近有个需求要批量调用Google翻译进行翻译...要是能调用的接口就好了,但接口是收费的。。。没办法,哎,只能自己搞,看看能不能破解。看了下Google翻译的接口, 对浏览器右键检查,可用发现翻译是有接口的: ...
  • JMeter翻译日志

    千次阅读 2007-03-10 22:01:00
    ,所以比较忙就没有太多时间去翻译,但是我会继续这个工程,最近感谢我好友阿杜的帮助,开始和我一起翻译,第五章就是的成果,我们准备在两个月内完成这个工程,也希望有兴趣的朋友也可以加入,一是为了一同学习...
  • 用Python做一个翻译软件

    千次阅读 2019-01-28 18:07:49
    前两天吃了平哥的一波狗粮,给女朋友写了一个翻译软件,自己真真切切的感受到了程序员的浪漫。在学习requests请求的时候做过类似的Demo,给百度翻译发送一个post请求可以实现任意词组的翻译,利用周六周日将那段...
  • 译者雪茗是我的一位朋友,看到她翻译的这个教程后,我觉得非常不错。 译者:Snowming(雪茗) 时间:北京时间 2019-03-17 本书英文名:The Hacker Playbook 3 阅读及 PDF 下载 在 Github 上阅读本书 PDF ...
  • GitChat 作者:魏勇鹏 关注微信公众号:GitChat 技术杂谈 ,一本正经的讲技术 ...6月27日下午,一个同传译员在朋友圈里爆料:某AI公司请这位译员去“扮演”机器同传,制造人工智能取代人工同传的“震撼”效果。
  • //编者按:郭新明是张孝祥老师最好的朋友,这是从美国发来的纪念文章。   (0) 网上曾经看到过一次"超过两条就是一辈子朋友"的帖子,我笑笑就过了---- "睡在过同一张床;穿过一样的衣服;互穿过对方的衣服;...
  • 程序员们,你们再这样下去会没朋友的。

    万次阅读 多人点赞 2017-05-01 23:01:08
     当时给LZ发了一张图片,然后问LZ,“这个@Test注解引用不了是咋回事?” 看到这个问题,LZ当时恰好没事,就顺手给回复了一下,说这个错误引起的原因是,注解的特性只在JDK1.5或者更高的版本才能用。 话虽...
  • 授权自AI科技大本营(ID: rgznai100)翻译: shawn本文共1W+字,建议阅读10+分钟。美国学者侯世达以自己亲身体验Google翻译的经历指出,机器翻译目前没有思想,很难替代人类。[ 导读 ] 尽管机器翻译明显玩不转备受期待...
  • 导语 ​ I love three things in this world ,sun for morning ,moon for night ,and you forever! 浮世万千,挚爱有三,喷薄朝阳,皓婉皎月,不及汝尔,沧海桑田。... —— 翻译自《暮光之城》 ​​ ​ ...
  • UE4这篇官方文档大体上讲解了UE4本身的诸多特性以及如何编写基本的C++代码,对理解UE4的编程基础内容非常有帮助,还是因为没有对于的汉语翻译。所以,这里我把这篇文档翻译出来,之后还会简洁的对其进行必要的总结。...
  • ZooKeeper官方文档-Java客户端开发例子翻译

    千次阅读 多人点赞 2018-10-22 17:40:00
    官网原文标题《ZooKeeper Java Example》 ... 译者:网上有很多ZooKeeper的java客户端例子,我也看过很多,不过大部分写的都不好,有各种问题。兜兜转转还是觉得官方给的例子最为经典,在学习之余翻译下来,...
  • <追忆张孝祥> 郭新明:一辈子的朋友(修订版)

    万次阅读 热门讨论 2012-01-03 20:19:01
    郭新明:一辈子的朋友//编者按:郭新明是张孝祥老师早期创业的合作伙伴和长期的老朋友,这是从美国发来的纪念文章。 (0)网上曾经看到过一次“超过两条就是一辈子朋友”的帖子,我笑笑就过了——“睡在过同一张床...
  • 项目上线后中英文翻译问题解决

    万次阅读 2020-02-24 17:03:15
    笔者目前是遇到俩种情况,分别都进行了对应的解决,如果你遇到了其他的关于浏览器对你项目进行翻译导致的问题的话可以在下方评论。笔者会第一时间和你一起解决。 问题一:谷歌浏览器自动会帮客户翻译英文网站 解决...
  • 很难想象哪个学习计算机技术的人是没看过这方面书籍的,如果只是在网上看看技术贴,...但是网上吐槽翻译”质量太差,语句颠三倒四,晦涩不通“的声音此起彼伏。结合我个人经验,谈谈好的技术译作应该具有什么样的标准。
  • unity插件开发让女朋友财富自由之路

    千次阅读 2019-03-03 11:03:05
    公司也快不行了,经济困难,在踌躇之际看到一个帖子,说做的特效插件被日本大公司买了,有很好的广告效应,收入比自己年薪还多,印象中大概在70w左右(现在再去找发现没找到那个帖子),突发奇想能不能将自己这一...
  • 大学英语综合教程三 Unit 6 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • 大学英语综合教程三 Unit 5 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • Android 百度翻译API(详细步骤+源码)

    千次阅读 多人点赞 2020-11-26 17:33:01
    百度翻译API一、创建平台应用二、创建及配置项目三、编码1. 修改外观与布局2. 初始化控件3. 输入框监听4. 语言选择监听5. 页面点击事件6. 翻译 一、创建平台应用   百度翻译开放平台也是属于百度智能云的一部分,...
  • 大学英语综合教程二 Unit 4 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • 大学英语综合教程三 Unit 1至Unit 8课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼...
  • 大学英语综合教程二 Unit 2 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • 大学英语综合教程一 Unit 2 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • 大学英语综合教程三 Unit 3 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • 大学英语综合教程一 Unit 8 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...
  • 大学英语综合教程一 Unit 4 课文内容英译中 中英翻译   大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博客地址为:亓官劼的博客 本文原创为亓官劼,请...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 64,020
精华内容 25,608
关键字:

他朋友翻译