0
\$\begingroup\$

I'm making a 2D game prototype in Unity and I want to have the player attack be a sword that hovers around the player with its direction being fixed to the direction you indicate with the arrow keys. So if the sword is in the upward position and you press the left button, you can see the arc it takes and an enemy in the way of that arc takes damage.

The game is not a platformer. It's on a flat surface.

edit: I want to know how to have the sword hover in a radius to the player and point the direction i press the arrow keys. I want to get the action of moving the sword to these positions to do damage to an enemy. But if the sword is in a upwards position and the player presses down, I want it to do an action that attacks the whole radius around the player, on a cooldown.

How would I go about programming this? I'm new to programming so I would greatly appreciate some helpful pointers.

Edit2:

So this is how far I have gotten: public class SwordSwing : MonoBehaviour {

public Transform swordHolder;

// Update is called once per frame
void Update ()
{
    if (Input.GetKeyDown(KeyCode.LeftArrow))
    {
        swordHolder.transform.Rotate(0, 0, -90);
    }

    if (Input.GetKeyDown(KeyCode.RightArrow))
    {
        swordHolder.transform.Rotate(0, 0, 90);
    }

    if (Input.GetKeyDown(KeyCode.UpArrow))
    {
        swordHolder.transform.Rotate(0, 0, 90);
    }

    if (Input.GetKeyDown(KeyCode.DownArrow))
    {
        swordHolder.transform.Rotate(0, 0, -90);
    }

}

I don't know if this is right, because when I use the arrow keys it just turns the sword 90 degrees and not to the specified position I want it to move to.

So Candid Moon said that I have to use Mathf.Lerp() and StartCoroutine() but I have no idea how to use them. I'm not really sure how to animate this either, I have done some animations in Unity but have a hard time implementing them into anything.

The hierarchy is now:

Player > SwordHolder > Sword

Now I also have this script:

if (GetComponent<Rigidbody2D>().velocity.x > 0)
        transform.localScale = new Vector3(1f, 1f, 1f);
    else if (GetComponent<Rigidbody2D>().velocity.x < 0)
        transform.localScale = new Vector3(-1f,1f,1f);

That flips the player sprite when i move left. This also flips the sword, I don't really want this. How do I stop it?

Let me know if there is anything I missed, I'm trying to learn.

\$\endgroup\$
  • \$\begingroup\$ gamedev.stackexchange.com/questions/69344/… \$\endgroup\$ – n_plum Feb 14 '17 at 14:03
  • \$\begingroup\$ What if the sword position is in the upward position and the player presses the down arrow key? \$\endgroup\$ – Vaillancourt Feb 14 '17 at 14:44
  • 1
    \$\begingroup\$ It's not clear where lies your issue. Do you want to know how to make the character attack on key press? Do you want to know how to perform the actual attack? Do you want to know how you could damage the enemies? Please add more details, including what you have already done/tried. \$\endgroup\$ – Vaillancourt Feb 14 '17 at 14:46
  • \$\begingroup\$ 1. I was thinking it would be a larger swing but with a slower attack. 2. I am very unfamiliar and have no training in C#. I don't know how to proceed with writing the code to do what I want to do. I have a vague idea, but nothing more. I'll update the post with some more details. \$\endgroup\$ – Anders Feb 14 '17 at 18:08
0
\$\begingroup\$

You should calculate the projection of distance vector to your enemy onto transform.forward vector (Vector3, front of z axis). You just have to save players transform.forward before rotating player. After rotation use Physics.OverlapCircle with radius of your attack and check if projection of enemy distance vector onto both current transform.forward and the one you saved. Are separately greater than 0 for every enemy you are going to hit. You need both vectors because I understood that you need only 1/4 of the whole circle. And that means that if your player was looking at Vector2(0, 1) direction and turned left, it means it only affects that 1/4 part between Vector2(0, 1) and Vector2(-1, 0). So if your enemy is standing for example on Vector2(0.3, 1), the projection onto Vector2(0, 1) will be proj > 0, but it's projection onto Vector2(1, 0) will be proj < 0. Same for the other part, and the last part both will be < 0.

Here is the answer on how to calculate the projection to give you return values between -1 and 1: Projection

@@@ Update @@@

I update my answer due to your comment. So you actually want not to calculate the area of effect, but hit your enemies with the collision system and you don't know how to implement the swinging in the direction. Well in this case it's simple.

1) You can write the sword swinging in the script. Just make the sword to be a child object of your player, change it pivot to be further from sword if you don't see sword or better make another empty gameobject (from now I will call it swordHolder). Sprite rotates around it's pivot.

So now all you have to do is to rotate sword in the direction that your player pressed the button. Something like if he presses left - swordHolder.transform.Rotate(0, 0, -90);. Make some trail effect for your sword to have a good swing look. Then simply add some box collider if you want it to calculate everything physically accurate and use OnCollisionEnter2D(Collision2D other) - call in this function methods that damage your enemies (not like in example I described above, there it affects every enemy immediately).

Objects should have Rigidbody2D attached in order to check for collisions with them. You can make them Kinematic if you don't use gravity and other physical stuff.

public class Sword : MonoBehavior { void OnCollisionEnter2D(Collision theOneWhoTouchedTheSword) { Enemy enemy = theOneWhoTouchedTheSword.collider.GetComponent<MyEnemy>(); if(enemy != null) { enemy.TakeDamage(swordAttackDamage) } } }

2) You can make 4 animations of sword swinging and call the right one instead of rotating it in script, but the OnCollisionEnter2D(Collision theOneWhoTouchedTheSword) should be there anyway and it will check for collisions anyway.

\$\endgroup\$
  • \$\begingroup\$ Thank you! I'll definitely try this. I'll update you if there is something I don't get. \$\endgroup\$ – Anders Feb 15 '17 at 15:31
  • \$\begingroup\$ I forgot to add that if you want to Rotate sword smoothly, you should use Mathf.Lerp() and StartCoroutine() where you rotate it. Alternatively you could use Quaternion.Lerp(). But the easiest way is animation. \$\endgroup\$ – Candid Moon _Max_ Feb 15 '17 at 16:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.