Announcement

Collapse
No announcement yet.

DoN's 3D Pathfinding for Flying A.I. [Support Thread]

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #31
    Do you, by chance, have a write-up that I can follow along with starting from a C++ project? I am anxious to try this amazing looking tool

    I've reviewed some of the GitHub source, but haven't stumbled on the documentation mentioned in the QSG. I certainly can, and will, lumber through the code and figure out how the setup and initialization should be (if needed), but if you have a simple write up that would be helpful to me.

    Thank you,
    Jerry

    Comment


      #32
      There's no write-up for C++ that you can readily use right now (although the API is fully documented in the header).

      The Fly To node's C++ implementation (BTTask_FlyTo.cpp) offers a fair overview of the different ways you can access the plugin's C++ API. Search for SchedulePathfindingTask which is the main entry point and see how the result delegates are bound. All the C++ API functions are fully documented in the header (eg: For SchedulePathfindingTask see DonNavigationManager.h) that should help you get started with the API.

      If you're using BTTask_FlyTo.cpp as a reference you can totally ignore the CustomDelegatePayload conversions in the FlyTo impl which are just a way of overcoming idiosyncrasies in the impl of behavior tree tasks (those quirks are documented extensively inside the FlyTo code itself).

      Another approach is to open the sample project's BP_Navigator_Dummy blueprint which provides a good high-level overview of the API (see "DoN Navigation - direct API queries" comment box) which you can then translate into C++ by using right-click Go to Definition to see the corresponding C++ function for each node. Unlike the FlyTo node, this Blueprint contains only exactly what is necessary and may be easier to learn from.
      Last edited by VSZ; 04-27-2017, 02:00 PM.

      Steam Early Access: Drunk On Nectar - The Nature Simulator

      UE4 Plugins: DoN’s Dynamic Mesh FX | DoN’s 3D Pathfinding

      Comment


        #33
        Thank you again.

        Comment


          #34
          I just want to say that I've been massively impressed with this. Due to a little boolean error in my blueprint, I accidentally spawned a huge swarm of flying NPCs. I looked at the cloud of them and said, "Oh yeah, this is going to crash awesomely." Nope! They all came right at me and it looked amazing.

          Also, if anyone is wondering, this works perfectly with Voxelfarm (or any procedural mesh component based terrain). Pretty much out of the box, flying AI will navigate tunnels you dig or pre-determined caves with the cave module they recently integrated.

          TLDR - This is amazing.

          Comment


            #35
            Originally posted by Koniferus View Post
            I just want to say that I've been massively impressed with this. Due to a little boolean error in my blueprint, I accidentally spawned a huge swarm of flying NPCs. I looked at the cloud of them and said, "Oh yeah, this is going to crash awesomely." Nope! They all came right at me and it looked amazing.

            Also, if anyone is wondering, this works perfectly with Voxelfarm (or any procedural mesh component based terrain). Pretty much out of the box, flying AI will navigate tunnels you dig or pre-determined caves with the cave module they recently integrated.

            TLDR - This is amazing.
            Glad to hear that!

            If you enjoyed this system, do check out my latest plugin as well - "DoN's Mesh Painting With Paint Blob Collisions"

            It allows you to rapidly paint visual FX on any character/landscape/prop and generate endless gameplay possibilities with paint blob collisions!



            You can expect the same level of quality and commitment to excellence with this plugin as well!

            All - Feel free to post any questions about this new plugin on this forum thread.
            Last edited by VSZ; 05-12-2017, 01:24 AM.

            Steam Early Access: Drunk On Nectar - The Nature Simulator

            UE4 Plugins: DoN’s Dynamic Mesh FX | DoN’s 3D Pathfinding

            Comment


              #36
              Hey, [MENTION=14603]VSZ[/MENTION]! I think I found another bug w/ an easy fix. Seems like this call to IsDirectPathLineSweep in SchedulePathfindingTask should be passing the collision inflation value in QueryParams, yeah?

              Code:
              	// Do we have direct access to the goal?
              	FHitResult hitResult;
              	const bool bFindInitialOverlaps = true;
              	if (IsDirectPathLineSweep(CollisionComponent, Origin, Destination, hitResult, bFindInitialOverlaps))
              	{
              		....
              Recently implemented support for units flying in formation and the leader needs some inflation to ensure there's room for his buddies!
              Check out my ★★★★★ UE4 plugin if you want to go fast!
              • Feedback Event Factory: Perfect for managing sounds, particle systems, force feedback, camera shakes, time dilation, animations & more...all within a single Blueprint!

              Comment


                #37
                Originally posted by rcdarcey View Post
                Hey, [MENTION=14603]VSZ[/MENTION]! I think I found another bug w/ an easy fix. Seems like this call to IsDirectPathLineSweep in SchedulePathfindingTask should be passing the collision inflation value in QueryParams, yeah?

                Code:
                	// Do we have direct access to the goal?
                	FHitResult hitResult;
                	const bool bFindInitialOverlaps = true;
                	if (IsDirectPathLineSweep(CollisionComponent, Origin, Destination, hitResult, bFindInitialOverlaps))
                	{
                		....
                Recently implemented support for units flying in formation and the leader needs some inflation to ensure there's room for his buddies!
                Good point, will incorporate this into the next patch. Would love to see your bots flying in formation some time!

                Steam Early Access: Drunk On Nectar - The Nature Simulator

                UE4 Plugins: DoN’s Dynamic Mesh FX | DoN’s 3D Pathfinding

                Comment


                  #38
                  Originally posted by VSZ View Post
                  Good point, will incorporate this into the next patch. Would love to see your bots flying in formation some time!
                  Thanks, man! I'll send you a quick video sometime soon
                  Check out my ★★★★★ UE4 plugin if you want to go fast!
                  • Feedback Event Factory: Perfect for managing sounds, particle systems, force feedback, camera shakes, time dilation, animations & more...all within a single Blueprint!

                  Comment


                    #39
                    Just a heads up: the link to the Mesh Painting With Paint Blob Collision thread is broken (it's pointing to 'placeholder') XD
                    Happy Coding!

                    Comment


                      #40
                      Originally posted by FacePalm.exe View Post
                      Just a heads up: the link to the Mesh Painting With Paint Blob Collision thread is broken (it's pointing to 'placeholder') XD
                      Oops. Fixed the link, thank you so much for letting me know

                      Here's the forum thread for the Mesh Painting plugin again:
                      https://forums.unrealengine.com/show...lob-Collisions!

                      Steam Early Access: Drunk On Nectar - The Nature Simulator

                      UE4 Plugins: DoN’s Dynamic Mesh FX | DoN’s 3D Pathfinding

                      Comment


                        #41
                        4.16 version available!

                        Version 1.7 of DoN's 3D pathfinding with support for UE 4.16 is now available on Github: https://github.com/VSZue/DonAINavigation

                        Marketplace version has been submitted too!

                        Steam Early Access: Drunk On Nectar - The Nature Simulator

                        UE4 Plugins: DoN’s Dynamic Mesh FX | DoN’s 3D Pathfinding

                        Comment


                          #42
                          Hi!

                          First of all thank you for everything you do, this is truly great

                          I have issues with making this plugin work. I have replicated everything from your test map (number 1), but I end up with this error:

                          DoNNavigationLog:Error: Error: Invalid Origin (X=-420.000 Y=-3398.000 Z=942.000) passed to navigation path solver
                          DoNNavigationLog:Error: Error: Invalid Destination (X=116.000 Y=2135.000 Z=4307.000) passed to navigation path solver
                          DoNNavigationLog:Warning: Pawn's initial/final position overlaps an obstacle. Attempting to find substitute vector (a nearby free spot) for pathfinding...

                          Except that there is no overlap nor obstacle at all. I have literally just a sphere (default pawn) trying to reach a smaller one (goal). The rest of the elements are the basic UE setup and the DonNavigationManager that largely encompasses everything.

                          Also, and it is probably related, I don't see the voxels at all when I'm moving through the space. I can see the volume bounds alright but not the green/red boxes.

                          Any idea what could trigger these errors and how to fix them?

                          Thank you!

                          Comment


                            #43
                            Invoke from C++

                            I am trying to invoke the HotPursuit behavior from C++. I have a Don Navigation Manager placed in my map with appropriate sizing.

                            Here is my enemy pawn controller source:
                            Code:
                            #include "Ascentroid.h"
                            #include "AscEnemyController.h"
                            
                            AAscEnemyController::AAscEnemyController(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
                            {
                            	BlackboardComponent = ObjectInitializer.CreateDefaultSubobject<UBlackboardComponent>(this, TEXT("BlackboardComponent"));
                            	BehaviorTreeComponent = ObjectInitializer.CreateDefaultSubobject<UBehaviorTreeComponent>(this, TEXT("BehaviorTreeComponent"));
                            
                            	FString Path = "/Game/DonNavigationSamples/BehaviorTree/HotPursuit";
                            	BehaviorTree = Cast<UBehaviorTree>(StaticLoadObject(UBehaviorTree::StaticClass(), nullptr, *Path));
                            }
                            
                            void AAscEnemyController::Possess(APawn* InPawn)
                            {
                            	Super::Possess(InPawn);
                            
                            	if (BehaviorTree)
                            	{
                            		if (GetWorld() != nullptr)
                            		{
                            			auto TimerDelegate = FTimerDelegate::CreateUObject(this, &AAscEnemyController::InitAI, InPawn);
                            			GetWorldTimerManager().SetTimer(AITimer, TimerDelegate, 1.f, true, 0.f);
                            			//GetWorld()->GetTimerManager().SetTimer(AITimer, this, &AAscEnemyController::InitAI, 1.f, true, 0.f);
                            		}
                            	}
                            }
                            
                            void AAscEnemyController::InitAI(APawn* InPawn)
                            {
                            	if (GetWorld() == nullptr)
                            	{
                            		UAscUtil::Debug(TEXT("GetWorld() is null!"));
                            		return;
                            	}
                            
                            	auto CurrentPlayer = static_cast<AAscPlayerCharacter*>(UGameplayStatics::GetPlayerCharacter(GetWorld(), 0));
                            
                            	if (CurrentPlayer == nullptr)
                            	{
                            		UAscUtil::Debug(TEXT("CurrentPlayer is null!"));
                            		return;
                            	}
                            
                            	BlackboardComponent->InitializeBlackboard(*BehaviorTree->BlackboardAsset);
                            
                            	auto Target = Cast<AAscEnemy>(InPawn);
                            
                            	BlackboardComponent->SetValueAsObject("Target", Target);
                            	BlackboardComponent->SetValueAsObject("SelfActor", Target);
                            	BlackboardComponent->SetValueAsVector("TargetLocationKey", CurrentPlayer->GetActorLocation());
                            	BlackboardComponent->SetValueAsVector("FlightGoal", CurrentPlayer->GetActorLocation());
                            
                            	BehaviorTreeComponent->StartTree(*BehaviorTree, EBTExecutionMode::Looped);
                            
                            	UAscUtil::Debug(TEXT("InitAI started!"));
                            
                            	GetWorld()->GetTimerManager().ClearTimer(AITimer);
                            }
                            When I enter the map, however, I get the following error(s):
                            Code:
                            [2017.05.30-00.03.39:187][264]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:200][265]LogCoherentUIGT:Error: ConsoleAPI coui://UIResources/Gui/static/js/coherent.js:652:16: TypeError: undefined is not an object (evaluating 'n("#asc-hud-content-player-placement-"+t+"-name").css("visibility").indexOf')
                            	coui://UIResources/Gui/static/js/app.17eabe89d9f670abddf3.js:1:30009
                            [2017.05.30-00.03.39:210][266]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:225][268]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:244][270]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:266][272]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:288][274]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:308][276]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:329][278]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:350][280]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:372][282]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:392][284]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:413][286]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:435][288]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:454][290]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:474][292]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:495][294]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:495][294]LogScript:Warning: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn
                            	Service_Pursuit_Helper_C /Game/Ascentroid/Maps/UEDPIE_0_MAP_Scale_Testing.MAP_Scale_Testing:PersistentLevel.AscEnemyController_0.BehaviorTreeComponent.Service_Pursuit_Helper_C_0
                            	Function /Game/DonNavigationSamples/BehaviorTree/Service_Pursuit_Helper.Service_Pursuit_Helper_C:ExecuteUbergraph_Service_Pursuit_Helper:00AA
                            [2017.05.30-00.03.39:495][294]PIE:Error: Error Blueprint Runtime Error: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn from function: 'ExecuteUbergraph_Service_Pursuit_Helper' from node: Branch in graph: EventGraph in object: Service_Pursuit_Helper with description: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn
                            [2017.05.30-00.03.39:496][294]LogBlueprintUserMessages: [Service_Pursuit_Helper_C_0] RESTARTING PURSUIT (Player has gotten way ahead of this bot!)
                            [2017.05.30-00.03.39:517][296]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:537][298]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:557][300]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:579][302]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:599][304]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:619][306]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:640][308]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:661][310]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:682][312]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:718][314]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:736][316]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:758][318]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:786][320]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:805][322]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:826][324]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:848][326]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:868][328]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:888][330]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:910][332]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:930][334]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:950][336]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:971][338]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.39:991][340]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:002][341]LogScript:Warning: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn
                            	Service_Pursuit_Helper_C /Game/Ascentroid/Maps/UEDPIE_0_MAP_Scale_Testing.MAP_Scale_Testing:PersistentLevel.AscEnemyController_0.BehaviorTreeComponent.Service_Pursuit_Helper_C_0
                            	Function /Game/DonNavigationSamples/BehaviorTree/Service_Pursuit_Helper.Service_Pursuit_Helper_C:ExecuteUbergraph_Service_Pursuit_Helper:00AA
                            [2017.05.30-00.03.40:003][341]PIE:Error: Error Blueprint Runtime Error: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn from function: 'ExecuteUbergraph_Service_Pursuit_Helper' from node: Branch in graph: EventGraph in object: Service_Pursuit_Helper with description: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn
                            [2017.05.30-00.03.40:003][341]LogBlueprintUserMessages: [Service_Pursuit_Helper_C_0] RESTARTING PURSUIT (Player has gotten way ahead of this bot!)
                            [2017.05.30-00.03.40:012][342]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:033][344]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:053][346]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:073][348]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:092][350]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:112][352]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:132][354]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:151][356]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:171][358]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:190][360]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:210][362]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:229][364]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:249][366]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:268][368]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:287][370]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:307][372]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:326][374]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:345][376]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:364][378]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:383][380]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:402][382]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:421][384]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:440][386]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:459][388]LogBlueprintUserMessages: [PickBot_C_0] Invalid Goal
                            [2017.05.30-00.03.40:468][389]LogScript:Warning: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn
                            	Service_Pursuit_Helper_C /Game/Ascentroid/Maps/UEDPIE_0_MAP_Scale_Testing.MAP_Scale_Testing:PersistentLevel.AscEnemyController_0.BehaviorTreeComponent.Service_Pursuit_Helper_C_0
                            	Function /Game/DonNavigationSamples/BehaviorTree/Service_Pursuit_Helper.Service_Pursuit_Helper_C:ExecuteUbergraph_Service_Pursuit_Helper:00AA
                            [2017.05.30-00.03.40:468][389]PIE:Error: Error Blueprint Runtime Error: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn from function: 'ExecuteUbergraph_Service_Pursuit_Helper' from node: Branch in graph: EventGraph in object: Service_Pursuit_Helper with description: Accessed None trying to read property CallFunc_Get_Goal_Bot_Pawn
                            [2017.05.30-00.03.40:468][389]LogBlueprintUserMessages: [Service_Pursuit_Helper_C_0] RESTARTING PURSUIT (Player has gotten way ahead of this bot!)
                            It seems like the "Get Goal Bot" function call in "Service_Pursuit_Helper" is returning 'None'. I can't figure out why. Any ideas? It feels like I am missing something obvious. You can see I try setting the target/pawn with SetValueAsObject, but I have no idea if this is the right way to do it.

                            Thanks!

                            Comment


                              #44
                              [MENTION=239810]Aurel[/MENTION] - A screenshot would help, but my first guess is that your target pawn has a collision body or prop on it whose collision profile is set to WorldStatic or WorldDynamic and is therefore being picked up as a navigation obstacle by the system. That would explain why your origin/goal is always invalid.

                              --

                              [MENTION=108847]jvukovich[/MENTION] - Looks like you're reusing the sample behavior tree of the demo project. The demo project has been setup in such a way that it picks goals from pawns via the "Goal Actor" public variable (which is set on a pawn from the map via world outliner). Additionally, each pawn implements a simple interface called "Demo Pawn Interface" which allows the behavior tree task to extract the goal from any arbitrary pawn. Now, if you're testing with the sample BT and not doing either of these, then the "Invalid Goal" message which you're seeing appears.

                              Of course you will eventually want to switch out the sample "Pick Goal" / "Pick Bot" tasks with your BT task/logic/implementation which sets the FlightLocationKey blackboard to a suitable vector depending on the specific gameplay tasks your A.I. is trying to achieve.

                              Edit:- I notice you're already setting the BB keys directly. In that case you should not be using the Pick Bot ("Refresh Pursuit Goal") node in your behavior tree at all. That node will attempt to override the goal with its own logic which is not desirable in your case.
                              Last edited by VSZ; 05-30-2017, 01:53 AM.

                              Steam Early Access: Drunk On Nectar - The Nature Simulator

                              UE4 Plugins: DoN’s Dynamic Mesh FX | DoN’s 3D Pathfinding

                              Comment


                                #45
                                Would someone be able to build and upload the plugin for mac? I'm having some problems trying to do that.

                                Comment

                                Working...
                                X