Răsfoiți Sursa

Merge pull request #41402 from saneery/interpolated-camera-process-mode

Rémi Verschelde 3 ani în urmă
părinte
comite
567083b981

+ 9 - 0
doc/classes/InterpolatedCamera.xml

@@ -22,6 +22,9 @@
 		<member name="enabled" type="bool" setter="set_interpolation_enabled" getter="is_interpolation_enabled" default="false">
 			If [code]true[/code], and a target is set, the camera will move automatically.
 		</member>
+		<member name="process_mode" type="int" setter="set_process_mode" getter="get_process_mode" enum="InterpolatedCamera.InterpolatedCameraProcessMode" default="1">
+			The camera's process callback. See [enum InterpolatedCameraProcessMode].
+		</member>
 		<member name="speed" type="float" setter="set_speed" getter="get_speed" default="1.0">
 			How quickly the camera moves toward its target. Higher values will result in tighter camera motion.
 		</member>
@@ -30,5 +33,11 @@
 		</member>
 	</members>
 	<constants>
+		<constant name="INTERPOLATED_CAMERA_PROCESS_PHYSICS" value="0" enum="InterpolatedCameraProcessMode">
+			The camera updates with the [code]_physics_process[/code] callback.
+		</constant>
+		<constant name="INTERPOLATED_CAMERA_PROCESS_IDLE" value="1" enum="InterpolatedCameraProcessMode">
+			The camera updates with the [code]_process[/code] callback.
+		</constant>
 	</constants>
 </class>

+ 34 - 10
scene/3d/interpolated_camera.cpp

@@ -35,12 +35,10 @@
 void InterpolatedCamera::_notification(int p_what) {
 	switch (p_what) {
 		case NOTIFICATION_ENTER_TREE: {
-			if (Engine::get_singleton()->is_editor_hint() && enabled) {
-				set_process_internal(false);
-			}
-
+			_update_process_mode();
 		} break;
-		case NOTIFICATION_INTERNAL_PROCESS: {
+		case NOTIFICATION_INTERNAL_PROCESS:
+		case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
 			if (!enabled) {
 				break;
 			}
@@ -50,7 +48,7 @@ void InterpolatedCamera::_notification(int p_what) {
 					break;
 				}
 
-				float delta = speed * get_process_delta_time();
+				float delta = speed * (process_mode == INTERPOLATED_CAMERA_PROCESS_PHYSICS ? get_physics_process_delta_time() : get_process_delta_time());
 				Transform target_xform = node->get_global_transform();
 				Transform local_transform = get_global_transform();
 				local_transform = local_transform.interpolate_with(target_xform, delta);
@@ -76,6 +74,18 @@ void InterpolatedCamera::_notification(int p_what) {
 	}
 }
 
+void InterpolatedCamera::set_process_mode(InterpolatedCameraProcessMode p_mode) {
+	if (process_mode == p_mode) {
+		return;
+	}
+	process_mode = p_mode;
+	_update_process_mode();
+}
+
+InterpolatedCamera::InterpolatedCameraProcessMode InterpolatedCamera::get_process_mode() const {
+	return process_mode;
+}
+
 void InterpolatedCamera::_set_target(const Object *p_target) {
 	ERR_FAIL_NULL(p_target);
 	set_target(Object::cast_to<Spatial>(p_target));
@@ -99,13 +109,19 @@ void InterpolatedCamera::set_interpolation_enabled(bool p_enable) {
 		return;
 	}
 	enabled = p_enable;
-	if (p_enable) {
-		if (is_inside_tree() && Engine::get_singleton()->is_editor_hint()) {
-			return;
-		}
+	_update_process_mode();
+}
+
+void InterpolatedCamera::_update_process_mode() {
+	if (Engine::get_singleton()->is_editor_hint() || !enabled) {
+		set_process_internal(false);
+		set_physics_process_internal(false);
+	} else if (process_mode == INTERPOLATED_CAMERA_PROCESS_IDLE) {
 		set_process_internal(true);
+		set_physics_process_internal(false);
 	} else {
 		set_process_internal(false);
+		set_physics_process_internal(true);
 	}
 }
 
@@ -132,12 +148,20 @@ void InterpolatedCamera::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_interpolation_enabled", "target_path"), &InterpolatedCamera::set_interpolation_enabled);
 	ClassDB::bind_method(D_METHOD("is_interpolation_enabled"), &InterpolatedCamera::is_interpolation_enabled);
 
+	ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &InterpolatedCamera::set_process_mode);
+	ClassDB::bind_method(D_METHOD("get_process_mode"), &InterpolatedCamera::get_process_mode);
+
 	ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "target"), "set_target_path", "get_target_path");
 	ADD_PROPERTY(PropertyInfo(Variant::REAL, "speed"), "set_speed", "get_speed");
 	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_interpolation_enabled", "is_interpolation_enabled");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "process_mode", PROPERTY_HINT_ENUM, "Physics,Idle"), "set_process_mode", "get_process_mode");
+
+	BIND_ENUM_CONSTANT(INTERPOLATED_CAMERA_PROCESS_PHYSICS);
+	BIND_ENUM_CONSTANT(INTERPOLATED_CAMERA_PROCESS_IDLE);
 }
 
 InterpolatedCamera::InterpolatedCamera() {
 	enabled = false;
 	speed = 1;
+	process_mode = INTERPOLATED_CAMERA_PROCESS_IDLE;
 }

+ 15 - 0
scene/3d/interpolated_camera.h

@@ -36,9 +36,19 @@
 class InterpolatedCamera : public Camera {
 	GDCLASS(InterpolatedCamera, Camera);
 
+public:
+	enum InterpolatedCameraProcessMode {
+		INTERPOLATED_CAMERA_PROCESS_PHYSICS,
+		INTERPOLATED_CAMERA_PROCESS_IDLE
+	};
+
+private:
 	bool enabled;
 	real_t speed;
 	NodePath target;
+	InterpolatedCameraProcessMode process_mode;
+
+	void _update_process_mode();
 
 protected:
 	void _notification(int p_what);
@@ -56,7 +66,12 @@ public:
 	void set_interpolation_enabled(bool p_enable);
 	bool is_interpolation_enabled() const;
 
+	void set_process_mode(InterpolatedCameraProcessMode p_mode);
+	InterpolatedCameraProcessMode get_process_mode() const;
+
 	InterpolatedCamera();
 };
 
+VARIANT_ENUM_CAST(InterpolatedCamera::InterpolatedCameraProcessMode);
+
 #endif // INTERPOLATED_CAMERA_H