godot 简单实用的旋转和位移平滑插值方案, tween 版本, 方案1 是通用的 unity 支持

发布时间 2023-12-20 17:03:39作者: porter_代码工作者

#相机平滑视角移动
 
#旧方案  移动超过360 或者负数的角度,会转大圈,也有可能会遇到万向节死锁的问题
func camera_move_old(move_node,move_pos:Vector3,move_rot:Vector3,time):
	var tween=create_tween().set_parallel()
	tween.tween_property(move_node,"global_position",Vector3(move_pos),time)
	tween.tween_property(move_node,"global_rotation",Vector3(move_rot),time)
	pass

#方案1 采用四元数完成 平滑插值 
func camera_move(move_node,move_pos:Vector3,move_rot:Vector3,time):
	var tween=create_tween().set_parallel()
	tween.tween_property(move_node,"global_position",Vector3(move_pos),time)
	# init 初始化 旋转的平滑插值 
	var basis = Basis()
#	欧拉角的默认旋转顺序: YXZ 
	var axisX = Vector3(1, 0, 0)
	var rotation_amountX = (move_rot.x)
	var axisY = Vector3(0, 1, 0)
	var rotation_amountY = (move_rot.y)
	var axisZ = Vector3(0, 0, 1)
	var rotation_amountZ = (move_rot.z)
	
	basis = Basis(axisZ, rotation_amountZ) * basis
	basis = Basis(axisX, rotation_amountX) * basis
	basis = Basis(axisY, rotation_amountY) * basis
	
	var my_lambda = func (weight): 
		var a = Quaternion(basis)
		var b = Quaternion(move_node.transform.basis)
		var c = a.slerp(b,weight/100.0)
		move_node.transform.basis = Basis(c)
	pass
	
	tween.tween_method(func(weight): my_lambda.call(weight), 0, 100,time)

	pass

#方案2 采用I3D 的提供的API interpolate_with 完成平滑插值
func camera_move_2(move_node,move_pos:Vector3,move_rot:Vector3,time):
	var tween=create_tween().set_parallel()
	
	# init 初始化 旋转的平滑插值 
	var basis = Basis()
#	欧拉角的默认旋转顺序: YXZ 
	var axisX = Vector3(1, 0, 0)
	var rotation_amountX = (move_rot.x)
	var axisY = Vector3(0, 1, 0)
	var rotation_amountY = (move_rot.y)
	var axisZ = Vector3(0, 0, 1)
	var rotation_amountZ = (move_rot.z)
	
	basis = Basis(axisZ, rotation_amountZ) * basis
	basis = Basis(axisX, rotation_amountX) * basis
	basis = Basis(axisY, rotation_amountY) * basis
	
	var target_transform = Transform3D(basis,move_pos) #init 旋转和位移
	var my_lambda = func (weight): 
		move_node.transform  = move_node.transform.interpolate_with(target_transform, weight/100.0)
	pass
	
	tween.tween_method(func(weight): my_lambda.call(weight), 0, 100,time)

	pass