Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Unity2D] How can I instantiate in the current rotation of the player?

Discussion in '2D' started by weshmega, Feb 21, 2016.

  1. weshmega

    weshmega

    Joined:
    Feb 21, 2016
    Posts:
    2
    Backstory
    ---------

    I'm currently working on a 2D sidescroller/platform game as a hobby, and I just started recently. Followed a few tutorials and such I managed to wrote my own code for basic command like walk, jump, health and so on. However my basic code wasnt perforning as I would expect, I needed a more "Tight" feeling with the movements so I followed a suggestion to use a physics based controller (Prime31's PC2D, Acrocatic or even Corgi Engine...)

    Well, now the movements are what I feel is good, So I kind of dived in the scripts to add/remove/customize some code.

    Question
    --------

    I'm stuck now on a simple issue, I added these lines

    Code (CSharp):
    1.     public Transform weaponMuzzle;
    2.     public GameObject projectile;
    3.     float fireRate = 0.5f;
    4.     float nextFire = 0;
    then in my `Update()`


    Code (CSharp):
    1.   if (Input.GetButtonDown("Fire2"))
    2.     {
    3.       animator.Play.Weapon();
    4.       fireProjectile ();
    5.     }
    and here is the problem I have

    Code (CSharp):
    1.     void fireProjectile ()
    2. {
    3.       if (Time.time > nextFire)
    4.       {
    5.         nextFire = Time.time + fireRate;
    6.  
    7.         if (_motor.facingLeft)
    8.         {
    9.           Instantiate (projectile, weaponMuzzle.position, Quaternion.Euler (new Vector3 (0,0,180f)));
    10.         }
    11.         else if (!_motor.facingLeft)
    12.         {
    13.           Instantiate (projectile, weaponMuzzle.position, Quaternion.Euler (new Vector3 (0, 0, 0)));
    14.         }
    15.    }
    16. }
    The prefabs are also physics based and they are fired with no problems, however they don't want to follow the current rotation of the player, they always go in the right X axis.

    First of all, the `facingLeft` on my code is what I understand is the reference to the character controller motor, I tried with `_motor.normalizedXMovement > 0` and `_motor.normalizedXMovement < 0` (`normalizedXMovement` -1 is full left and 1 is full right) this just make it that you can only fire while moving, not stopped and the problem still persists.

    I also tried with `Quaternion.Identity` instead of Euler and it's the same.

    For a full source code : https://github.com/prime31/CharacterController2D

    I'm kinda lost and it would means a lot if you can help me out on this issue.
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I don't know what's happening either, but I know how I would find out. Comment out the "if" test so that the code always attempts to fire the projectile to the left. Does that work? What about other rotation values besides 0 or 180? Do they do what you expect?

    What if you just drag a projectile into the scene manually? Can you rotate it so that it goes left, or does something in its scripts always make it go right?
     
  3. weshmega

    weshmega

    Joined:
    Feb 21, 2016
    Posts:
    2
    Thanks for your help, I did what you suggested and here are the results :

    -about the if statement, whatever degrees I put on the Quaternion.Euler Z (0, 0, 180-360 or 0) it always goes right.
    -When dragged onto the scene, whatever Transform.rotation.z or transform.scale.x i tried the projectile fires to the right.
    -The projectile itself has this small script attached to :

    Code (CSharp):
    1.  
    2. public float projectileSpeed;
    3. Rigidbody2D myRB;
    4.  
    5.  
    6. voidAwake()
    7. {
    8. myRB=GetComponent<Rigidbody2D>();
    9. myRB.AddForce(newVector2(1,0)*projectileSpeed,ForceMode2D.Impulse);
    10. }
    and this bit at the end to call when the projectile triggers a collider :

    Code (CSharp):
    1.     public void removeForce ()
    2.     {
    3.         myRB.velocity = new Vector2 (0, 0);
    4.     }
    With your advices I changed this :

    Code (CSharp):
    1. myRB.AddForce(newVector2(1,0)*projectileSpeed,ForceMode2D.Impulse);
    to this :

    Code (CSharp):
    1. myRB.AddForce(newVector2(-1,0)*projectileSpeed,ForceMode2D.Impulse);
    and the projectile fires to the left now. \o/. But the problem remains, how can I instantiate it to match the current rotation of the player ?

    I could make a copy of the projectile script and rename one to projectilescriptLeft and the other to projectilescriptRight but this seem redundant, as i have to make a mirror prefab so that it fires one of them.

    I also could rewrite the fireProjectile (); but do I have to make it like that :

    Code (CSharp):
    1.  
    2. void fireProjectile ()
    3.     {
    4.       if (Time.time > nextFire)
    5.       {
    6.         nextFire = Time.time + fireRate;
    7.  
    8.         if (_motor.facingLeft)
    9.         {
    10.           Instantiate (projectileLeft, weaponMuzzle.position, Quaternion.Identity);
    11.         }
    12.         else if (!_motor.facingLeft)
    13.         {
    14.           Instantiate (projectileRight, weaponMuzzle.position, Quaternion.Identity);
    15.         }
    16.       }
    17.     }
    18.  
    with an added public GameObject projectileLeft / projectileRight variable and changing .Euler to .Identity since it doesnt seems to do any thing in my case.

    I'm not sure wich one is the best method and if that will work.

    Again, thanks for the help, I'll be back in this thread to let you know how it worked and if you or others have some tips/tricks/help I could use.

    EDIT
    I did what I wrote, mirroring the prefabs changing the fireProjectile(); function and now it works as intended, thanks a lot even tho it was a small reply, it did change my view on this issue and helped cleared this out.
     
    Last edited: Feb 22, 2016
  4. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, that's a reasonable solution, though personally I would prefer a projectile that goes in whatever direction it's facing.

    To do that, you could probably just change the projectile code to

    Code (csharp):
    1. myRB.AddForce(transform.right*projectileSpeed,ForceMode2D.Impulse);
    This makes it thrust in whatever is its own "right" direction, which will be (1,0) when it's not rotated, but when rotated, it will be whatever other direction is appropriate.

    Best,
    - Joe