0 votes

I want to make a game similar to those where you have rotating target in the middle and you throw/shoot knives/arrows at it. Projectile then gets stuck to the target but it rotates with it.
So the question is can anyone tell me how to do that "rotates with it" part?
The target is currently Area2D with sprite that rotates and it has CollisionShape2d around it (not rotating). The part that fires & stops projectile (KinematicBody2D) I have but following part I cannot figure out.
I've trie with Joint and even with pathfollow.

Thank you

in Engine by (15 points)

2 Answers

+1 vote
Best answer

Are you familiar with instancing? If not, it's pretty easy.

I would recommend making your projectile a scene: (right click -> save branch as scene), which you then can instance an infinite amount of times. That means, you could spawn your projectiles in some kind of container (simply Node2D):

In the container node:

var projectile_scene = load("path_to_the_scene_in_resources")
var projectile = projectile_scene.instance()
add_child(projectile)

After you throw them and they get stuck, you would remove them from the container

projectile.queue_free()

and instance them as a child of the Area2D with accurate position in the same manner. This way, it would simply obey the Area2D's rotation.

by (840 points)
selected by

Ok I went with Footurist's approach because it looked simpler. I also made some changes.
Target is now rotated as Area2d with CollisionShape2D. It has script:

extends Area2D

func _physics_process(delta):
    rotate(2 * delta)

Next I have a bullet with code:

extends Node2D

var speed = 800
signal bullet_hit

func _physics_process(delta):
    position.y -= delta * speed
    if $RayCast.is_colliding():
        emit_signal("bullet_hit", $RayCast.get_collision_normal(), $RayCast.get_collision_point())
        hide()
        queue_free()

As you can see I am using RayCast2D to check for collision.

Finally I have the world where everything is occurring.

extends Node

var bulletScene = preload('res://Scenes/Bullet.tscn')
var bulletStickScene = preload('res://Scenes/BulletStuck.tscn')

func _input(event):
    if Input.is_action_pressed("mouse_press"):
        var bullet = bulletScene.instance()
        bullet.global_position = $Spawn.global_position
        bullet.connect("bullet_hit", self, "bullet_hit_callback")
        add_child(bullet)

func bullet_hit_callback(hit_pos_normal, hit_pos):
    var bulletStuck = bulletStickScene.instance()
    bulletStuck.global_position = hit_pos * hit_pos_normal - Vector2(0, 110)
    $Target.add_child(bulletStuck)

The result is almost what I need. The Bullet gets stuck to the Target but every time on the same position as if Target didn't move at all.

Again, thank you for help and suggestions
Cheers

Upload project file, I'll have a look at it. WIll be easier.

Here it is.

This is working as intended now. I've added some useful stuff and removed the unnecessary. Play around with it to figure out why it's doing what it does. I've added an animation "fadeout" for the bullet, which triggers a function "destroy_self" at its end for example.

That's it, thank you so much!

No problem. Remember to deduce the logic, so that you remember it later on. :P

0 votes

Well there are several options:

  • Move the arrow as a children to your target. If the arrow rotates the children will do also. I'm not sure if this is the best way of handling physics bodies this way but I guess it could work.
  • You can send a signal when your target is rotating (coupled with the rotation-angle). Everytime the target rotates it sends a signal and if you connect every arrow with this signal they can call a function to rotate according to the rotation-angle.
  • Two PinJoints2d can also be used if you decide to change your target and arrow nodes to RigidBodies2d. I'm not sure if this would also work if you switch their modes to Kinematic to prevent code breakage.
by (1,028 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.