Skip to content

🦾 角色动画集合

tongsim.entity.action

LookAtLocation dataclass

Bases: ActionBase

动作: 注视指定位置或取消注释指定位置

Attributes:

Name Type Description
loc Vector3

注视的目标位置。

is_cancel float

注视或取消注视,默认为False。

execute_immediately bool

是否立即执行,默认为False

Source code in src\tongsim\entity\action\impl\aim.py
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
@dataclass(slots=True)
class LookAtLocation(ActionBase):
    """
    动作: 注视指定位置或取消注释指定位置

    Attributes:
        loc (Vector3): 注视的目标位置。
        is_cancel (float): 注视或取消注视,默认为False。
        execute_immediately (bool): 是否立即执行,默认为False
    """

    loc: Vector3
    is_cancel: bool = False
    execute_immediately: bool = False

    def validate(self) -> None:
        if not isinstance(self.loc, Vector3):
            raise TypeError(f"loc must be a Vector3, got {type(self.loc)}")

        if not isinstance(self.is_cancel, bool):
            raise ValueError(f"is_cancel must be a bool, got {type(self.is_cancel)}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.look_at_location(
                loc=self.loc,
                is_cancel=self.is_cancel,
                execute_immediately=self.execute_immediately,
            )
        )

LookAtLocationWithDuration dataclass

Bases: ActionBase

动作: 注视指定位置,并保持指定时长后取消注视。

Attributes:

Name Type Description
loc Vector3

注视的目标位置。

time_duration float

注视保持的时长(秒)。若为 0 则立即取消注视。

Source code in src\tongsim\entity\action\impl\aim.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
@dataclass(slots=True)
class LookAtLocationWithDuration(ActionBase):
    """
    动作: 注视指定位置,并保持指定时长后取消注视。

    Attributes:
        loc (Vector3): 注视的目标位置。
        time_duration (float): 注视保持的时长(秒)。若为 0 则立即取消注视。
    """

    loc: Vector3
    time_duration: float

    def validate(self) -> None:
        if not isinstance(self.loc, Vector3):
            raise TypeError(f"loc must be a Vector3, got {type(self.loc)}")

        if not isinstance(self.time_duration, int | float) or self.time_duration < 0:
            raise ValueError("time_duration must be a non-negative number.")

    async def execute(self) -> None:
        # 开始注视
        await self.submit(
            AnimCmd.look_at_location(
                loc=self.loc,
                is_cancel=False,
            )
        )

        # 保持指定时长
        if self.time_duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.time_duration))

        # 取消注视
        await self.submit(
            AnimCmd.look_at_location(
                loc=self.loc,
                is_cancel=True,
            )
        )

LookAtObject dataclass

Bases: ActionBase

动作: 注视指定实体或取消注视。

Attributes:

Name Type Description
object_id str

目标实体的 ID。

is_cancel bool

是否取消注视。默认为 False 表示执行注视。

Source code in src\tongsim\entity\action\impl\aim.py
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
@dataclass(slots=True)
class LookAtObject(ActionBase):
    """
    动作: 注视指定实体或取消注视。

    Attributes:
        object_id (str): 目标实体的 ID。
        is_cancel (bool): 是否取消注视。默认为 False 表示执行注视。
    """

    object_id: str
    is_cancel: bool = False
    execute_immediately: bool = False

    def validate(self) -> None:
        if not isinstance(self.object_id, str) or not self.object_id:
            raise ValueError("object_id must be a non-empty string.")
        if not isinstance(self.is_cancel, bool):
            raise ValueError("is_cancel must be a bool.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.look_at_object(
                object_id=self.object_id,
                is_cancel=self.is_cancel,
                execute_immediately=self.execute_immediately,
            )
        )

LookAtObjectWithDuration dataclass

Bases: ActionBase

动作: 注视指定实体并保持指定时长后取消。

Attributes:

Name Type Description
object_id str

目标实体的 ID。

time_duration float

注视保持的时长(秒)。若为 0 则立即取消。

Source code in src\tongsim\entity\action\impl\aim.py
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
@dataclass(slots=True)
class LookAtObjectWithDuration(ActionBase):
    """
    动作: 注视指定实体并保持指定时长后取消。

    Attributes:
        object_id (str): 目标实体的 ID。
        time_duration (float): 注视保持的时长(秒)。若为 0 则立即取消。
    """

    object_id: str
    time_duration: float

    def validate(self) -> None:
        if not isinstance(self.object_id, str) or not self.object_id:
            raise ValueError("object_id must be a non-empty string.")
        if not isinstance(self.time_duration, int | float) or self.time_duration < 0:
            raise ValueError("time_duration must be a non-negative number.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.look_at_object(
                object_id=self.object_id,
                is_cancel=False,
            )
        )
        if self.time_duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.time_duration))
        await self.submit(
            AnimCmd.look_at_object(
                object_id=self.object_id,
                is_cancel=True,
            )
        )

PointAtLocation dataclass

Bases: ActionBase

动作: 指向指定位置或取消指向指定位置。

Attributes:

Name Type Description
loc Vector3

指向的目标位置。

is_cancel float

指向指定位置或取消指向指定位置,True表示取消,False表示执行。默认为False。

which_hand AnimCmdHandType

使用的手部,AnimCmdHandType.LEFTAnimCmdHandType.RIGHTAnimCmdHandType.BOTH

Source code in src\tongsim\entity\action\impl\aim.py
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@dataclass(slots=True)
class PointAtLocation(ActionBase):
    """
    动作: 指向指定位置或取消指向指定位置。

    Attributes:
        loc (Vector3): 指向的目标位置。
        is_cancel (float): 指向指定位置或取消指向指定位置,True表示取消,False表示执行。默认为False。
        which_hand (AnimCmdHandType): 使用的手部,`AnimCmdHandType.LEFT`、`AnimCmdHandType.RIGHT`、`AnimCmdHandType.BOTH`。
    """

    loc: Vector3
    is_cancel: bool = False
    which_hand: AnimCmdHandType = AnimCmdHandType.RIGHT

    def validate(self) -> None:
        if not isinstance(self.loc, Vector3):
            raise TypeError(f"loc must be a Vector3, got {type(self.loc)}")

        if not isinstance(self.is_cancel, bool):
            raise ValueError(f"is_cancel must be a bool, got {type(self.is_cancel)}")

        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.point_at_location(
                loc=self.loc,
                is_cancel=self.is_cancel,
                is_left_hand=self.which_hand == AnimCmdHandType.LEFT,
            )
        )

PointAtLocationWithDuration dataclass

Bases: ActionBase

动作: 指向指定位置,并保持指定时长后取消。

Attributes:

Name Type Description
loc Vector3

指向的目标位置。

time_duration float

指向保持的时长(秒)。若为 0 则立即取消指向。

which_hand AnimCmdHandType

使用的手部,AnimCmdHandType.LEFTAnimCmdHandType.RIGHTAnimCmdHandType.BOTH

Source code in src\tongsim\entity\action\impl\aim.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
@dataclass(slots=True)
class PointAtLocationWithDuration(ActionBase):
    """
    动作: 指向指定位置,并保持指定时长后取消。

    Attributes:
        loc (Vector3): 指向的目标位置。
        time_duration (float): 指向保持的时长(秒)。若为 0 则立即取消指向。
        which_hand (AnimCmdHandType): 使用的手部,`AnimCmdHandType.LEFT`、`AnimCmdHandType.RIGHT`、`AnimCmdHandType.BOTH`。
    """

    loc: Vector3
    time_duration: float
    which_hand: AnimCmdHandType = AnimCmdHandType.RIGHT

    def validate(self) -> None:
        if not isinstance(self.loc, Vector3):
            raise TypeError(f"loc must be a Vector3, got {type(self.loc)}")

        if not isinstance(self.time_duration, int | float) or self.time_duration < 0:
            raise ValueError("time_duration must be a non-negative number.")

        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        # 开始指向
        await self.submit(
            AnimCmd.point_at_location(
                loc=self.loc,
                is_cancel=False,
                is_left_hand=self.which_hand == AnimCmdHandType.LEFT,
            )
        )

        # 保持指定时长
        if self.time_duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.time_duration))

        # 取消指向
        await self.submit(
            AnimCmd.point_at_location(
                loc=self.loc,
                is_cancel=True,
                is_left_hand=self.which_hand == AnimCmdHandType.LEFT,
            )
        )

PointAtObject dataclass

Bases: ActionBase

动作: 指向指定实体或取消指向。

Attributes:

Name Type Description
object_id str

目标实体的 ID。

is_cancel bool

是否取消指向。默认为 False 表示执行指向。

which_hand AnimCmdHandType

使用的手部。

Source code in src\tongsim\entity\action\impl\aim.py
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
@dataclass(slots=True)
class PointAtObject(ActionBase):
    """
    动作: 指向指定实体或取消指向。

    Attributes:
        object_id (str): 目标实体的 ID。
        is_cancel (bool): 是否取消指向。默认为 False 表示执行指向。
        which_hand (AnimCmdHandType): 使用的手部。
    """

    object_id: str
    is_cancel: bool = False
    which_hand: AnimCmdHandType = AnimCmdHandType.RIGHT

    def validate(self) -> None:
        if not isinstance(self.object_id, str) or not self.object_id:
            raise ValueError("object_id must be a non-empty string.")
        if not isinstance(self.is_cancel, bool):
            raise ValueError("is_cancel must be a bool.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.point_at_object(
                object_id=self.object_id,
                is_cancel=self.is_cancel,
                is_left_hand=self.which_hand == AnimCmdHandType.LEFT,
            )
        )

PointAtObjectWithDuration dataclass

Bases: ActionBase

动作: 指向指定实体并保持指定时长后取消。

Attributes:

Name Type Description
object_id str

目标实体的 ID。

time_duration float

指向保持的时长(秒)。若为 0 则立即取消。

which_hand AnimCmdHandType

使用的手部。

Source code in src\tongsim\entity\action\impl\aim.py
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
@dataclass(slots=True)
class PointAtObjectWithDuration(ActionBase):
    """
    动作: 指向指定实体并保持指定时长后取消。

    Attributes:
        object_id (str): 目标实体的 ID。
        time_duration (float): 指向保持的时长(秒)。若为 0 则立即取消。
        which_hand (AnimCmdHandType): 使用的手部。
    """

    object_id: str
    time_duration: float
    which_hand: AnimCmdHandType = AnimCmdHandType.RIGHT

    def validate(self) -> None:
        if not isinstance(self.object_id, str) or not self.object_id:
            raise ValueError("object_id must be a non-empty string.")
        if not isinstance(self.time_duration, int | float) or self.time_duration < 0:
            raise ValueError("time_duration must be a non-negative number.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.point_at_object(
                object_id=self.object_id,
                is_cancel=False,
                is_left_hand=self.which_hand == AnimCmdHandType.LEFT,
            )
        )
        if self.time_duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.time_duration))
        await self.submit(
            AnimCmd.point_at_object(
                object_id=self.object_id,
                is_cancel=True,
                is_left_hand=self.which_hand == AnimCmdHandType.LEFT,
            )
        )

EatOrDrink dataclass

Bases: ActionBase

动作: 吃喝动作。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定举手的手部。

Source code in src\tongsim\entity\action\impl\gesture.py
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
@dataclass(slots=True)
class EatOrDrink(ActionBase):
    """
    动作: 吃喝动作。

    Attributes:
        which_hand (AnimCmdHandType): 指定举手的手部。
    """

    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.eat_or_drink(self.which_hand))

IdleGesture dataclass

Bases: ActionBase

恢复为默认动作(Idle)。

该动作用于重置当前动画状态,将角色恢复到默认姿态。

Source code in src\tongsim\entity\action\impl\gesture.py
14
15
16
17
18
19
20
21
22
23
24
25
26
@dataclass(slots=True)
class IdleGesture(ActionBase):
    """
    恢复为默认动作(Idle)。

    该动作用于重置当前动画状态,将角色恢复到默认姿态。
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.idle_gesture())

NodHead dataclass

Bases: ActionBase

动作: 点头。

Source code in src\tongsim\entity\action\impl\gesture.py
123
124
125
126
127
128
129
130
131
132
133
@dataclass(slots=True)
class NodHead(ActionBase):
    """
    动作: 点头。
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.nod_head())

NodHeadWithDuration dataclass

Bases: ActionBase

动作: 点头并保持指定时长后恢复为 Idle。

Attributes:

Name Type Description
duration float

持续时间(秒)。0 表示立即恢复。

Source code in src\tongsim\entity\action\impl\gesture.py
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
@dataclass(slots=True)
class NodHeadWithDuration(ActionBase):
    """
    动作: 点头并保持指定时长后恢复为 Idle。

    Attributes:
        duration (float): 持续时间(秒)。0 表示立即恢复。
    """

    duration: float = 0.0

    def validate(self) -> None:
        if not isinstance(self.duration, int | float) or self.duration < 0:
            raise ValueError("Duration must be a non-negative number.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.nod_head())

        if self.duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.duration))

        await self.submit(AnimCmd.idle_gesture())

RaiseHand dataclass

Bases: ActionBase

动作: 举手。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定举手的手部。

Source code in src\tongsim\entity\action\impl\gesture.py
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
@dataclass(slots=True)
class RaiseHand(ActionBase):
    """
    动作: 举手。

    Attributes:
        which_hand (AnimCmdHandType): 指定举手的手部。
    """

    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(AnimCmd.raise_hand(which_hand=self.which_hand))

RaiseHandWithDuration dataclass

Bases: ActionBase

动作: 举手并保持指定时长后恢复为 Idle。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定举手的手部。

duration float

持续时间(秒)。0 表示立即恢复。

Source code in src\tongsim\entity\action\impl\gesture.py
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
@dataclass(slots=True)
class RaiseHandWithDuration(ActionBase):
    """
    动作: 举手并保持指定时长后恢复为 Idle。

    Attributes:
        which_hand (AnimCmdHandType): 指定举手的手部。
        duration (float): 持续时间(秒)。0 表示立即恢复。
    """

    which_hand: AnimCmdHandType
    duration: float = 0.0

    def validate(self) -> None:
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")
        if not isinstance(self.duration, int | float) or self.duration < 0:
            raise ValueError("Duration must be a non-negative number.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.raise_hand(which_hand=self.which_hand))

        if self.duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.duration))

        await self.submit(AnimCmd.idle_gesture())

RompPlay dataclass

Bases: ActionBase

动作: 把玩当前手上的物体(需要手上有物体),若不通过 IdleGesture 取消,会一直持续把玩的动作。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定用哪知手。 不可使用 BOTH 同时双手。

decrease_boredom float

做完这个动作可以减少 agent 多少的无聊值

Source code in src\tongsim\entity\action\impl\gesture.py
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@dataclass(slots=True)
class RompPlay(ActionBase):
    """
    动作: 把玩当前手上的物体(需要手上有物体),若不通过 IdleGesture 取消,会一直持续把玩的动作。

    Attributes:
        which_hand (AnimCmdHandType): 指定用哪知手。 不可使用 BOTH 同时双手。
        decrease_boredom (float): 做完这个动作可以减少 agent 多少的无聊值
    """

    which_hand: AnimCmdHandType
    decrease_boredom: float = 0.0

    def validate(self) -> None:
        # hand type
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise TypeError(
                f"which_hand must be AnimCmdHandType, got {type(self.which_hand)}"
            )
        if self.which_hand == AnimCmdHandType.BOTH:
            raise ValueError("RompPlay does not support BOTH hands.")

        # decrease_boredom
        if not isinstance(self.decrease_boredom, int | float):
            raise TypeError(
                f"decrease_boredom must be int or float, got {type(self.decrease_boredom)}"
            )

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.romp_play(
                which_hand=self.which_hand, decrease_boredom=self.decrease_boredom
            )
        )

RompPlayWithDuration dataclass

Bases: ActionBase

动作: 把玩当前手上的物体并保持指定时长后恢复为 Idle。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定用哪只手。不可使用 BOTH 同时双手。

decrease_boredom float

做完这个动作可以减少 agent 多少的无聊值。

duration float

持续时间(秒)。0 表示立即恢复 Idle。

Source code in src\tongsim\entity\action\impl\gesture.py
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
@dataclass(slots=True)
class RompPlayWithDuration(ActionBase):
    """
    动作: 把玩当前手上的物体并保持指定时长后恢复为 Idle。

    Attributes:
        which_hand (AnimCmdHandType): 指定用哪只手。不可使用 BOTH 同时双手。
        decrease_boredom (float): 做完这个动作可以减少 agent 多少的无聊值。
        duration (float): 持续时间(秒)。0 表示立即恢复 Idle。
    """

    which_hand: AnimCmdHandType
    decrease_boredom: float = 0.0
    duration: float = 0.0

    def validate(self) -> None:
        # hand type
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise TypeError(
                f"which_hand must be AnimCmdHandType, got {type(self.which_hand)}"
            )
        if self.which_hand == AnimCmdHandType.BOTH:
            raise ValueError("RompPlay does not support BOTH hands.")

        # decrease_boredom
        if not isinstance(self.decrease_boredom, int | float):
            raise TypeError(
                f"decrease_boredom must be int or float, got {type(self.decrease_boredom)}"
            )

        # duration
        if not isinstance(self.duration, int | float):
            raise TypeError(f"duration must be int or float, got {type(self.duration)}")
        if self.duration < 0:
            raise ValueError("duration must be non-negative.")

    async def execute(self) -> None:
        # 开始把玩
        await self.submit(
            AnimCmd.romp_play(
                which_hand=self.which_hand, decrease_boredom=self.decrease_boredom
            )
        )

        # 等待指定时长
        if self.duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.duration))

        # 恢复 Idle
        await self.submit(AnimCmd.idle_gesture())

ShakeHead dataclass

Bases: ActionBase

动作: 摇头。

Source code in src\tongsim\entity\action\impl\gesture.py
160
161
162
163
164
165
166
167
168
169
170
@dataclass(slots=True)
class ShakeHead(ActionBase):
    """
    动作: 摇头。
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.shake_head())

ShakeHeadWithDuration dataclass

Bases: ActionBase

动作: 摇头并保持指定时长后恢复为 Idle。

Attributes:

Name Type Description
duration float

持续时间(秒)。0 表示立即恢复。

Source code in src\tongsim\entity\action\impl\gesture.py
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
@dataclass(slots=True)
class ShakeHeadWithDuration(ActionBase):
    """
    动作: 摇头并保持指定时长后恢复为 Idle。

    Attributes:
        duration (float): 持续时间(秒)。0 表示立即恢复。
    """

    duration: float = 0.0

    def validate(self) -> None:
        if not isinstance(self.duration, int | float) or self.duration < 0:
            raise ValueError("Duration must be a non-negative number.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.shake_head())

        if self.duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.duration))

        await self.submit(AnimCmd.idle_gesture())

WaveHand dataclass

Bases: ActionBase

动作: 挥手。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定挥手的手部,可选值为 AnimCmdHandType.LEFTAnimCmdHandType.RIGHTAnimCmdHandType.BOTH

Source code in src\tongsim\entity\action\impl\gesture.py
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@dataclass(slots=True)
class WaveHand(ActionBase):
    """
    动作: 挥手。

    Attributes:
        which_hand (AnimCmdHandType): 指定挥手的手部,可选值为 `AnimCmdHandType.LEFT`、`AnimCmdHandType.RIGHT`、`AnimCmdHandType.BOTH`。
    """

    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(AnimCmd.wave_hand(which_hand=self.which_hand))

WaveHandWithDuration dataclass

Bases: ActionBase

动作: 挥手并保持指定时长后恢复为 Idle。

Attributes:

Name Type Description
which_hand AnimCmdHandType

指定挥手的手部。

duration float

持续时间(秒)。0 表示立即恢复。

Source code in src\tongsim\entity\action\impl\gesture.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
@dataclass(slots=True)
class WaveHandWithDuration(ActionBase):
    """
    动作: 挥手并保持指定时长后恢复为 Idle。

    Attributes:
        which_hand (AnimCmdHandType): 指定挥手的手部。
        duration (float): 持续时间(秒)。0 表示立即恢复。
    """

    which_hand: AnimCmdHandType
    duration: float = 0.0

    def validate(self) -> None:
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")
        if not isinstance(self.duration, int | float) or self.duration < 0:
            raise ValueError("Duration must be a non-negative number.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.wave_hand(which_hand=self.which_hand))

        if self.duration > 0:
            await self.submit(AnimCmd.wait_for(time_duration=self.duration))

        await self.submit(AnimCmd.idle_gesture())

HandBack dataclass

Bases: ActionBase

动作: 手部收回。

Attributes:

Name Type Description
which_hand AnimCmdHandType

使用的手部。

Source code in src\tongsim\entity\action\impl\hand.py
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
@dataclass(slots=True)
class HandBack(ActionBase):
    """
    动作: 手部收回。

    Attributes:
        which_hand (AnimCmdHandType): 使用的手部。
    """

    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.hand_back(
                which_hand=self.which_hand,
            )
        )

HandReach dataclass

Bases: ActionBase

动作: 手部伸向目标位置。

Attributes:

Name Type Description
which_hand AnimCmdHandType

使用的手部。

target_location Vector3

目标位置。

is_reach_from_front bool

是否从前方伸手,默认 False。

auto_offset bool

是否自动调整到表面,默认 True。

Source code in src\tongsim\entity\action\impl\hand.py
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
@dataclass(slots=True)
class HandReach(ActionBase):
    """
    动作: 手部伸向目标位置。

    Attributes:
        which_hand (AnimCmdHandType): 使用的手部。
        target_location (Vector3): 目标位置。
        is_reach_from_front (bool): 是否从前方伸手,默认 False。
        auto_offset (bool): 是否自动调整到表面,默认 True。
    """

    which_hand: AnimCmdHandType
    target_location: Vector3
    is_reach_from_front: bool = False
    auto_offset: bool = True

    def validate(self) -> None:
        if not isinstance(self.target_location, Vector3):
            raise TypeError("target_location must be a Vector3.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.hand_reach_to_location(
                which_hand=self.which_hand,
                location=self.target_location,
                is_reach_from_front=self.is_reach_from_front,
                auto_offset=self.auto_offset,
            )
        )

HandRelease dataclass

Bases: ActionBase

动作: 释放手中的物体。

Attributes:

Name Type Description
which_hand AnimCmdHandType

使用的手部。

target_location Vector3

目标位置。

force_locate bool

是否强制放到特定位置,默认 True。

force_release bool

是否强制释放,默认 True

auto_rotate bool

是否自动调整旋转,默认 False。

disable_physics bool

是否禁用物理效果,默认 False。

hold_if_unreachable bool

若释放失败是否继续抓握,默认 False。

container_id str | None

容器 ID(用于优化表现),可选。

Source code in src\tongsim\entity\action\impl\hand.py
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
@dataclass(slots=True)
class HandRelease(ActionBase):
    """
    动作: 释放手中的物体。

    Attributes:
        which_hand (AnimCmdHandType): 使用的手部。
        target_location (Vector3): 目标位置。
        force_locate (bool): 是否强制放到特定位置,默认 True。
        force_release (bool): 是否强制释放,默认 True
        auto_rotate (bool): 是否自动调整旋转,默认 False。
        disable_physics (bool): 是否禁用物理效果,默认 False。
        hold_if_unreachable (bool): 若释放失败是否继续抓握,默认 False。
        container_id (str | None): 容器 ID(用于优化表现),可选。
    """

    which_hand: AnimCmdHandType
    target_location: Vector3
    force_locate: bool = True
    force_release: bool = True
    auto_rotate: bool = False
    rotation: Quaternion | None = None
    disable_physics: bool = False
    hold_if_unreachable: bool = False
    container_id: str | None = None

    def validate(self) -> None:
        if not isinstance(self.target_location, Vector3):
            raise TypeError("target_location must be a Vector3.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.hand_release_with_location(
                which_hand=self.which_hand,
                target_location=self.target_location,
                force_locate=self.force_locate,
                auto_rotate=self.auto_rotate,
                rotation=self.rotation,
                force_release=self.force_release,
                disable_physics=self.disable_physics,
                hold_if_unreachable=self.hold_if_unreachable,
                container_unique_name=self.container_id,
            )
        )

PutDownToLocation dataclass

Bases: ActionBase

动作: 放下物体到指定位置。

Attributes:

Name Type Description
which_hand AnimCmdHandType

使用的手部。

target_location Vector3

目标位置。

disable_physics bool

松手后是否禁用物理效果,默认 False。

hold_if_unreachable bool

若物体无法到达目标位置,是否保持抓握,默认 False。

force_release bool

是否强制释放,默认 True。

auto_rotate bool

是否自动调整旋转,默认 False。

rotation Quaternion | None

调整后的旋转角度,可选。

force_locate bool

是否强制放到特定位置,默认 True。

container_id str | None

容器 ID(用于优化动作表现),可选。

Source code in src\tongsim\entity\action\impl\hand.py
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
@dataclass(slots=True)
class PutDownToLocation(ActionBase):
    """
    动作: 放下物体到指定位置。

    Attributes:
        which_hand (AnimCmdHandType): 使用的手部。
        target_location (Vector3): 目标位置。
        disable_physics (bool): 松手后是否禁用物理效果,默认 False。
        hold_if_unreachable (bool): 若物体无法到达目标位置,是否保持抓握,默认 False。
        force_release (bool): 是否强制释放,默认 True。
        auto_rotate (bool): 是否自动调整旋转,默认 False。
        rotation (Quaternion | None): 调整后的旋转角度,可选。
        force_locate (bool): 是否强制放到特定位置,默认 True。
        container_id (str | None): 容器 ID(用于优化动作表现),可选。
    """

    which_hand: AnimCmdHandType
    target_location: Vector3
    force_release: bool = True
    disable_physics: bool = False
    hold_if_unreachable: bool = False
    auto_rotate: bool = False
    rotation: Quaternion | None = None
    force_locate: bool = True
    container_id: str | None = None

    def validate(self) -> None:
        if not isinstance(self.target_location, Vector3):
            raise TypeError("target_location must be a Vector3.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        # 1. 伸手
        await self.submit(
            AnimCmd.hand_reach_to_location(
                which_hand=self.which_hand,
                location=self.target_location,
                is_reach_from_front=False,
                auto_offset=True,
            )
        )

        # 2. 放置
        await self.submit(
            AnimCmd.hand_release_with_location(
                which_hand=self.which_hand,
                target_location=self.target_location,
                force_locate=self.force_locate,
                auto_rotate=self.auto_rotate,
                rotation=self.rotation,
                force_release=self.force_release,
                disable_physics=self.disable_physics,
                hold_if_unreachable=self.hold_if_unreachable,
                container_unique_name=self.container_id,
            )
        )

        # 3. 收手
        await self.submit(AnimCmd.hand_back(which_hand=self.which_hand))

TakeObject dataclass

Bases: ActionBase

动作: 拿起物体。

Attributes:

Name Type Description
which_hand AnimCmdHandType

使用的手部。

object_id str

目标物体 ID。

use_socket bool

是否使用 socket,默认 False。

force_grab bool

是否强制抓取,默认 False。

is_reach_from_front bool

是否从前方伸手,默认 False。

auto_offset bool

是否自动调整到物体表面,默认 False。

container_id str | None

容器 ID(用于优化动作表现),可选。

Source code in src\tongsim\entity\action\impl\hand.py
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@dataclass(slots=True)
class TakeObject(ActionBase):
    """
    动作: 拿起物体。

    Attributes:
        which_hand (AnimCmdHandType): 使用的手部。
        object_id (str): 目标物体 ID。
        use_socket (bool): 是否使用 socket,默认 False。
        force_grab (bool): 是否强制抓取,默认 False。
        is_reach_from_front (bool): 是否从前方伸手,默认 False。
        auto_offset (bool): 是否自动调整到物体表面,默认 False。
        container_id (str | None): 容器 ID(用于优化动作表现),可选。
    """

    which_hand: AnimCmdHandType
    object_id: str
    use_socket: bool = False
    force_grab: bool = False
    is_reach_from_front: bool = False
    auto_offset: bool = False
    container_id: str | None = None

    def validate(self) -> None:
        if not self.object_id:
            raise ValueError("object_id must be specified.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        # 1. 伸手
        await self.submit(
            AnimCmd.hand_reach_to_object(
                which_hand=self.which_hand,
                object_id=self.object_id,
                is_reach_from_front=self.is_reach_from_front,
                auto_offset=self.auto_offset,
                use_socket=self.use_socket,
            )
        )

        # 2. 抓取
        await self.submit(
            AnimCmd.hand_grab_object(
                which_hand=self.which_hand,
                object_id=self.object_id,
                container_unique_name=self.container_id,
                force_grab=self.force_grab,
                use_socket=self.use_socket,
            )
        )

        # 3. 收手
        await self.submit(AnimCmd.hand_back(which_hand=self.which_hand))

InputAnimation dataclass

Bases: ActionBase

动作: 输入动作(Input Animation)。

该动作用于控制角色的输入行为,比如移动方向、是否冲刺、角速度、跳跃与下蹲等。 所有参数均为可选,若不设置,则不影响对应的输入状态。

Attributes:

Name Type Description
move_vec Vector2 | None

是否有移动向量的输入,x表示左右移动, y表示前后移动,范围[-1, 1],None 表示未设置。

angular_speed float | None

角速度,表示旋转速率,单位为度/秒,None 表示不设置。

sprint bool | None

是否冲刺,True 表示冲刺,False 表示正常移动,None 表示未设置。

jump bool | None

是否跳跃,True 表示跳跃,False 表示不跳,None 表示未设置。

crouch bool | None

是否下蹲,True 表示下蹲,False 表示站立,None 表示未设置。

Source code in src\tongsim\entity\action\impl\input.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
@dataclass(slots=True)
class InputAnimation(ActionBase):
    """
    动作: 输入动作(Input Animation)。

    该动作用于控制角色的输入行为,比如移动方向、是否冲刺、角速度、跳跃与下蹲等。
    所有参数均为可选,若不设置,则不影响对应的输入状态。

    Attributes:
        move_vec (Vector2 | None): 是否有移动向量的输入,x表示左右移动, y表示前后移动,范围[-1, 1],None 表示未设置。
        angular_speed (float | None): 角速度,表示旋转速率,单位为度/秒,None 表示不设置。
        sprint (bool | None): 是否冲刺,True 表示冲刺,False 表示正常移动,None 表示未设置。
        jump (bool | None): 是否跳跃,True 表示跳跃,False 表示不跳,None 表示未设置。
        crouch (bool | None): 是否下蹲,True 表示下蹲,False 表示站立,None 表示未设置。
    """

    move_vec: Vector2 | None = None
    angular_speed: float | None = None
    sprint: bool | None = None
    jump: bool | None = None
    crouch: bool | None = None

    def validate(self) -> None:
        if self.move_vec is not None and not isinstance(self.move_vec, Vector2):
            raise ValueError("move_vec must be a Vector2 or None.")

        if self.sprint is not None and not isinstance(self.sprint, bool):
            raise ValueError("sprint must be a boolean or None.")

        if self.jump is not None and not isinstance(self.jump, bool):
            raise ValueError("jump must be a boolean or None.")

        if self.crouch is not None and not isinstance(self.crouch, bool):
            raise ValueError("crouch must be a boolean or None.")

        if self.angular_speed is not None:
            if not isinstance(self.angular_speed, int | float):
                raise ValueError("angular_speed must be a float or None.")
            if not -360.0 <= self.angular_speed <= 360.0:
                raise ValueError("angular_speed must be in [-360.0, 360.0]")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.input_action(
                move_vec=self.move_vec,
                sprint=self.sprint,
                angular_speed=self.angular_speed,
                jump=self.jump,
                crouch=self.crouch,
            )
        )

SwitchInputAnimation dataclass

Bases: ActionBase

动作: 启动或者关闭输入控制器。

Attributes:

Name Type Description
is_enable bool

是否启动控制器。

Source code in src\tongsim\entity\action\impl\input.py
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@dataclass(slots=True)
class SwitchInputAnimation(ActionBase):
    """
    动作: 启动或者关闭输入控制器。

    Attributes:
        is_enable (bool): 是否启动控制器。
    """

    is_enable: bool = False

    def validate(self) -> None:
        if not isinstance(self.is_enable, bool):
            raise TypeError("is_close_input must be a bool.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.switch_input_animation(is_close_input=not self.is_enable)
        )

Interact dataclass

Bases: ActionBase

动作: 交互对象状态。

用于控制对象状态(如开/关),可应用于灯、按钮、机器开关等。

Attributes:

Name Type Description
object_id str

目标对象的唯一 ID。

new_object_state bool

希望设置的状态,True 表示开启/激活,False 表示关闭/停用。

Source code in src\tongsim\entity\action\impl\interact.py
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@dataclass(slots=True)
class Interact(ActionBase):
    """
    动作: 交互对象状态。

    用于控制对象状态(如开/关),可应用于灯、按钮、机器开关等。

    Attributes:
        object_id (str): 目标对象的唯一 ID。
        new_object_state (bool): 希望设置的状态,True 表示开启/激活,False 表示关闭/停用。
    """

    object_id: str
    new_object_state: bool

    def validate(self) -> None:
        if not isinstance(self.object_id, str):
            raise TypeError(f"object_id must be str, got {type(self.object_id)}")
        if not isinstance(self.new_object_state, bool):
            raise TypeError(
                f"new_object_state must be bool, got {type(self.new_object_state)}"
            )

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.touch_object_state(
                target_id=self.object_id, new_state=self.new_object_state
            )
        )

MoveToComponent dataclass

Bases: ActionBase

动作: 移动至指定目标组件,移动速度较大时会切换为跑步动作,移动速度较小时维持走路动作。

Attributes:

Name Type Description
component_id str

目标的 ComponentID。

speed float

移动速度,单位为 cm/s,若为 0 表示使用默认速度。

Source code in src\tongsim\entity\action\impl\locomotion.py
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
@dataclass(slots=True)
class MoveToComponent(ActionBase):
    """
    动作: 移动至指定目标组件,移动速度较大时会切换为跑步动作,移动速度较小时维持走路动作。

    Attributes:
        component_id (str): 目标的 ComponentID。
        speed (float): 移动速度,单位为 cm/s,若为 0 表示使用默认速度。
    """

    component_id: str
    speed: float = 0.0

    def validate(self) -> None:
        if not self.component_id:
            raise ValueError("component_id must be specified.")
        if not isinstance(self.speed, int | float) or self.speed < 0:
            raise ValueError("speed must be a non-negative number")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.move_to_component(
                component_id=self.component_id, move_speed=self.speed, can_run=False
            )
        )

MoveToLocation dataclass

Bases: ActionBase

动作: 移动至指定目标位置,移动速度较大时会切换为跑步动作,移动速度较小时维持走路动作。

Attributes:

Name Type Description
loc Vector3

目标世界坐标位置。

speed float

移动速度,单位为 cm/s,若为 0 表示使用默认速度。

Source code in src\tongsim\entity\action\impl\locomotion.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
@dataclass(slots=True)
class MoveToLocation(ActionBase):
    """
    动作: 移动至指定目标位置,移动速度较大时会切换为跑步动作,移动速度较小时维持走路动作。

    Attributes:
        loc (Vector3): 目标世界坐标位置。
        speed (float): 移动速度,单位为 cm/s,若为 0 表示使用默认速度。
    """

    loc: Vector3
    speed: float = 0.0

    def validate(self) -> None:
        if not isinstance(self.loc, Vector3):
            raise TypeError(f"loc must be a Vector3, got {type(self.loc)}")
        if not isinstance(self.speed, int | float) or self.speed < 0:
            raise ValueError(f"speed must be a non-negative number, got {self.speed}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.move_to_location(loc=self.loc, move_speed=self.speed, can_run=False)
        )

MoveToObject dataclass

Bases: ActionBase

动作: 移动至指定目标,移动速度较大时会切换为跑步动作,移动速度较小时维持走路动作。

Attributes:

Name Type Description
object_id str

目标的 EntityID。

speed float

移动速度,单位为 cm/s,若为 0 表示使用默认速度。

Source code in src\tongsim\entity\action\impl\locomotion.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@dataclass(slots=True)
class MoveToObject(ActionBase):
    """
    动作: 移动至指定目标,移动速度较大时会切换为跑步动作,移动速度较小时维持走路动作。

    Attributes:
        object_id (str): 目标的 EntityID。
        speed (float): 移动速度,单位为 cm/s,若为 0 表示使用默认速度。
    """

    object_id: str
    speed: float = 0.0

    def validate(self) -> None:
        if not self.object_id:
            raise ValueError("object_id must be specified.")
        if not isinstance(self.speed, int | float) or self.speed < 0:
            raise ValueError("speed must be a non-negative number")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.move_to_object(
                object_id=self.object_id, move_speed=self.speed, can_run=False
            )
        )

TurnInDegree dataclass

Bases: ActionBase

动作: 原地转特定角度。

Attributes:

Name Type Description
degree float

需要原地转的角度。

Source code in src\tongsim\entity\action\impl\locomotion.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
@dataclass(slots=True)
class TurnInDegree(ActionBase):
    """
    动作: 原地转特定角度。

    Attributes:
        degree (float): 需要原地转的角度。
    """

    degree: float

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.turn_around_degree(
                degree=self.degree,
            )
        )

TurnToComponent dataclass

Bases: ActionBase

动作: 转向至指定目标组件。

Attributes:

Name Type Description
component_id str

目标的 ComponentID。

Source code in src\tongsim\entity\action\impl\locomotion.py
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
@dataclass(slots=True)
class TurnToComponent(ActionBase):
    """
    动作: 转向至指定目标组件。

    Attributes:
        component_id (str): 目标的 ComponentID。
    """

    component_id: str

    def validate(self) -> None:
        if not self.component_id:
            raise ValueError("component_id must be specified.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.turn_around_to_component(
                component_id=self.component_id,
            )
        )

TurnToLocation dataclass

Bases: ActionBase

动作: 转向目标至指定目标位置。

Attributes:

Name Type Description
loc Vector3

目标世界坐标位置。

Source code in src\tongsim\entity\action\impl\locomotion.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
@dataclass(slots=True)
class TurnToLocation(ActionBase):
    """
    动作: 转向目标至指定目标位置。

    Attributes:
        loc (Vector3): 目标世界坐标位置。
    """

    loc: Vector3

    def validate(self) -> None:
        if not isinstance(self.loc, Vector3):
            raise TypeError(f"loc must be a Vector3, got {type(self.loc)}")

    async def execute(self) -> None:
        await self.submit(AnimCmd.turn_around_to_location(loc=self.loc))

TurnToObject dataclass

Bases: ActionBase

动作: 转向目标至指定目标。

Attributes:

Name Type Description
object_id str

目标的 EntityID。

Source code in src\tongsim\entity\action\impl\locomotion.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
@dataclass(slots=True)
class TurnToObject(ActionBase):
    """
    动作: 转向目标至指定目标。

    Attributes:
        object_id (str): 目标的 EntityID。
    """

    object_id: str

    def validate(self) -> None:
        if not self.object_id:
            raise ValueError("object_id must be specified.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.turn_around_to_object(object_id=self.object_id))

CancelAllActions dataclass

Bases: ActionBase

动作:强制取消所有动作,包括当前正在执行的动作。

Source code in src\tongsim\entity\action\impl\standard.py
485
486
487
488
489
490
491
492
493
494
495
@dataclass(slots=True)
class CancelAllActions(ActionBase):
    """
    动作:强制取消所有动作,包括当前正在执行的动作。
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.cancel_all_action())

ClimbDown dataclass

Bases: ActionBase

动作: 爬下

Source code in src\tongsim\entity\action\impl\standard.py
67
68
69
70
71
72
73
74
75
76
77
@dataclass(slots=True)
class ClimbDown(ActionBase):
    """
    动作: 爬下
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.climb_down())

ClimbObject dataclass

Bases: ActionBase

动作: 爬上指定物体。

Attributes:

Name Type Description
object_name str

目标物体名称

Source code in src\tongsim\entity\action\impl\standard.py
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
@dataclass(slots=True)
class ClimbObject(ActionBase):
    """
    动作: 爬上指定物体。

    Attributes:
        object_name (str): 目标物体名称
    """

    object_name: str

    def validate(self) -> None:
        if not self.object_name:
            raise ValueError("object_name must be provided.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.climb_object(object_name=self.object_name))

CloseDoor dataclass

Bases: ActionBase

动作: 关门或抽屉。TongSim中, 门组件 泛指 基于物理约束绑定的组件,比如旋转门,推拉门,抽屉等等。

Attributes:

Name Type Description
component_id str

门组件 ID。

which_hand AnimCmdHandType

使用哪只手

Source code in src\tongsim\entity\action\impl\standard.py
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
@dataclass(slots=True)
class CloseDoor(ActionBase):
    """
    动作: 关门或抽屉。TongSim中, 门组件 泛指 基于物理约束绑定的组件,比如旋转门,推拉门,抽屉等等。

    Attributes:
        component_id (str): 门组件 ID。
        which_hand (AnimCmdHandType): 使用哪只手
    """

    component_id: str
    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not self.component_id:
            raise ValueError("component_id must be provided.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.move_to_component(component_id=self.component_id, use_socket=True)
        )
        await self.submit(
            AnimCmd.turn_around_to_component(
                component_id=self.component_id, use_socket=True
            )
        )
        await self.submit(
            AnimCmd.hand_reach_to_component(
                which_hand=self.which_hand,
                component_id=self.component_id,
                use_socket=True,
            )
        )
        await self.submit(
            AnimCmd.close_door(
                component_id=self.component_id, which_hand=self.which_hand
            )
        )
        await self.submit(AnimCmd.hand_back(which_hand=self.which_hand))

MopFloor dataclass

Bases: ActionBase

动作:使用拖把清洁地面。

注意:该动作要求 agent 右手持有拖把。

Attributes:

Name Type Description
dirt_id str

需要清洁的污渍 ID。

Source code in src\tongsim\entity\action\impl\standard.py
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
@dataclass(slots=True)
class MopFloor(ActionBase):
    """
    动作:使用拖把清洁地面。

    注意:该动作要求 agent 右手持有拖把。

    Attributes:
        dirt_id (str): 需要清洁的污渍 ID。
    """

    dirt_id: str

    def validate(self) -> None:
        if not self.dirt_id:
            raise ValueError("dirt_id must be provided.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.mop_floor(dirt_id=self.dirt_id))

OpenDoor dataclass

Bases: ActionBase

动作: 开门或抽屉。TongSim中, 门组件 泛指 基于物理约束绑定的组件,比如旋转门,推拉门,抽屉等等。

Attributes:

Name Type Description
component_id str

门组件 ID。

which_hand AnimCmdHandType

使用哪只手

Source code in src\tongsim\entity\action\impl\standard.py
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
@dataclass(slots=True)
class OpenDoor(ActionBase):
    """
    动作: 开门或抽屉。TongSim中, 门组件 泛指 基于物理约束绑定的组件,比如旋转门,推拉门,抽屉等等。

    Attributes:
        component_id (str): 门组件 ID。
        which_hand (AnimCmdHandType): 使用哪只手
    """

    component_id: str
    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not self.component_id:
            raise ValueError("component_id must be provided.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError(f"Invalid hand type: {self.which_hand}")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.move_to_component(component_id=self.component_id, use_socket=True)
        )
        await self.submit(
            AnimCmd.turn_around_to_component(
                component_id=self.component_id, use_socket=True
            )
        )
        await self.submit(
            AnimCmd.hand_reach_to_component(
                which_hand=self.which_hand,
                component_id=self.component_id,
                use_socket=True,
            )
        )
        await self.submit(
            AnimCmd.open_door(
                component_id=self.component_id, which_hand=self.which_hand
            )
        )
        await self.submit(AnimCmd.hand_back(which_hand=self.which_hand))

PlayAnimation dataclass

Bases: ActionBase

动作: 播放指定的动画序列。

Attributes:

Name Type Description
animation_name str

动画序列的名称。

animation_slot str

动画槽位。当前支持: [PlayAnimSequence(default), UpperBody, LowerBody,Facial]

Source code in src\tongsim\entity\action\impl\standard.py
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
@dataclass(slots=True)
class PlayAnimation(ActionBase):
    """
    动作: 播放指定的动画序列。

    Attributes:
        animation_name (str): 动画序列的名称。
        animation_slot (str): 动画槽位。当前支持: [PlayAnimSequence(default), UpperBody, LowerBody,Facial]
    """

    animation_name: str
    animation_slot: str = "PlayAnimSequence"

    def validate(self) -> None:
        if not self.animation_name:
            raise ValueError("animation_name must be provided.")
        if not self.animation_slot:
            raise ValueError("animation_slot must be provided.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.play_animation(
                animation_to_play=self.animation_name,
                animation_slot=self.animation_slot,
            )
        )

PourWater dataclass

Bases: ActionBase

动作: 倒水。

Attributes:

Name Type Description
target_id str

倒水目标对象ID(杯子)

location Vector3

倒水的目标位置(比如杯子伸到哪)

which_hand AnimCmdHandType

使用哪只手

Source code in src\tongsim\entity\action\impl\standard.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
@dataclass(slots=True)
class PourWater(ActionBase):
    """
    动作: 倒水。

    Attributes:
        target_id (str): 倒水目标对象ID(杯子)
        location (Vector3): 倒水的目标位置(比如杯子伸到哪)
        which_hand (AnimCmdHandType): 使用哪只手
    """

    target_id: str
    location: Vector3
    which_hand: AnimCmdHandType

    def validate(self) -> None:
        if not self.target_id:
            raise ValueError("target_id must be provided.")
        if not isinstance(self.location, Vector3):
            raise TypeError("location must be a Vector3.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.pour_water(
                target_id=self.target_id,
                location=self.location,
                which_hand=self.which_hand,
            )
        )

ReadBook dataclass

Bases: ActionBase

动作: 阅读书籍, 需要手上有书

Attributes:

Name Type Description
duration int

阅读时间(秒)。

Source code in src\tongsim\entity\action\impl\standard.py
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@dataclass(slots=True)
class ReadBook(ActionBase):
    """
    动作: 阅读书籍, 需要手上有书

    Attributes:
        duration (int): 阅读时间(秒)。
    """

    duration: int

    def validate(self) -> None:
        if not isinstance(self.duration, int) or self.duration <= 0:
            raise ValueError("duration must be a positive integer.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.read_book(duration=self.duration))

SitDownToLocation dataclass

Bases: ActionBase

动作: 坐下到指定位置。

Attributes:

Name Type Description
location Vector3

坐下的位置

Source code in src\tongsim\entity\action\impl\standard.py
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
@dataclass(slots=True)
class SitDownToLocation(ActionBase):
    """
    动作: 坐下到指定位置。

    Attributes:
        location (Vector3): 坐下的位置
    """

    location: Vector3

    def validate(self) -> None:
        if not isinstance(self.location, Vector3):
            raise TypeError("location must be a Vector3.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.sit_down_to_location(location=self.location))

SitDownToObject dataclass

Bases: ActionBase

动作: 坐下到指定物体。

Attributes:

Name Type Description
object_id str

目标物体 ID

Source code in src\tongsim\entity\action\impl\standard.py
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
@dataclass(slots=True)
class SitDownToObject(ActionBase):
    """
    动作: 坐下到指定物体。

    Attributes:
        object_id (str): 目标物体 ID
    """

    object_id: str

    def validate(self) -> None:
        if not self.object_id:
            raise ValueError("object_id must be provided.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.sit_down_to_object(object_id=self.object_id))

SleepDown dataclass

Bases: ActionBase

动作: 躺下睡觉

Attributes:

Name Type Description
object_id str

睡觉目标(床 或者 沙发)

Source code in src\tongsim\entity\action\impl\standard.py
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
@dataclass(slots=True)
class SleepDown(ActionBase):
    """
    动作: 躺下睡觉

    Attributes:
        object_id (str): 睡觉目标(床 或者 沙发)
    """

    object_id: str

    def validate(self) -> None:
        if not self.object_id:
            raise ValueError("object_id must be provided.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.sleep_down(subject=self.object_id))

SleepUp dataclass

Bases: ActionBase

动作: 起身(从睡眠状态)。

Source code in src\tongsim\entity\action\impl\standard.py
165
166
167
168
169
170
171
172
173
174
175
@dataclass(slots=True)
class SleepUp(ActionBase):
    """
    动作: 起身(从睡眠状态)。
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.sleep_up())

SliceFood dataclass

Bases: ActionBase

动作: 切割食物。

Attributes:

Name Type Description
food_id str

被切割的食物 ID

location Vector3

切割位置

Source code in src\tongsim\entity\action\impl\standard.py
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
@dataclass(slots=True)
class SliceFood(ActionBase):
    """
    动作: 切割食物。

    Attributes:
        food_id (str): 被切割的食物 ID
        location (Vector3): 切割位置
    """

    food_id: str
    location: Vector3

    def validate(self) -> None:
        if not self.food_id:
            raise ValueError("food_id must be provided.")
        if not isinstance(self.location, Vector3):
            raise TypeError("location must be a Vector3.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.slice_food(food_id=self.food_id, location=self.location)
        )

StandUp dataclass

Bases: ActionBase

动作: 起立。

用于从坐下或躺下状态回到站立状态。

Source code in src\tongsim\entity\action\impl\standard.py
357
358
359
360
361
362
363
364
365
366
367
368
369
@dataclass(slots=True)
class StandUp(ActionBase):
    """
    动作: 起立。

    用于从坐下或躺下状态回到站立状态。
    """

    def validate(self) -> None:
        pass

    async def execute(self) -> None:
        await self.submit(AnimCmd.stand_up())

Wait dataclass

Bases: ActionBase

动作: 等待指定时间。用于动作之间的间隔或延迟处理。

Attributes:

Name Type Description
time_duration float

等待时间(单位: 秒),必须为非负数。

Source code in src\tongsim\entity\action\impl\standard.py
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
@dataclass(slots=True)
class Wait(ActionBase):
    """
    动作: 等待指定时间。用于动作之间的间隔或延迟处理。

    Attributes:
        time_duration (float): 等待时间(单位: 秒),必须为非负数。
    """

    time_duration: float = 0.0

    def validate(self) -> None:
        if not isinstance(self.time_duration, int | float) or self.time_duration < 0:
            raise ValueError("time_duration must be a non-negative number.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.wait_for(time_duration=self.time_duration))

WashFace dataclass

Bases: ActionBase

动作: 洗脸。

Attributes:

Name Type Description
faucet_object_id str

水龙头对象名称

Source code in src\tongsim\entity\action\impl\standard.py
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
@dataclass(slots=True)
class WashFace(ActionBase):
    """
    动作: 洗脸。

    Attributes:
        faucet_object_id (str): 水龙头对象名称
    """

    faucet_object_id: str

    def validate(self) -> None:
        if not self.faucet_object_id:
            raise ValueError("faucet_object_id must be provided.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.wash_face(faucet_object_name=self.faucet_object_id))

WashHands dataclass

Bases: ActionBase

动作: 洗手。

Attributes:

Name Type Description
faucet_object_id str

水龙头对象名称

Source code in src\tongsim\entity\action\impl\standard.py
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
@dataclass(slots=True)
class WashHands(ActionBase):
    """
    动作: 洗手。

    Attributes:
        faucet_object_id (str): 水龙头对象名称
    """

    faucet_object_id: str

    def validate(self) -> None:
        if not self.faucet_object_id:
            raise ValueError("faucet_object_id must be provided.")

    async def execute(self) -> None:
        await self.submit(AnimCmd.wash_hands(faucet_object_name=self.faucet_object_id))

WashObjectInHand dataclass

Bases: ActionBase

动作: 洗手中的物体。

Attributes:

Name Type Description
faucet_object_id str

水龙头对象名称

Source code in src\tongsim\entity\action\impl\standard.py
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
@dataclass(slots=True)
class WashObjectInHand(ActionBase):
    """
    动作: 洗手中的物体。

    Attributes:
        faucet_object_id (str): 水龙头对象名称
    """

    faucet_object_id: str

    def validate(self) -> None:
        if not self.faucet_object_id:
            raise ValueError("faucet_object_id must be provided.")

    async def execute(self) -> None:
        await self.submit(
            AnimCmd.wash_object_in_hand(faucet_object_name=self.faucet_object_id)
        )

WipeQuad dataclass

Bases: ActionBase

动作:擦拭一个矩形区域。

注意:该动作想要成功擦除,要求 agent 手上有抹布等物体。

Attributes:

Name Type Description
which_hand AnimCmdHandType

使用的手(左手或右手)。

dirt_location Vector3

矩形区域的中心位置。

quad_extent float

半边长(单位: cm), 决定矩形的大小。

Source code in src\tongsim\entity\action\impl\standard.py
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
@dataclass(slots=True)
class WipeQuad(ActionBase):
    """
    动作:擦拭一个矩形区域。

    注意:该动作想要成功擦除,要求 agent 手上有抹布等物体。

    Attributes:
        which_hand (AnimCmdHandType): 使用的手(左手或右手)。
        dirt_location (Vector3): 矩形区域的中心位置。
        quad_extent (float): 半边长(单位: cm), 决定矩形的大小。
    """

    which_hand: AnimCmdHandType
    dirt_location: Vector3
    quad_extent: float = 5.0

    def validate(self) -> None:
        if not isinstance(self.dirt_location, Vector3):
            raise ValueError("dirt_location must be a Vector3.")
        if not isinstance(self.quad_extent, int | float) or self.quad_extent <= 0:
            raise ValueError("quad_extent must be a positive number.")
        if not isinstance(self.which_hand, AnimCmdHandType):
            raise ValueError("which_hand must be a valid AnimCmdHandType.")

    async def execute(self) -> None:
        x, y, z = self.dirt_location.x, self.dirt_location.y, self.dirt_location.z
        e = self.quad_extent

        wipe_point1 = Vector3(x - e, y + e, z)
        wipe_point2 = Vector3(x + e, y + e, z)
        wipe_point3 = Vector3(x - e, y - e, z)
        wipe_point4 = Vector3(x + e, y - e, z)

        await self.submit(
            AnimCmd.wipe_quadrilateral(
                which_hand=self.which_hand,
                conner1=wipe_point1,
                conner2=wipe_point2,
                conner3=wipe_point3,
                conner4=wipe_point4,
            )
        )