使用功能

From Valve Developer Community
< Zh
Revision as of 05:33, 29 June 2025 by WoShiGeNiCheng (talk | contribs) (Created page with "{{LanguageBar|Use|title=使用功能}} {{TabsBar|main=gs|base=Use}} {{toc-right}} 所有实体都有一个<code>Use</code>{{L|input|输入}},尽管许多实体对此不做响应。任何实体都可以设置自定义使用功能(参见{{↓|Programming}}),如果没有自定义功能则默认行为是将使用操作转发给实体的{{L|parent|父级}}。通常,使用功能执行玩家与实体交互时期望的操作(例如开门/关门、拾取物理对象)。有...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
English (en)中文 (zh)Translate (Translate)

所有实体都有一个Use输入(en),尽管许多实体对此不做响应。任何实体都可以设置自定义使用功能(参见Programming ↓),如果没有自定义功能则默认行为是将使用操作转发给实体的父级(en)。通常,使用功能执行玩家与实体交互时期望的操作(例如开门/关门、拾取物理对象)。有几种调用方式:

1. 玩家看向实体并执行+use控制台命令(通常绑定到E键) 2. 实体输出(en)指定Use输入,或不指定任何输入 3. firetarget作弊(en)命令(直接调用_Use方法_,类型为USE_TOGGLE) 4. 在代码中直接调用C++函数

控制台变量

控制台变量/命令 参数或默认值 描述符 效果
sv_debug_player_use 0 bool 可视化+use逻辑。绿色十字=追踪成功,红色十字=距离过远,绿色方框=半径范围内成功

玩家使用逻辑

([待完善] 总体描述) 由玩家实体的PlayerUse方法定义。[1] 可能被覆盖:

编程实现

虽然始终存在Use输入[5]和_Use方法_[6](作为CBaseEntity的一部分),但实际的_Use函数_初始为null。此处的_Use函数_指m_pfnUse字段设置的函数,可通过SetUse( void *SomeFunc(CBaseEntity(en) *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float(en) value) )随时分配。_Use函数_还必须在实体的数据描述(en)中使用DEFINE_USEFUNC(en)( our_func )定义。

Note.png注意:func_button等实体使用DEFINE_FUNCTION将_Use函数_指针放入数据描述。虽然没有实质区别,但使用DEFINE_USEFUNC更规范。

CBaseEntity::Use方法仅检查是否设置了_Use函数_(即m_pfnUse非null),如果设置了则调用;否则如果有父级则调用父级的_Use方法_。许多实体通常重写_Use方法_而非设置_Use函数_。设置_Use函数_的优势在于可以动态更改为不同函数,例如响应输入时。

使用类型

定义于shareddefs.h

typedef enum
{
	USE_OFF = 0, 
	USE_ON = 1, 
	USE_SET = 2, //表示我们传递了一个值
	USE_TOGGLE = 3
} USE_TYPE;

I/O中的使用类型

在映射时无法通过I/O系统指定USE_TYPEvalue。 Use输入使用outputID属性指定USE_TYPE。这意味着只能通过在代码中将AcceptInput或AddEvent函数的outputID参数设为所需USE_TYPE来指定。玩家执行使用操作时[7]如此设置,USE_TYPE基于实体的ObjectCaps(en)

outputID参数作为USE_TYPE也导致以下行为:

  • ent_fire将outputID设为0,意味着通过它触发的use始终为USE_OFF类型
  • 当前游戏会话中第一个加载的输出(具有outputID 1)触发的use输入为USE_ON,第二个为USE_SET,第三个为USE_TOGGLE,其余通常被解释为USE_TOGGLE
  • firetarget直接以USE_TOGGLE类型调用Use函数
PlacementTip.png示例:
观察此行为的示例

创建仅含npc_grenade_frag的地图,设置4个输出OnUser1-4 !self,Use。假设这是地图中仅有的输出且是当前游戏会话加载的第一个地图,则当使用FireUser1-4时其中一个能拾取手榴弹而其他不能。(很可能是FireUser3能拾取,激活者必须是玩家才能拾取) 这是因为其中一个输出的id为3,对应USE_TYPE为USE_TOGGLE,而CBaseGrenade::Use方法检查此类型以拾取手榴弹。Ent_fire_不能_拾取手榴弹而firetarget可以。