2D object does not rotate

Godot Version

Godot v4.4.1.stable.mono - macOS Sequoia (15.4.0) - Multi-window, 1 monitor - Metal (Forward+) - integrated Apple M3 Pro (Apple9) - Apple M3 Pro (11 threads)

Disclamer

Hello, I’m very new to Godot and gamedev - basically my second day playing around. But I’ve been programming on c# for few years so I do have some understanding of programming.

Question

I’ve been playing with “Your First 2D Game” from godot documentation.
After walking through this “Getting Started” I tried to make a special mob, which would do some sort of player tracking and chasing him. The tracking part works fine, but I struggle to understand why my mob doesn’t rotate towards the player but stays locked with his initial rotation. By the flickering I see on playthrough I consider that rotation is being set for one frame or so, but than returns back to initial. Any help will be appreciated. I tried to attach a short explanation video, but I can’t load mp4 files.
Lower I provide related code code:

// I do have a timer in main scene which triggers every 0.5 seconds
private void OnMobTimerTimeout()
    {
        var mobBoss = TryGetMobBoss();
        if (mobBoss is not null)
        {
            var player = GetNode<Player>("Player");
            mobBoss.Recalibrate(player.Position);
        }
        else if (_score % 15 == 0 && _score > 0)
        {
            SpawnBossMob();
        }
    }

// Retruns mob boss if he exists in the scene
private BossMob? TryGetMobBoss()
    {
        var bossMob = GetTree().GetFirstNodeInGroup("BossMob");
        return bossMob as BossMob;
    }

private void SpawnBossMob()
    {
        var bossMob = BossMobScene.Instantiate<BossMob>();
        
        var mobSpawnLocation = GetSpawnLocation();
        bossMob.Position = mobSpawnLocation.Position;
        
        var player = GetNode<Player>("Player");
        bossMob.Recalibrate(player.Position);
        AddChild(bossMob);
    }

private PathFollow2D GetSpawnLocation()
    {
        var mobSpawnLocation = GetNode<PathFollow2D>("MobPath/MobSpawnLocation");
        mobSpawnLocation.ProgressRatio = GD.Randf();

        return mobSpawnLocation;
    }

// Recalibrate method in BossMob class
public void Recalibrate(Vector2 playerPosition)
    {
        var velocity = new Vector2(Speed, 0);
        var newAngle = (playerPosition - Position).Angle();
        
       // This does not rotate the mob for some reason
        Rotation = newAngle;
        LinearVelocity = velocity.Rotated(newAngle);

        _lifeCycles--;
        if (_lifeCycles == 0)
        {
            // TODO: puff animation
            QueueFree();
        }
    }

Here is my MobBoss scene -

[gd_scene load_steps=6 format=3 uid="uid://c5r5rggmcpawg"]

[ext_resource type="Script" uid="uid://cms818jjbxb2y" path="res://BossMob.cs" id="1_6lbbi"]
[ext_resource type="Texture2D" uid="uid://se46a8wlr5g5" path="res://art/enemyWalking_1.png" id="1_wixse"]
[ext_resource type="Texture2D" uid="uid://co34uw0k2lfjp" path="res://art/enemyWalking_2.png" id="2_6lbbi"]

[sub_resource type="SpriteFrames" id="SpriteFrames_blbt7"]
animations = [{
"frames": [{
"duration": 1.0,
"texture": ExtResource("1_wixse")
}, {
"duration": 1.0,
"texture": ExtResource("2_6lbbi")
}],
"loop": true,
"name": &"walk",
"speed": 3.0
}]

[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_yjb3h"]
radius = 64.0
height = 136.0

[node name="BossMob" type="RigidBody2D" groups=["BossMob", "Mobs"]]
collision_mask = 0
gravity_scale = 0.0
script = ExtResource("1_6lbbi")

[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
scale = Vector2(0.75, 1)
sprite_frames = SubResource("SpriteFrames_blbt7")
animation = &"walk"
frame = 1
frame_progress = 0.606371

[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(-3, 0)
rotation = 1.5708
scale = Vector2(0.75, 0.75)
shape = SubResource("CapsuleShape2D_yjb3h")

[node name="VisibleOnScreenNotifier2D" type="VisibleOnScreenNotifier2D" parent="."]

If I recall correctly I think when a mob is spawned in the tutorial its rotation is set. Have you amended that?

I will see if I can find it.

Here it is:

# Add some randomness to the direction.
	direction += randf_range(-PI / 4, PI / 4)
	mob.rotation = direction

I could not find a link to that point but it is in the example code block just above this link:

PS I have presumed here that your boss mob was based on the original mob set up.

PPS You may have already overridden this, I should have looked at your code in a bit more detail. Another possibility is that if you have rotation enabled on a PathFollw2D this will override the rotation of an object following the path too. Here in the docs:

Much thanks for your help.
I had Rotates enabled on PathFollow2D but sadly turning them of didn’t help. I tried.

And I guess it should not have helped, cause in my method SpawnBossMob I don’t use Rotation property of returned PathFollow2D and my node doesn’t follow the path (as far as I understood) - it only uses initial position, taken from the path, but the movement is set by LinearVelocity inside Recalibrate method.

I use only mobSpawnLocation.Position and than I set rotation inside Recalibrate method.

var newAngle = (playerPosition - Position).Angle();
        
Rotation = newAngle;
1 Like

Oh, I was trying to remember what that beach ball icon was for and it is for a RigidBody2D. I am not too familiar with these but I am pretty sure you are not supposed to set rotations etc directly during gameplay. (Initially pre-spawn sure, but not once it is added to the tree).

It cannot be controlled directly, instead, you must apply forces to it (gravity, impulses, etc.), and the physics simulation will calculate the resulting movement, rotation, react to collisions, and affect other physics bodies in its path.

So although you set the rotation the physics engine is immediately overwriting it. You may need to change your node type or approach this in a different way for a RigidBody2D.

Oh, I see.
Ok, thank you than, gonna browse for mor appropriate node type.

1 Like