小案例:模拟鼠标移动物体
不知道为啥我没有UNDO菜单
import bpy
bl_info = {
"name" : "test",
"author" : "yl",
"description" : "",
"blender" : (3, 0, 0),
"version" : (0, 0, 1),
"location" : "",
"warning" : "",
"category" : "Yuelili",
"doc_url":"https://yuelili.com"
}
# 自定义类
class MoveCubeOperator(bpy.types.Operator):
bl_idname="cube.movecube" # ID,必须。命名必须要带,以小写字母,下划线 数字(my_operator.my_class_name)
bl_label = "Test Move Cube" # 标签,显示名称
bl_description = "Description About This Tool" # 描述
bl_options = {'REGISTER', 'UNDO'} # 选项,UNDO是左下角UNDO面板
# 定义RNA属性,鼠标的X和Y位置
mouseX : bpy.props.FloatProperty(name="float",default=0.0)
mouseY : bpy.props.FloatProperty(name="float",default=0.0)
# 定义初始化X和Y属性
defX = 0.0
defy = 0.0
# 定义状态,为了左键退出
isOK = False
@classmethod
def poll(cls,context):
# 如果不是3D视窗下的物体编辑模式,并且选择的物体为空,则退出
if context.area.ui_type == "VIEW_3D":
if context.active_object is not None:
if context.object.mode == "OBJECT":
return True
def excute(self,context):
# 获取对象,并把对象的值绑定鼠标位置
obj = context.object
obj.location[0] = self.mouseX
obj.location[1] = self.mouseY
# 如果左键OK了,则退出
if self.isOK:
return {"FINISHED"}
def invoke(self,context,event):
# 记住物体初始位置
self.defX = context.object.location[0]
self.defY = context.object.location[1]
# 使用RUNNING_MODAL的前置handler函数
context.window_manager.modal_handler_add(self)
return {"RUNNING_MODAL"}
def modal(self, context, event):
# 获取鼠标信息,并用excute移动物体
self.mouseX = event.mouse_x / 50
self.mouseY = event.mouse_y / 50
self.excute(context)
# 右键可以取消,并把物体位置还原
if event.type == "RIGHTMOUSE":
print("cancel")
self.mouseX = self.defX
self.mouseY = self.defY
self.excute(context)
return {"FINISHED"}
# 左键就生效,并退出
if event.type == "LEFTMOUSE":
self.isOK = True
print("ok")
return {"FINISHED"}
return {"RUNNING_MODAL"}
def register():
print("塔塔开")
# 注册
bpy.utils.register_class(MoveCubeOperator)
...
def unregister():
print("已经不用再战斗了")
#注销
bpy.utils.unregister_class(MoveCubeOperator)
...