0
\$\begingroup\$

To summarize, my ramp is acting like a wall even if it is created to have a collision and mesh that fits its shape.

I have tried:

  • Putting the max angle to 90

  • using different ramps (CSG & mesh)

  • I have stopped everything but the basics that impact movement.

... but still I get blocked by ramps as if they are a wall. I am using move and slide and in all the tutorials I have looked at to see why it doesn't work, there is no major difference between my code and the tutorial. So what can be the problem?

Here is my code:

public partial class MovementPlayer : CharacterBody3D
{
    #region Movement
    [Export]
    private int Maxspeed = 8;
    private Vector3 direction;
    [Export]
    private float jumpspeed = 5.0f;
    private float gravity;
    [Export]
    private float accelerationSpeed;
    [Export]
    private float decelerationSpeed;
    private Vector3 PositionBeforeMove { get; set; }

    private Vector3 TemporaryVelocity;
    #endregion
    Node3D Head;
    [Export]//moves objects variables etc to the editor
    NodePath HeadPath;
    Camera3D PlayerCamera;
    [Export]
    NodePath PCameraPath;
    [Export]
    private float mousesensitivity = 2.5f;
    [Export]
    RayCast3D raycast;
    [Export]
    Node3D RayCasst;
    [Export]
    private bool Thirdperson;
    [Export]
    private float interpolateweight;

    // Called when the node enters the scene tree for the first time.
    // Called every frame. 'delta' is the elapsed time since the previous frame.
    public override void _Ready()
    {
        GD.Print("Override");
        Head = GetNode<Node3D>(HeadPath);
        PlayerCamera = GetNode<Camera3D>(PCameraPath);
        gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity") * -1;
        //Input.MouseMode = Input.MouseModeEnum.Captured;
        if (Thirdperson == true)
        {
            PlayerCamera.GlobalPosition = new Vector3(PlayerCamera.GlobalPosition.X, PlayerCamera.GlobalPosition.Y + 2, PlayerCamera.GlobalPosition.Z+4);
            PlayerCamera.RotateX(Mathf.DegToRad(-20));
        }
    }

    public override void _Process(double delta)
    {
        base._PhysicsProcess(delta);
        ProccesInput(delta);
        ProccesMovement((float)delta);
      //is on floor is working
        /*if (raycast.IsColliding())
        {
            //GD.Print("RayHitSomething");
            RaycastCollision(raycast.GetCollisionPoint(),raycast.GetCollisionNormal());
            
        }*/
    }
    #region Camera&Keys
    public void ProccesInput(double value)
    {
        direction = new Vector3();
        var InputMovementVector = new Vector2();

        if (Input.IsActionPressed("Move_Up") == true)
        {
            InputMovementVector.Y += 1;
            //GD.Print("Player Angle Is:" + RotationDegrees.Y);
            //GD.Print("Camera Angle Is:" + Head.RotationDegrees.X);
            //GD.Print("Head Z Rotation" + Head.RotationDegrees.Z);
            //GD.Print("MovingForward");

        }
        if (Input.IsActionPressed("Move_Down") == true)
        {
            InputMovementVector.Y += -1;
        }
        if (Input.IsActionPressed("Move_Left") == true)
        {
            InputMovementVector.X += -1;
        }
        if (Input.IsActionPressed("Move_Right") == true)
        {
            InputMovementVector.X += 1;
        }
        InputMovementVector = InputMovementVector.Normalized();
        direction -= GlobalTransform.Basis.Z * InputMovementVector.Y;
        direction += GlobalTransform.Basis.X * InputMovementVector.X;
       /* if(IsOnFloor() && Input.IsActionJustPressed("Move_Jump"))
        {
            direction.Y = jumpspeed;
        }*/
    }

    public void ProccesMovement(float value)
    {
        PositionBeforeMove = GlobalPosition;   
        TemporaryVelocity = Velocity;
        /*if (direction.Y != 0)
        {
            TemporaryVelocity.Y += direction.Y;
        }*/
        //apply gravity
        TemporaryVelocity.Y += value * gravity;
        direction = direction.Normalized();
        //horizontalMovement
        var horizontalVelocity = TemporaryVelocity;
        horizontalVelocity.Y = 0;
 
        var target = direction;
        target *= Maxspeed;
        //Speed up or slow down
        float acceleration;
        if (direction.Dot(horizontalVelocity) > 0)
        {
            acceleration = accelerationSpeed;
        }
        else
        {
            acceleration = decelerationSpeed;
        }

        horizontalVelocity = horizontalVelocity.Lerp(target, acceleration * value);
        TemporaryVelocity.X = horizontalVelocity.X;
        TemporaryVelocity.Z = horizontalVelocity.Z;
        Velocity = TemporaryVelocity;
        PositionBeforeMove = GlobalPosition;
        MoveAndSlide();
        raycast.ForceRaycastUpdate();
       
    }
    public override void _Input(InputEvent @event)
    {
       // GD.Print("OverridingInputforMouse"); is working
        base._Input(@event);
        if (Input.MouseMode == Input.MouseModeEnum.Visible)
        {
            InputEventMouseMotion mouseMotion = @event as InputEventMouseMotion;
            if (mouseMotion!=null)
            {
                HandleCameraRotation(mouseMotion);
                
            }
        }
    }

    public void HandleCameraRotation(InputEventMouseMotion mouseMotion)
    {
        if (Thirdperson==false) {
             //rotates around the x axis to look down and up
            Head.RotateX(Mathf.DegToRad(-mouseMotion.Relative.Y * mousesensitivity));
            //set the degrees
            Head.RotationDegrees = new Vector3(Mathf.Clamp(Head.RotationDegrees.X, -70, 70), 0, 0); 
        }
        //rotate around the y axis to turn left and right
        RotateY(Mathf.DegToRad(-mouseMotion.Relative.X * mousesensitivity));

        GD.Print("Player velocity" + Velocity);
    }
   
    #endregion
    public void RaycastCollision( Vector3 Globalpositionpoint,Vector3 Normal)
    {
        Vector3 Change=new Vector3(0,Globalpositionpoint.Y-PositionBeforeMove.Y,Globalpositionpoint.Z-PositionBeforeMove.Z);
        var xform =Align_With_Normal(GlobalTransform, Normal);
        GlobalTransform = GlobalTransform.InterpolateWith(xform,interpolateweight);
        GD.Print("Current Z Angle" + GlobalRotationDegrees.Z);
        GD.Print("Current Y Angle" + GlobalRotationDegrees.Y);
        GD.Print("Current X Angle" + GlobalRotationDegrees.X);
        // RotateX(-Angle);
        Velocity = new Vector3(TemporaryVelocity.X, Change.Y, Change.X);
        MoveAndSlide();
    }

    public Transform3D Align_With_Normal(Transform3D xform,Vector3 Normal)
    {
        xform.Basis.Y =Normal;
        xform.Basis.Z = -xform.Basis.Z.Cross(Normal);
        xform.Basis = xform.Basis.Orthonormalized();
        xform.Basis.Z = Basis.Z;
        return xform;
    }
}

If it is needed I'll try to film a video to show how it looks. Here is the pictures:PlayerProfile1 PlayerProfil2 And here is the Video:Here is the video [i dont know why i cant move right now,it wasnt like that when i opened the gamefile last time so for now just ignore it i will fix it in the future]

\$\endgroup\$
8
  • 1
    \$\begingroup\$ Why are you calling _PhysicsProcess from _Process? I would expect that placing your code in _PhysicsProcess instead of _Process and not using _Process at all to work better. - How do the colliders look like? Can you post picture of the colliders of the character and the ramps? \$\endgroup\$
    – Theraot
    Feb 1 at 18:08
  • \$\begingroup\$ I have added pictures and a video,the problem with moving around is coused by the floor so if the video looks laggy to you thats why \$\endgroup\$
    – NEWBIE
    Feb 2 at 18:45
  • \$\begingroup\$ Sadly I cannot see the colliders for the environment. You can enable Visible Collision Shapes in the Debug menu to have them show up while playing. I see you have an issue with the floor that makes the character get stuck, that same issue might be the problem with the ramps. Did you try not using _Process as I suggested? Anyway, here is another idea: Add a collider with a SeparationRayShape3D pointing down and slightly ahead of the character, like this: i.stack.imgur.com/L9Y6p.png - usually you would not need that, but hey. \$\endgroup\$
    – Theraot
    Feb 2 at 19:14
  • \$\begingroup\$ when i switched from process to physicsproccess all of my movement broke,also i dont understand what i will be using the seperationrayshape3d for,could you please eleborate furthur so i can try that method too \$\endgroup\$
    – NEWBIE
    Feb 2 at 20:44
  • \$\begingroup\$ The SeparationRayShape3D will automatically push out the body. Just add it. \$\endgroup\$
    – Theraot
    Feb 2 at 20:45

1 Answer 1

0
\$\begingroup\$

Answer: The fix to this problem was to redo the whole movement script and the character. The code is here:

    public partial class Movement2 : CharacterBody3D
{
    # region export
    [Export]
    NodePath Head;
    [Export]
    NodePath PCameraPath;
    [Export]
    RayCast3D Raycast;
    [Export]
    private bool Thirdperson;
    [Export]
    private float MaxSpeed;
    [Export]
    private float acceleration;
    [Export]
    private float deacceleration;
    [Export]
    private float Jumpspeed;
    [Export]
    private float mousesensitivity = 2.5f;
    [Export]
    private float interpolateweight;
    [Export]
    CollisionShape3D scale;
    [Export]
    RayCast3D GrabRay;
    #endregion
    private Vector3 PositionBeforeMove { get; set; }
    private Vector3 direction;
    private Vector3 TemporaryVelocity;
    Vector2 planemovement = new Vector2();
    PhysicsDirectSpaceState3D spacestate;
    #region bools
    private bool MovementClass;
    private bool Jumping;
    private bool launch;
    private bool Chrouch;
    private bool grabbool;
    #endregion

    Node3D HeadNode;
    Camera3D PlayerCamera;
    // Get the gravity from the project settings to be synced with RigidBody nodes.
    public float gravity = ProjectSettings.GetSetting("physics/3d/default_gravity").AsSingle();
    public override void _Ready()
    {
        GD.Print("Override");
        HeadNode = GetNode<Node3D>(Head);
        PlayerCamera = GetNode<Camera3D>(PCameraPath);
        gravity = (float)ProjectSettings.GetSetting("physics/3d/default_gravity") * -1;
        //Input.MouseMode = Input.MouseModeEnum.Captured;
        if (Thirdperson == true)
        {
            PlayerCamera.GlobalPosition = new Vector3(PlayerCamera.GlobalPosition.X, PlayerCamera.GlobalPosition.Y + 2, PlayerCamera.GlobalPosition.Z + 4);
            PlayerCamera.RotateX(Mathf.DegToRad(-20));
        }

    }
    public override void _PhysicsProcess(double delta)
    {
        if (Jumping == true && Input.IsActionJustPressed("Move_Jump") == true)
        {
            launch = true;
        }
        if (IsOnFloor() == true)
        {
            Jumping = false;
        }
        if (Raycast.IsColliding())
        {
            RaycastCollision(Raycast.GetCollisionPoint(), Raycast.GetCollisionNormal());

        }
        input((float)delta); //spitting into 2 classes dont impact movement above edges
    }
    public void Movement(float delta)
    {
        PositionBeforeMove = Raycast.GlobalPosition;
        TemporaryVelocity = Velocity;
        
        if (Jumping==true && IsOnFloor() == true)
        {
            TemporaryVelocity.Y = Jumpspeed;
        }
        if (IsOnFloor() == false ) 
        {
            TemporaryVelocity.Y += delta * gravity;
            Jumping = true;
            //works
        }
        if (Jumping == false || Chrouch == true||grabbool==true)
        {
            TemporaryVelocity.Y = 0;
        }
        if (launch == true)//works like butter hehheheheh
        {
            launch = false;
            Vector3 launchvector = new Vector3(TemporaryVelocity.X, 0, TemporaryVelocity.Z + 10);
            TemporaryVelocity -= launchvector * PlayerCamera.GlobalBasis.Z;
        }
        direction = direction.Normalized();
        //horizontalMovement
        var horizontalVelocity = TemporaryVelocity;
        horizontalVelocity.Y = 0;

        var target = direction;
        target *= MaxSpeed;
        //Speed up or slow down
        float accelerationn;
        if (direction.Dot(horizontalVelocity) > 0)
        {
            accelerationn = acceleration;
        }
        else
        {
            accelerationn = deacceleration;
        }

        horizontalVelocity = horizontalVelocity.Lerp(target, accelerationn * delta);
        TemporaryVelocity.X = horizontalVelocity.X;
        TemporaryVelocity.Z = horizontalVelocity.Z;
        Velocity = TemporaryVelocity;
        MoveAndSlide();

    } 
    public void input(float delta)
    {
        direction = new Vector3();
        planemovement = new Vector2();
        if (Input.IsActionPressed("Move_Up") == true)//jumping while going forward
        {
        
            planemovement.Y -= 1;
            MovementClass = true;
        }
        if (Input.IsActionPressed("Move_Down") == true)//works
        {
     
            planemovement.Y += 1;
            MovementClass = true;
        }
        if (Input.IsActionPressed("Move_Left") == true)//jumping while going Left
        {
         
            planemovement.X += 1;
            MovementClass = true;
        }
        if (Input.IsActionPressed("Move_Right") == true)//works
        {
     
            planemovement.X -= 1;
            MovementClass = true;
        }
        if ( Input.IsActionJustPressed("Move_Jump") ==true)//working
        {
            Jumping = true;
            direction.Y += 1;
            MovementClass = true;
        }
        if (Input.IsActionPressed("Chrouch"))
        {
            scale.Scale=new Vector3(scale.Scale.X,Scale.Y/2,scale.Scale.Z);
            Chrouch = true;
        }
        else
        {
            scale.Scale = new Vector3(scale.Scale.X, Scale.Y, scale.Scale.Z);
            Chrouch = false;
        }
        if (Input.IsActionJustPressed("Grab") == true && GrabRay.IsColliding()==true)
        {
            Grab(GrabRay.GetCollisionPoint());
            GD.Print("Grab");
        }
        if(Input.IsActionPressed("Grab")==false)
        {
            grabbool = false;
        }
        if (MovementClass == true)
        {
            planemovement = planemovement.Normalized();
            direction += GlobalBasis.Z * planemovement.Y;
            direction -= GlobalBasis.X * planemovement.X;
            Movement(delta);
           
        }
    } //ignore works fine
    public override void _Input(InputEvent @event)
    {
        // GD.Print("OverridingInputforMouse"); is working
        base._Input(@event);
        if (Input.MouseMode == Input.MouseModeEnum.Visible)
        {
            InputEventMouseMotion mouseMotion = @event as InputEventMouseMotion;
            if (mouseMotion != null)
            {
                HandleCameraRotation(mouseMotion);

            }


        }

    }
    public void HandleCameraRotation(InputEventMouseMotion mouseMotion)
    {


        if (Thirdperson == false)
        {
            //rotates around the x axis to look down and up
            HeadNode.RotateX(Mathf.DegToRad(-mouseMotion.Relative.Y * mousesensitivity));
            //set the degrees
            HeadNode.RotationDegrees = new Vector3(Mathf.Clamp(HeadNode.RotationDegrees.X, -70, 70), 0, 0);
        }
        //rotate around the y axis to turn left and right
        RotateY(Mathf.DegToRad(-mouseMotion.Relative.X * mousesensitivity));

    }
    public void RaycastCollision(Vector3 Globalpositionpoint, Vector3 Normal)
    {
        Vector3 Change = new Vector3(0, Globalpositionpoint.Y - PositionBeforeMove.Y, Globalpositionpoint.Z - PositionBeforeMove.Z);
        if (Mathf.Floor(Globalpositionpoint.Y) == Mathf.Floor(PositionBeforeMove.Y) && Jumping == false)
        {
            Velocity = new Vector3(TemporaryVelocity.X, Change.Y, TemporaryVelocity.Z);
            MoveAndSlide();
        }
        var xform = Align_With_Normal(GlobalTransform, Normal);
        GlobalTransform = GlobalTransform.InterpolateWith(xform, interpolateweight);
        
    }

    public Transform3D Align_With_Normal(Transform3D xform, Vector3 Normal)
    {
        xform.Basis.Y = Normal;
        xform.Basis.Z = -xform.Basis.Z.Cross(Normal);
        xform.Basis = xform.Basis.Orthonormalized();
        xform.Basis.Z = Basis.Z;
        return xform;
    }
  
    public void Grab(Vector3 RayPoint)
    {
        GlobalPosition = GlobalPosition.Lerp(RayPoint, interpolateweight);
        grabbool = true;
    }//working
}
```
\$\endgroup\$
3
  • \$\begingroup\$ This answer would be more useful to future readers if you explain what's different about this code and how it solves the problem. That way another developer struggling with a similar problem won't have to just copy your code — they'll learn what they need to do to fix their own version. \$\endgroup\$
    – DMGregory
    Feb 21 at 15:59
  • \$\begingroup\$ i am not really sure why it worked in the first place,i just had enough then i redid it with very little change and suddenly it worked,if i knew why i would have eleborated furthur :( \$\endgroup\$
    – NEWBIE
    Feb 21 at 18:07
  • \$\begingroup\$ If this code solved your problem then, you can click the ✅ icon in the top left to mark it as "Accepted" \$\endgroup\$
    – DMGregory
    Feb 21 at 20:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .