2D Aiming and Shooting at the mouse

So I’m currently working on a little side project where I want a shooting mechanic similar to that of games such as “enter the guneon” or “Nuclear Throne”.
I’ve tried to implement this for a few days now but all the information that i find seem to either be outdated or incompatible with the version of unity that I’m currently working in(v5.3.4f1), I have tried using raycast to give the bullet a line to go in, but from what I’ve read the raycast is sorta bugged with this current version, so i’ve tried to do some scripts with the use of Quaternion rotations.
However the closest i’ve gotten to a working system like the one I intended is one where the bullet spawns facing the direction that i’m aiming with the mouse(full 360 degrees), however when I try to add speed using AddForce or Vectors the bullet either ignores it or shoots the bullet in a wierd angle around the 0 - 90 degree right side of the world, the more sidewards i move the mouse the less of an additional angle it gives the bullet, and instead curves it.

I’m relatively new to unity but know a decent amount of C#

using UnityEngine;
using System.Collections;

public class Aim : MonoBehaviour {

    public Transform gun;

    public Rigidbody2D bullet;

    void Start()
    {
        GetComponent<Rigidbody2D>().angularVelocity = 0;
        float input = Input.GetAxis("Vertical");
    }

    void FixedUpdate () 
    {
        Quaternion rotation = Quaternion.LookRotation(transform.position - Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector3.forward);
        transform.rotation = rotation;
        transform.eulerAngles = new Vector3(0, 0, transform.eulerAngles.z);

	}

    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            Rigidbody2D bulletClone;
            bulletClone = Instantiate(bullet, gun.position, gun.rotation) as Rigidbody2D;
            
        }
    }
}

This is the script I currently use for aiming and instantiating the bullet, i got a bullet prefab with a rigidbody2D attached and an empty gameObject that i use for the “gun”, i removed the AddForce part from the script referenced above since it doesn’t show signs of any kind of functionality anyways.
So if you have anything in mind that might help me get past this problem i would be more than happy to try it out, thanks in advance!

ps. I would prefer suggestions which doesn’t involve the raycast functionality since it’s bugged in some cases of this version, however if they work I’m not gonna be picky about it.

  1. You need a position of touch

    function update(){
         if (Input.GetMouseButtonDown(0)){ 
            pos = Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x,Input.mousePosition.y,2));
             /some code/
             }
     }
    
  2. I have cannon i’n middle of screen from where I’m shooting and i need to rotate him

    function rotate (position : Vector3){
    var d:float;   //distance 
    var angle:float;
    var x:float;
    
    x = position.x;  //basic maths pythagor's phrase :D c^2 = b^2 + a^2
    d = Mathf.Sqrt((position.y*position.y)+(x*x));  //this is distance (c)
    angle = Mathf.Acos(position.y/d) * Mathf.Rad2Deg; //here I get angle
    if (x > 0)   //here i determinate to turn left or right
    	for (var i = 0; i < uhol; i++){
    		shootingPosTransform.eulerAngles = Vector3(0, 0,-i);
    	}
    else 
    	for (var j = 0; j < uhol; j++){
    		shootingPosTransform.eulerAngles = Vector3(0, 0,j);	
    	}
    

    } //note: my cannon is at coordintes 0,0 so if u have another use vector touchPosition-shootingPosition

  3. Creating projectile and shooting

     function shoot(poz:Vector3){
     var strelaObject : GameObject = new GameObject("strela"); //strela means projectile
     var renderer : SpriteRenderer = strelaObject.AddComponent.<SpriteRenderer>();
     var st : Transform = strelaObject.GetComponent("Transform");
     var sr : Rigidbody2D = strelaObject.AddComponent.<Rigidbody2D>();
     var vec2smer : Vector2 = new Vector2((8/poz.y)*poz.x,8); //here is magic for constant move :) if you know touch position you are able to calculate it at some another point so every touch will come form y=8 and x form touch will be moved to height of y=8
     var cc : CircleCollider2D = strelaObject.AddComponent(CircleCollider2D);
     
     renderer.sprite = strelaSprite;	//sprite
     
     cc.radius = 0.2f;   //radius of collider
     cc.sharedMaterial = physMat;
     
     sr.AddForce(vec2smer*silaStrely); //now all what moves projectile is rigidbodyAddForce * someForce (i use int)
     sr.mass = 1;
     sr.gravityScale = 1;
     //sr.isKinematic = true;
    
     st.Translate(0,0,-0.5); //here is fix to get position on z = -0.5
     Destroy(strelaObject,1.5); //and destroy
    

    }

Quite easy :smiley:
I hope i helped you :slight_smile:

sorry for the late reply, just woke up again, was 1 am when i last answered, anyways, i mean, i’m working in C# but i’ll try to convert that from java to see if it works, i personally prefer using a prefab solution though, looking at your code though you seem to be creating the bullet with all it’s components from scratch, later on once i get the basics of it all working to perfection i was also gonna add object pooling to the whole process as your method of doing the spawning of the projectiles seem to be very cpu intensive compared to having a few objects activated and deactivated, i think changing the spawn part would be a good way to optimize your script, however the aiming part seems to be a little more complex than what i have going on in my script atm, the following is what i got:

using UnityEngine;
using System.Collections;

public class Aiming : MonoBehaviour
{ 
    public GameObject shotPrefab;

    public GameObject exit_Point;

    private Rigidbody2D rb;

    public float speed;

    void Update()
    {
        Vector2 target = Camera.main.ScreenToWorldPoint(new Vector2(Input.mousePosition.x, Input.mousePosition.y));
        Vector2 exitPoint = new Vector2(exit_Point.transform.position.x, exit_Point.transform.position.y);
        Vector2 direction = target - exitPoint;
        direction.Normalize();

        Quaternion rotation = Quaternion.Euler(0, 0, Mathf.Atan2(direction.y, direction.x) *                                            Mathf.Rad2Deg);
        transform.rotation = rotation;

        if (Input.GetMouseButtonDown(0))
        {
            GameObject shot = (GameObject)Instantiate(shotPrefab, exitPoint, rotation);
            rb = shot.GetComponent<Rigidbody2D>();
            rb.AddForce(direction * speed);
        }
    }
}

i have the GameObjects set to public so i can just drag a prefab and an empty object in rather than create them from scratch, later on ill be adding object pooling by doing a standard list of gameobjects that i activate/de-activate, i make an empty rigid body for the bullet to reference it, define a target, exit point(the gameobject) and a direction based of those 2, a normalize to make it a constant speed, rather than have it very on where you click, since i did the direction really simple(since i use the direction in the addforce, so the longer you are from the player the bigger the number it multiplies etc.), then i use quaternions to rotate it and an innstantiation for finally shooting the bullet out, that’s all there is so far(except for the object pooling since ill bbe adding that as a finnal touch).