Changing the spawn location of the projectile?

I’ve noticed that the projectile is spawned at the centre of my Player’s Ship, but it would look better if it came from the nose of the spaceship, but i can’t seem to make it work. any advice?

	public float speed = 10.0f;
	public float padding = 0.1f;
	public GameObject projectile;
	public float projectileSpeed;
	public float firingRate = 0.2f;

	float xMin;
	float xMax;

	void Start (){ 
		float distance = transform.position.z - Camera.main.transform.position.z;
		Vector3 leftmost = Camera.main.ViewportToWorldPoint(new Vector3(0,0,distance));
		Vector3 rightmost = Camera.main.ViewportToWorldPoint(new Vector3(1,0,distance));
		xMin = leftmost.x + padding;
		xMax = rightmost.x - padding;
	}
	void Fire (){
		GameObject beam = Instantiate(projectile, transform.position, Quaternion.identity) as GameObject;
		beam.GetComponent<Rigidbody2D>().velocity = new Vector3(0, projectileSpeed, 0);
	}

	void Update ()
	{
		if (Input.GetKeyDown (KeyCode.Space)) {
			InvokeRepeating ("Fire", 0.00001f, firingRate);
		}
		if (Input.GetKeyUp (KeyCode.Space)) {
			CancelInvoke ("Fire");
		}
		if (Input.GetKey (KeyCode.RightArrow)) {
			transform.position += Vector3.right * speed * Time.deltaTime; 
		} else if (Input.GetKey (KeyCode.LeftArrow)) {
			transform.position += Vector3.left * speed * Time.deltaTime;
		}
		//restricts player to gamespace
		float newX = Mathf.Clamp(transform.position.x, xMin, xMax);
		transform.position = new Vector3(newX, transform.position.y, transform.position.z);
	}
}

I have tried to change the transfer.position in the Instantiate(projectile, transform.position, Quaternion.identity) as GameObject; to a different Vector3 coordinate, but it seems to break it. Anything else I could try?

Thanks in advance!

1 Like

Hi,

From memory there is a projectile for the enemies and the player isn’t there, both of which are prefab’d?

Assuming so, drop a prefab’d player projectile into your scene and player it directly over the top of the player ship. Then, adjust it’s transform’s Y value until the projectile is just in front of the ship. Apply the changes to the prefab.

Repeat the same process for the enemy projectile, you will invariably need to drop an enemy into the scene as well in order to do this. Again, adjust the Y value of the enemy projectile’s transform component and apply the changes to the prefab.

When the projectiles are now spawned they will be placed at the location of the enemy or player ship which are firing them, but because you have adjusted the Y value of their respective transform components, the projectiles should appear just in front of both the enemy and player ships.

Hope this helps, any problems let me know :slight_smile:


Updated Tue Apr 24 2018 13:05

Actually, you may need to create an Empty GameObject for the above, and then child the projectile to it. The parent empty would have a standard 0,0,0 transform, the childed laser a slightly different value on the Y, and of course then re-prefab it.

Having just opened a copy of the project here, I don’t appear to have the empty GameObject approach, and the prefab’d lasers seem to have zero transforms and appear ok on the screen, they emerge from the tip of the player ship, but of course they are actually under it.

The above should work for you if you want to make them actually spawn in front of the ship, but you would probably want to use the empty GameObject approach.

Awesome, thanks for the replies!

Would you be able to jog my memory on how to child the projectile to an empty GameObject?

Thanks again!

1 Like

I’m just testing this and it will work - but… you will then most likely run into some further problems. For example, I did this (don’t do it yet, I don’t want to mess up your project, just read along! :slight_smile: )…

  • dragged the PlayerLaser into the scene, it appears at 0,0,0
  • Right-clicked in the Hierarchy and created an Empty GameObject
  • dragged the PlayerLaser into the Empty GameObject
  • renamed PlayerLaster (the instance in the Hierarchy) to LaserBeam
  • renamed the Empty GameObject to PlayerLaser
  • renamed the PlayerLaser prefab to PlayerLaserOld (for a backup etc)
  • dragged the PlayerLaser GameObject from the Hierarchy into the assets folder to create a new prefab
  • deleted the PlayerLaser GameObject from the Hierarchy
  • selected the Player prefab, clicked on the circle selected next to the Projectile and selected PlayerLaser (the new prefab with the parent/child)
  • ran the game
  • received an error because PlayerLaser doesn’t have a BoxCollider2D component.

I realised at this point that I would then need to change the structure a little further, moving the various components from child to parent, and of course you need to make sure the BoxCollider2D is going to be actually over the laser sprite itself or else you’ll have collisions either looking like they are occuring when they aren’t or vice-versa…

So… in the end I just fiddled it with code;

    /// <summary>
    /// Fires the player's laser
    /// </summary>
    private void Fire()
    {
		Vector3 laserPosition = transform.position;
		laserPosition.y += 1f;
		
        GameObject laser = Instantiate(projectile, laserPosition, Quaternion.identity) as GameObject;
        laser.GetComponent<Rigidbody2D>().velocity = new Vector3(0f, projectileSpeed, 0f);

        AudioSource.PlayClipAtPoint(fireSound, transform.position);
    }

I have arbitrarily put a value of 1f in there, which in my case is a little too big, 0.5f appear to be just slightly under the ship, so you may want something more like 0.75f.

Note the change on this line also;

GameObject laser = Instantiate(projectile, laserPosition, Quaternion.identity) as GameObject;

We are passing in laserPosition instead of using transform.position.

This isn’t the most elegant solution, but give it a try and see if it works for you, it can be improved :slight_smile:


Updated Tue Apr 24 2018 13:29

This is the point of spawn with 0.75f as the value for laserPosition's Y value;

image


Updated Tue Apr 24 2018 13:33

Just spotted you didn’t have the line in your Fire method for the audio, probably comes a little further along in the course that you are, just remove this line from my example above;

AudioSource.PlayClipAtPoint(fireSound, transform.position);

Thanks for that.

Just added in the code, and it works great!

1 Like

Great to hear and you’re welcome. :slight_smile:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms