bh_earth0
bh_earth0

Reputation: 2834

update node3d cube.position inside Task.Run ? ( goal is to animate object in circular path.)

in godot 4.3 , c# .

i want to update gui or node3d object position inside Task.run.

end goal is to animate object. in circle path.

it also needs to be in the code.
using gui is not an option for me.. it just complicates...

expected animation duration:

3.6 seconds => 50ms * 360degree/5step ;

actual behavior:

When I run this code, UI doesn't do anything. it freezes for a while...

code

public partial class Scene1 : Node3D
{
    public override void _Ready(){};
    public override void _Process(double delta){};   

    void Button_Move_in_Circle_onClick() => MoveCube_inCirclularPath();
    
    private void MoveCube_inCirclularPath()
    {
        Task.Run( () => 
        { 
            //cube y is Height, move it to 2meter. above ground;
            InvokeHelper.CallDeferred(() =>{
                cube.position.x = 2;
            });

           for (int i = 0; i < 360; i = i +5)
           {
               Thread.Sleep(50);
               var pt = GetCircleCoordinates_FromAngle(i, 4);

               InvokeHelper.CallDeferred(() =>{
                   cube.position.x = pt.x;
                   cube.position.z = pt.y;
               });
           }

        });
    }

    public static (double x, double y) GetCircleCoordinates_FromAngle(double angleDegrees, double distance)
    {
        double angleRadians = angleDegrees * Math.PI / 180.0;

        double x = distance * Math.Cos(angleRadians);
        double y = distance * Math.Sin(angleRadians);
        return (x, y);
    }

}

InvokeHelper.cs

using Godot;
using System;

public static class InvokeHelper
{
    /// <summary>
    /// in winforms equivalent is  *this.Invoke( delegate { } )* 
    /// </summary>
    public static void CallDeferred(this Action action)
    {
        Callable.From(action).CallDeferred();
    }
}

Upvotes: 0

Views: 30

Answers (2)

user2635469
user2635469

Reputation: 77

If all you want is to animate an object in a circular path, you can create a curve3d: https://docs.godotengine.org/en/stable/classes/class_curve3d.html

with a pathfollow child:

https://docs.godotengine.org/en/stable/classes/class_pathfollow3d.html

then, you just add your object as a child of the pathfollow. To move the pathfollow along the path, just modify its progress_ratio. This technique also works for other, more complicated, paths.

Upvotes: 0

bh_earth0
bh_earth0

Reputation: 2834

adding async await, to task.Run , made it work.!!

  • (good thing) this doesnt require, async to be added to MoveCuve_xxx function.

now, i can see it animated. box is moving in circular path.


  private void MoveCube_inCirclularPath()
  {
      Task.Run(async () => 
      { 
          InvokeFn.CallDeferred(() => {
              cube.position.y = 2; // set height to 2 meter.   
          });

          for (int i = 0; i < 360; i = i + 2)
          {
              await Task.Delay(20);
              var pt = CircleHelper.GetCircleCoordinates_FromAngle(i, 4);

              InvokeFn.CallDeferred(() =>{
                  cube.position.x = pt.x;
                  cube.position.z = pt.y;
              });
          }

      });

  }

Upvotes: -1

Related Questions