Reputation: 1214
I'm having a hard time grasping the concept of position in Unity.
Have a parent object (Player). On that player, I have a child object called "Gun". On the gun, I have a script to fire bullets. When I fire the bullets, it spawns to the left of the gun, and the player.
I've tried offsetting the bullet's position on spawn, but when I turn around, the location is incorrect (it's still not centered on the gun). I also have a feeling that the offset that I've tried is a hack, and that I've missed something somewhere.
My code for the firing script on the gun :
void Update()
{
if (Input.GetAxisRaw("Fire1") > 0)
{
var pos = transform.position;
print(pos.ToString());
var proj = Instantiate(projectile, pos, Quaternion.identity);
proj.transform.rotation = transform.rotation;
}
}
The only other thing touching the bullet, is my BulletController, a script on the bullet :
void Start()
{
rb = GetComponent<Rigidbody2D>();
//rb.AddForce(transform.forward * 100, ForceMode.Impulse);
rb.velocity = transform.up * 10;
}
Attached screenshot of my setup
Upvotes: 2
Views: 2007
Reputation: 1214
The problem was that I instantiated the sprite on the bullets on an offset, and not 0,0,0 relative to the actual gameobject.
Upvotes: 1
Reputation: 90813
feeling that the offset that I've tried is a hack
I don't see any offset .. you could do e.g.
public float offset = 0.5f;
if (Input.GetAxisRaw("Fire1") > 0)
{
// add the offset here
var pos = transform.position + transform.up * offset;
print(pos.ToString());
var proj = Instantiate(projectile, pos, Quaternion.identity);
proj.transform.rotation = transform.rotation;
}
transform.position
spawns the bullet at the same place as the gun. I added transform.up
since it seems this is the direction your player is looking to (in 3D space it would e.g. be transform.forward
but in 2D it is either transform.up
or transform.right
depending in which direction the player looks by default). offset
is just how far you want the bullet be placed in the given direction in meters/units.
If you rather want a Vector3
offset for more control/for debugging which axis is the correct one you could instead use
public Vector3 offset;
//...
var proj = Instantiate(projectile, transform.position, Quaternion.identity);
proj.transform.rotation = transform.rotation;
// Now move it to the offset in local space
proj.transform.Translate(offset, Space.Self);
You don't want to spawn it as child ... because if you than move or rotate after, your bullets will all also move and rotate together with you!
Upvotes: 1
Reputation: 816
You want to position the bullet to a relative offset based on the facing of the gun, right? If you set the position as you do now, you do it in world position unrelated to the facing of the gun.
Now, there are 2 ways how you can do it:
Place the bullet as a child object of the gun with a relative local position and unparent it immediately. Not a nice solution and resembles more a hack.
Or use the following methods, which I created:
/// <summary> Returns a vector which is relative to the facing and position of 'c'. </summary>
public static Vector3 RelativePosition (Transform c, Vector3 target)
{
return c.right * target.x + c.up * target.y + c.forward * target.z + c.position;
}
/// <summary> Returns a vector which is relative. </summary>
public static Vector3 RelativePosition (Vector3 position, Vector3 forward, Vector3 up, Vector3 right, Vector3 target)
{
return right * target.x + up * target.y + forward * target.z + position;
}
And complementary this:
/// <summary> Returns a vector which is relative to the facing of 'c'. </summary>
public static Vector3 RelativePositionZero (Transform c, Vector3 target)
{
return c.right * target.x + c.up * target.y + c.forward * target.z;
}
/// <summary> Returns a vector which is relative. </summary>
public static Vector3 RelativePositionZero (Vector3 forward, Vector3 up, Vector3 right, Vector3 target)
{
return right * target.x + up * target.y + forward * target.z;
}
Usage: Use the RelativePosition method, provide the Transform of the gun as parameter and the relative offset for the Vector3 parameter. Example:
item.position = RelativePosition (Camera.Main.transform, new Vector3 (1.5f, 0f, 4.0f));
This would place the position of 'item' 4 unity distance in front of the camera and 1.5 unity distance to the right.
Hint: RelativePosition will give you the resulting world position as it is. This is what you use to receive the relative position you seek as world position. RelativePositionZero will give you the relative offset from the Transform object to the given Vector3 position. That can be used to determine if something is left or right, above or below, in front or behind the given Transform.
Upvotes: 2