UE4中自定义用于sequence的变量和函数

UE4中自定义用于sequence的变量和函数

https://zhuanlan.zhihu.com/p/136962130

ue4进化了sequence这个系统,每个版本都在进化,使得这个工具越来越好用,好用到我们甚至我们在做游戏的时候,任意的过场都可以拿他来制作,可以说是美术的利器。

绝大部分美术在短时间内就能学会ue4的sequence并用它做出绚烂的画面,但是,这只限制与一般的单机游戏的过场,如果我们希望把它做成游戏里的事件的过场,比如触发事件后的表现,就有不少欠缺了。最主要的是,因为角色在游戏中会有换装,会有不同的装备和武器,会有不是纯美术就可以控制的逻辑。

再比如说,我们拿ue做一个2d游戏,2d系统的flipbook是没有动画状态机的,那么再sequence里改变角色的方向的动画,以及改变角色的动作就不是内置的那几个trace就可以解决的了。

所以我们必须要自己定义一些函数和变量方便sequence里的动画变现,用数据和逻辑去驱动部分的动画。

向sequence里添加变量方式很多,目前就列举下我所常用的几种方式。

1.在蓝图里定义变量,并把它暴露给sequence。

选择旁边的Expose to Cinematics

2.第二个办法稍微麻烦点,在构建变量的同时等于构建了函数

先定义变量

然后定义一个Set+变量名的函数

这个时候我们打开sequence,导入定义了变量的函数,我们可以看到这两个变量都出现在sequence的trace里了

3.但是这些都是基于蓝图的,对我们程序实际控制起来有点麻烦,所以还有个方式是基于c++的,假定,我们定义了两个枚举类型,一个控制移动方向,一个控制动画动作。

我们只需要在uproperty里添加interp标识即可.

这个时候,我们可以看到sequence里多了两个自定义的枚举类型,以方便我们在不同的帧里切换不同的状态,至于切换了状态之后的处理,自然是有代码内部判断即可。

 

另外呢,ue4的sequence里访问自定义的函数就很简单了,两种方法.

1.在蓝图里,我们设置一个custom event。

2.或者我们在c++随便定义个函数,让它向蓝图暴露.

然后在sequence里打开这个对象,建立event的 trace,我们都可以在这个trace的任意帧绑定这个事件或者函数,方便在特定的时间里触发。

需要说明下的是,这个函数或者事件,在4.22和4.23的时候是不可以带参数的,到了4.24的时候又可以携带参数了.

 

下面就是我简单只利用了变量和函数,让没有状态机和动画概念的flipbook实现了事件的过场动画.

 

 

另外还有一点,如果你希望在sequence里精确的触发某一帧的状态改变,或者某个状态的精确变化,比如一个触发状态,希望它下一帧就改变回来,那么这个勾选是必须的,不然它基于时间改变的状态,可能让你会触发多次。

大致就这些。

发布于 04-28

 

 

 

 

 

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一般来说,m_sequencer不会同时作为sequencesequence item的成员变量,因为它们是不同的类别。一般情况下,sequencesequence item是在SystemVerilog Testbench使用的,用于驱动和监测DUT。下面是一个示例代码,其包含sequencesequence item,并且它们都有自己的成员变量: ``` class my_sequence extends uvm_sequence #(my_sequence_item); rand int data; my_sequence_item seq_item; function new(string name = "my_sequence"); super.new(name); endfunction virtual task body(); // Generate sequence items repeat(10) begin seq_item = my_sequence_item::type_id::create("seq_item"); seq_item.data = $urandom_range(0, 10); seq_item.addr = $urandom_range(0, 1024); seq_item.size = 4; `uvm_info("my_sequence", $sformatf("Sequence item generated: addr=%0d, data=%0d", seq_item.addr, seq_item.data), UVM_MEDIUM) // Send sequence item to driver seq_item.randomize(); seq_item.set_starting_phase(get_starting_phase()); seq_item.set_parent_sequence(this); if(!seq_item.randomize()) `uvm_error("my_sequence", "Failed to randomize sequence item") if(!seq_item.send_request()) `uvm_error("my_sequence", "Failed to send sequence item") // Wait for response from DUT if(!seq_item.grab_response()) `uvm_error("my_sequence", "Failed to grab response for sequence item") end endtask endclass class my_sequence_item extends uvm_sequence_item; rand int data; int addr; int size; `uvm_object_utils(my_sequence_item) function new(string name = "my_sequence_item"); super.new(name); endfunction function void do_print (uvm_printer printer); super.do_print(printer); printer.print_field("data", data, $bits(data), UVM_HEX); printer.print_field("addr", addr, $bits(addr), UVM_HEX); printer.print_field("size", size, $bits(size), UVM_DEC); endfunction endclass ``` 在这个示例代码,my_sequence类表示一个sequence,my_sequence_item类表示一个sequence item。它们都有自己的成员变量,例如my_sequence的data和seq_item,以及my_sequence_item类的data、addr和size。没有一个名为m_sequencer的成员变量,因为它们都是在uvm_sequence和uvm_sequence_item的基础上定义的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值