#Vectors not rotating effectively

3 messages · Page 1 of 1 (latest)

idle glacier
#

Hey there,

So I'm working on a Vampire Survivors type of game.

I want to have a knockback area which is always active. So I've decided to make the enemies steer away from my character when they are under a certain distance in pixels (that's what RotationDistance is for).

However, as shown in the video in the last reply to the thread, even if I put 90 degrees for rotation, the directionToPlayer vector doesn't rotate at all that much.

I'm not really sure why. I've coded a RotateVector method to help me with that but tbh, I'm not really sure it's working as intended.

At first I was thinking that maybe the acceleration was the problem but even if that was the problem I don't really know how to solve that.

I'm completely lost right now and I have a hard time putting the math down and all. I'm not particularly good at linear algebra.

As you can see in the video, when I put 600 enemies, the "knockback area" is very little on the first time the enemies go close to the player. This is just a consequence of the previous problem.

And, especially the further away the enemies are, the closer they get to the player, which is why I thought acceleration was the problem.

As an extra info, enemies spawn evenly in concentric circles outside of the camera.

I will provide the code in the next message in the thread.

I hope someone can help me with that because it's kind of a very essential feature of my game.

Thank you a lot for your help in any way!

P.S : For experienced C# programmers, I hope this code is not too shitty, I'm just getting started in C#. (that's also my real first game ever so yeah...). I know the naming is not perfect right now (like I'm changing cases and all) but yeah, I'll go over it later when this is solved.

#
using Godot;
using System;

public partial class DarkGreyAlien : CharacterBody2D
{
    private const int SkipFrames = 3;

    private int MaxSpeed = 180;
    private int Acceleration = 300;
    private int FrameCount = 0;

    private Node PositionsNode;
    private RayCast2D rayCast;
    
    private float VectorRotationDegrees = 45; // Min 45 Max 120
    private float RotationDistance = 500; // Min 500 Max 700
    
    public override void _Ready()
    {
        PositionsNode = GetNode("/root/Positions");
        rayCast = GetNode<RayCast2D>("RayCast2D"); 
    }

    public override void _PhysicsProcess(double delta)
    {
        if (PositionsNode != null && rayCast != null) 
        {
            Vector2 playerPosition = (Vector2)PositionsNode.Get("player_position");
            FrameCount++;
            if (FrameCount % SkipFrames == 0)
            {
                System.Numerics.Vector2 directionToPlayer = ToNumericsVector(playerPosition) - ToNumericsVector(GlobalPosition);
            
                if (directionToPlayer.Length() <= RotationDistance)
                {
                    directionToPlayer = RotateVector(directionToPlayer, VectorRotationDegrees);
                }

                directionToPlayer = System.Numerics.Vector2.Normalize(directionToPlayer);
                
                Velocity = Velocity.MoveToward(
                    ToGodotVector(directionToPlayer * MaxSpeed * 2),
                    Acceleration * (float)delta
                );
                // DEBUG RAYCAST
                float angle = (float)Math.Atan2(Velocity.Y, Velocity.X);
                angle *= 180f / (float)Math.PI;
                angle -= 90f;
                rayCast.RotationDegrees = angle;
                rayCast.TargetPosition = new Vector2(0, Velocity.Length() / 2);
            }
            Position += Velocity * (float)delta;
        }
    }
#
    private System.Numerics.Vector2 ToNumericsVector(Godot.Vector2 vec)
    {
        return new System.Numerics.Vector2(vec.X, vec.Y);
    }

    private Godot.Vector2 ToGodotVector(System.Numerics.Vector2 vec)
    {
        return new Godot.Vector2(vec.X, vec.Y);
    }
    
    private System.Numerics.Vector2 RotateVector(System.Numerics.Vector2 vec, float degrees)
    {
        double radians = Math.PI / 180 * degrees;
        float cos = (float)Math.Cos(radians);
        float sin = (float)Math.Sin(radians);

        return new System.Numerics.Vector2(
            vec.X * cos - vec.Y * sin,
            vec.X * sin + vec.Y * cos
        );
    }
    
    
    private bool IsFacingPlayer(System.Numerics.Vector2 facingDirection, System.Numerics.Vector2 directionToPlayer)
    {
        float dot = facingDirection.X * directionToPlayer.X + facingDirection.Y * directionToPlayer.Y;

        return dot > 0.99;
    }
}