Godot Recipe: Drag-select Multiple Units

Поділитися
Вставка
  • Опубліковано 1 січ 2020
  • RTS-style drag-to-select and command multiple units.
    Text version:
    kidscancode.org/godot_recipes/...
    Support me on Patreon: / kidscancode

КОМЕНТАРІ • 76

  • @danylbekhoucha6180
    @danylbekhoucha6180 4 роки тому +9

    It's nice to see you back, you are one of my favorite Godot instructor.
    An indispensable game mechanic for RTS games.

  • @IrwinRodriguez
    @IrwinRodriguez 4 роки тому +1

    It's nice to see you again Chris! Thank you very much for helping and teaching us the fundamentals of Godot!

    • @Kidscancode
      @Kidscancode  4 роки тому +1

      My pleasure - thanks for watching!

  • @upyours2707
    @upyours2707 4 роки тому

    2020 starts off good with my fav Godot instructor! thank you sensei

  • @darktrunks0
    @darktrunks0 4 роки тому +1

    Conveniently, I needed just this recipe for a project I'm working on. Thanks Chris!

  • @bit_fiddler
    @bit_fiddler 4 роки тому +5

    intersect_shape() defaults to 32 "max results" if you want to select more make sure to increase this"intersect_shape(query, )" . Was really confused when I created a lot of units. Hope it helps someone. Thx for the videos, very helpful!

    • @Kidscancode
      @Kidscancode  4 роки тому

      Good catch!

    • @megadesu69
      @megadesu69 2 роки тому

      Thanks so much for this, you're a lifesaver :)

    • @timflatus
      @timflatus 6 місяців тому

      Thank you. That was doing my head in.

  • @ArtER21
    @ArtER21 3 роки тому

    I got this working except that when I select multiple units the units RayCast2D's that detect obstacles in the vehicles path stop working , when a unit gets stuck this way and I click on it the RayCast2D's starts working again and it navigates out of the obstacle with out being given the second click to set its destination. when I select units one at a time the navigation RayCasts don't stop working it only happens when I select multiple units.

  • @michaelkneeshaw5954
    @michaelkneeshaw5954 4 роки тому +1

    How would you select only collision shapes for one physics layer?

  • @sestalacto
    @sestalacto 4 роки тому

    I have no idea how to handle a target system do you have any video about that? selecting by clic on enemy and set as a target for a player.

  • @will7466
    @will7466 Рік тому +2

    Do you have a link to your video dealing with point and click movement?

  • @giggleghost3751
    @giggleghost3751 4 роки тому +1

    Happy new year to KCC! I hope 2020 brings us a ton more videos from this channel. 🧡💛💚
    After I have finished your tank tutorial, I started working on my own little game that uses some of the tips and tricks from that tutorial. Here is what I have so far: ua-cam.com/video/RApt-3fIHB8/v-deo.html All the art (except bullets and explosion) I drew myself. I plan on making few different biomes some time later, once I have everything in the game working. It's not the most original game, but I need something I can handle in order to learn the engine. 😁
    This tutorial will be awesome when I start making a little selectable hero unit.
    Thank you for your tutorials, they really make a difference. Your teaching style just works for me, and I prefer it to any other tutorial series!

    • @Kidscancode
      @Kidscancode  4 роки тому

      Thanks - keep up the good work!

  • @tombkings6279
    @tombkings6279 2 роки тому +1

    for item in selected:
    item.collider.selected = true
    it doesn't highlight the units
    else:
    for item in selected:
    item.collider.target = event.position
    item.collider.selected = false
    selected = []
    when I try to run it, crashes

  • @jonynunez61
    @jonynunez61 3 роки тому

    could you make a video where you show how to make a character for an rts game?

  • @syrupthesaiyanturtle
    @syrupthesaiyanturtle Рік тому +1

    How does this implement in a 3D RTS game?

  • @FMGFlookV.2
    @FMGFlookV.2 6 місяців тому

    how i fix this ? (Godot3.5)
    invalid set index 'selected' (on base: 'KinematicBody2D (Unit.gd) with value of type 'bool'

  • @alexi2706
    @alexi2706 Рік тому

    how do you make this 3d?

  • @giggleghost3751
    @giggleghost3751 4 роки тому +4

    By the way, which video shows us how to make click to move? I tried searching for it on the channel but can't find it.
    Also, on the website, in the article for this tutorial, "starting project" link is missing. I am guessing it will be added later.

    • @Kidscancode
      @Kidscancode  4 роки тому

      I'm sure I've used it in some demo before. Regardless, see here for an example of click-to-move:
      docs.godotengine.org/en/latest/tutorials/2d/2d_movement.html#click-and-move
      I'll check the written article - thanks for letting me know.

    • @samuelleal4250
      @samuelleal4250 7 днів тому

      I tried something like this for CharacterBody2D node:
      extends CharacterBody2D
      @export var speed = 400
      var selected = false
      var target: Vector2
      func _ready():
      target = position
      func _physics_process(delta):
      velocity = position.direction_to(target) * speed
      if position.distance_to(target) > 10:
      move_and_slide()

  • @parkerstroh6586
    @parkerstroh6586 12 днів тому

    He says he talked about click-to-move in another recipe but I can't find it anywhere! Does anyone know which video he is talking about?

  • @johnd5736
    @johnd5736 4 роки тому

    Awesome videos, but why don't you have ssl on your site?
    It will definitely help your search engine ranking, more ppl need to see your content.

  • @kylehouk2281
    @kylehouk2281 3 роки тому +4

    When I was doing this with a moving camera, my rectangles drew wrong. event.position was giving different values than get_global_mouse_position so i just set both to get_global_mouse_position and it started drawing correctly. I think it was because event.position's 0, 0 coordinates were based on camera position while global was not. I was confused because with a fixed camera it worked as intended.
    However, now Im not getting it to return the kinematic2d bodies I have within the rectangle. I just wanted to give folks a heads up that might be doing something similar, however I didnt want to say the solution worked perfectly till I could get thing to show up in my array.

    • @whiteflaggaming6641
      @whiteflaggaming6641 2 роки тому +1

      saved me a lot of hassle thank you :D

    • @whiteflaggaming6641
      @whiteflaggaming6641 2 роки тому

      though mine do still show up in the array (so far lol)

    • @kevinscales
      @kevinscales 2 роки тому

      did you get it to detect the kinematic2d bodies? I have no idea how to get it to work
      Edit:
      Just figured it out. I was using PhysicsShapeQueryParameters instead of Physics2DShapeQueryParameters
      took far too long to figure that out

    • @lethn2929
      @lethn2929 Рік тому +1

      Thank you! Helping me solve bugs in 2023 :D

    • @timflatus
      @timflatus 6 місяців тому

      Yep. event.position was returning local positions not global ones with my set up too, so I use get_global_mouse_position() instead. It's fine so long as you use the same for drag_end, drag_start and in the _draw function.

  • @NonsenseCommon
    @NonsenseCommon 3 роки тому

    is it possible to do this with rigidbodies instead of kinematic bodies?
    i cant get the mouse detection to work

    • @Kidscancode
      @Kidscancode  3 роки тому

      Body type doesn't really matter.

  • @ArtER21
    @ArtER21 3 роки тому +1

    thanks for the tutorial , I cant seem to figure out how to set this up so I cant select enemy units

    • @camuor3645
      @camuor3645 3 роки тому

      you could give each unit a team name eg. ""red"" and then check if the players team is the same as the units
      eg if TEAM_COLOR == item.color:
      ## put the action here

    • @ArtER21
      @ArtER21 3 роки тому +1

      @@camuor3645 thanks, I asked this some time ago and never really got this to work quite this way using Direct space state. I learned how to do box select with an area and defining a collision rectangle. I just used groups [ if body.is_in_group("player"): body.selected = true ]
      I learned a lot from this video , I also make some Godot content you may want see see a variation on this method
      ua-cam.com/video/9Q8zgXQBinU/v-deo.html

  • @jorgegomes83
    @jorgegomes83 4 роки тому +1

    Yeah, unit selection can be quite complicated to implement in the first time, specially in Godot.
    Another thing that I find very hard is to automate some unit according to its function: like a lumberjack that receives the command to chop some wood and keep doing its task (find a tree, chop it, collect the wood, carry the wood to the lumberyard, drop the wood, restart) until another command is given.
    I would be very grateful if you could give some directions.

    • @DarkestEngineer
      @DarkestEngineer 4 роки тому

      make a State Machine

    • @jorgegomes83
      @jorgegomes83 4 роки тому

      @@DarkestEngineer That's the right answer. But imagine a AoE worker that you can assign multiple kinds of jobs (forager, farmer, gold miner, stone miner, lumberjack, hunter, fisher). What is the idea? To define a state machine for each possible job an then set the corresponding job on the unit when a new comand is given, or to define a big single state machine and then change the states according to some auxiliary "job" variable?
      Maybe there are more ways of doing it.

    • @DarkestEngineer
      @DarkestEngineer 4 роки тому +1

      @@jorgegomes83 what you will take as a solution it only depends on you. As state machine you can group jobs as a categories where they are doing the same thing but from different sources. So this way you can create states as mine, harvest, hunt.

    • @jorgegomes83
      @jorgegomes83 4 роки тому

      @@DarkestEngineer Godot probably already provides a State Machine node, but i'm yet to learn how to use it and see if it works more or less the way I imagine. Thanks for the help, anyways.

  • @Mc.GRonald
    @Mc.GRonald 3 роки тому +1

    Can this be used for 3D RTS ?

    • @Kidscancode
      @Kidscancode  3 роки тому

      Sure, with some modifications.

  • @iAmCodeMonkey
    @iAmCodeMonkey Рік тому

    Sadly, the zip file for the project can't be found on the site anymore. That's kind of an important oversight.

  • @regalraccoon
    @regalraccoon 4 роки тому

    How would you combine this with a click to select a single unit? I've been trying to find a simple implementation for this

    • @Kidscancode
      @Kidscancode  4 роки тому +1

      Physics bodies all have _input_event(), so you can detect clicks that are directly on the body.

    • @regalraccoon
      @regalraccoon 4 роки тому

      @@Kidscancode Thanks for the reply. I was referring specifically to the order of processing: unhandled_input() is handled before input_event(), so a mouse event will first be considered the start of a drag, rather than a press and release

    • @Kidscancode
      @Kidscancode  4 роки тому

      True, but in the main scene you can check for this case first. In practice, you're probably going to want a hover effect on the unit, so you'd use its `mouse_entered` signal and at that point you know you have a unit under the mouse so you don't start a drag.

    • @regalraccoon
      @regalraccoon 4 роки тому

      @@Kidscancode Mouse_entered and _exited is what I'm currently using. However, I feel like this is a non-intuitive approach, especially for beginners. Perhaps something to discuss in a future video? :)

    • @regalraccoon
      @regalraccoon 4 роки тому

      @@Kidscancode One more question: if you're developing for mobile it's not possible to check for mouse_entered. What would you recommend in that case?

  • @lethn2929
    @lethn2929 Рік тому

    Updated version of the code that I've tweaked to be more like classic C&C selection.
    extends Node2D
    var isDragging = false
    var selectedUnits = []
    var dragStart = Vector2()
    var selectedRectangle = RectangleShape2D.new()
    func _unhandled_input(event):
    if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:

    if event.is_pressed():
    isDragging = true
    dragStart = get_global_mouse_position

    for selection in selectedUnits:
    var selectionCollision = selection.collider
    if selectionCollision.is_in_group("Selectable"):
    selectionCollision.DisableSelection()
    selectedUnits = []

    elif isDragging == true:
    isDragging = false
    queue_redraw()
    var dragEnd = get_global_mouse_position
    selectedRectangle.size = (dragEnd - dragStart).abs()

    var space = get_world_2d().direct_space_state
    var query = PhysicsShapeQueryParameters2D.new()
    query.set_shape(selectedRectangle)
    query.transform = Transform2D (0, (dragEnd + dragStart) / 2)
    selectedUnits = space.intersect_shape(query)

    for selection in selectedUnits:
    var selectionCollision = selection.collider
    if selectionCollision.is_in_group("Selectable"):
    selectionCollision.EnableSelection()


    if event is InputEventMouseMotion and isDragging == true:
    queue_redraw()

    func _draw():
    if isDragging == true:
    draw_rect(Rect2 (dragStart, get_global_mouse_position() - dragStart), Color.DARK_GREEN, false)

  • @bongblender
    @bongblender 4 роки тому

    how to do slow motion effect....?

    • @Kidscancode
      @Kidscancode  4 роки тому +1

      There are multiple tutorials about this if you search.

    • @bongblender
      @bongblender 4 роки тому

      @@Kidscancode I wanted to apply a slow motion effect to my game when my player is stand still/not moving...so i used time_scale like......
      If input false....
      Engine.time_scale = 0.5
      else:
      Engine.time_scale = 1
      But Then my game physics is affected... Like the length of jump height get low... I think it's because it's affecting delta....
      So , now help me, how to create a slow motion effect.... When my player not moving with out affecting the jump height....
      YOU ARE MY LAST HOPE....

    • @Kidscancode
      @Kidscancode  4 роки тому +1

      If you're using delta in all your movement calculations then changing time_scale shouldn't change any of your physics.

    • @bongblender
      @bongblender 4 роки тому

      ​@@Kidscancode ok , i got it and i solved it...

  • @vaughanling1833
    @vaughanling1833 4 роки тому

    Awesome! Thanks!! Btw, are you still coming to Burbank coding group? This is Vaughan, the painting app guy.

    • @Kidscancode
      @Kidscancode  4 роки тому

      I'm afraid not - it's been pretty busy. Is there one this coming week, because maybe I could stop by.
      How's the app coming along?

    • @vaughanling1833
      @vaughanling1833 4 роки тому

      @@Kidscancode Ah ok, I might try to come this week too...The app is going well, just published a big update yesterday, getting a little bit into shader scripting now, and finally got IAP working for iOS and Android after months of trial and error. I'm using match everywhere in my code now, learned so much from you that one time!

    • @Heavypoly
      @Heavypoly 4 роки тому

      @@Kidscancode I might not be able to make it this week after all :(

  • @eruaiokoyomoh3177
    @eruaiokoyomoh3177 4 роки тому

    Please do a video on Normal Maps please, pretty please

    • @Kidscancode
      @Kidscancode  4 роки тому

      What about normal maps are you curious about? Is there a particular application? 2D or 3D?

    • @eruaiokoyomoh3177
      @eruaiokoyomoh3177 4 роки тому

      Ooh I use Gimp to make my normal maps, but they don't really affect the surface only the edges of the sprite and it doesn't really look realistic

  • @Matthewgb204
    @Matthewgb204 4 роки тому

    Awesome

  • @samanodun6257
    @samanodun6257 4 роки тому +6

    "click to move is pretty easy to implement"
    it took me 100 lines of code ;-;

    • @Kidscancode
      @Kidscancode  4 роки тому +9

      Not sure if you're joking, but here's a great example of how easy it is: docs.godotengine.org/en/latest/tutorials/2d/2d_movement.html#click-and-move

    • @ernestomercado8176
      @ernestomercado8176 3 роки тому +1

      he didnt mean to a pathfinding

  • @lethn2929
    @lethn2929 Рік тому +1

    Just made a thread about this tutorial on the Godot forums, here's the updated code for Godot 4, the main change is in how the rectangle shape is calculated, this should all be functional, you've just got to finish it off for your particular mechanics.
    selectedRectangle.size = (dragEnd - dragStart).abs()
    extends Node2D
    var isDragging = false
    var selectedUnits = []
    var dragStart = Vector2()
    var selectedRectangle = RectangleShape2D.new()
    func _unhandled_input(event):
    if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
    if event.is_pressed():
    if selectedUnits.size() == 0:
    isDragging = true
    dragStart = event.position
    else:
    selectedUnits = []

    elif isDragging == true:
    isDragging = false
    queue_redraw()
    var dragEnd = event.position
    selectedRectangle.size = (dragEnd - dragStart).abs()

    var space = get_world_2d().direct_space_state
    var query = PhysicsShapeQueryParameters2D.new()
    query.set_shape(selectedRectangle)
    query.transform = Transform2D (0, (dragEnd + dragStart) / 2)
    selectedUnits = space.intersect_shape(query)
    print(selectedUnits)

    for selection in selectedUnits:
    print(selection)

    if event is InputEventMouseMotion and isDragging == true:
    queue_redraw()

    func _draw():
    if isDragging == true:
    draw_rect(Rect2 (dragStart, get_global_mouse_position() - dragStart), Color.DARK_GREEN, false)

  • @Matthewgb204
    @Matthewgb204 4 роки тому +3

    When your done with this game you showing us how to make you should show us how to make a game engine I know it’d be very hard but I think it would be a fun project

    • @danylbekhoucha6180
      @danylbekhoucha6180 4 роки тому

      I prefer small tips to implement features in our Godot game like he does.

    • @Kidscancode
      @Kidscancode  4 роки тому +1

      Making a game engine is an enormous project. Not really something I'm looking to take on, I'm afraid. There are existing resources out there, if you're really interested. Plus Godot's source is all open, so you can look under the hood and see how it's done.

    • @Matthewgb204
      @Matthewgb204 4 роки тому

      KidsCanCode thanks I’ll check that out

  • @artik_mc6570
    @artik_mc6570 4 роки тому

    Спасибо за урок. Но как то я уже остыл не знаю зачем я всё это смотрю, хоть и понимаю что написать код мне удастся только для чего? Риторический вопрос.