- Home /
Stick a projectile to an object (arrow into an object)
So I am trying to stick an arrow into the object that the arrow collides with so, I am using OnCollisionEnter like so, where the script is attached to the arrow with a collider at the tip of the arrow:
private void OnCollisionEnter(Collision collision)
{
if (collision.collider.tag != "Player")
{
rb.isKinematic = true;
transform.parent = collision.gameObject.transform;
}
}
But that is creating some issues. Like when you parent the arrow to the object the scaling of the object is applied to the arrow. So if the object is scaled on the X by 10, the arrow will be scaled on the X by 10.
So, to solve that, I tried to re-scale the arrow after making it the child of the object with:
transform.localScale = new Vector3(transform.localScale.x / collision.transform.lossyScale.x, transform.localScale.y / collision.transform.lossyScale.y, transform.localScale.z / collision.transform.lossyScale.z);
But that didn't seem to do the trick. Anyone have any suggestions for alternatives or tweaks?
Answer by bakir-omarov · Jun 14, 2018 at 07:28 PM
UPDATE!
For the solving parenting scale problem you can use third gameobject. Because localScale gets first parents scaling, so we need new game object with 1,1,1 scaling in the middle (of hierarchy) of two attaching objects. It is common problem with making as a child game object without a scaling. So there is just few lines of code that will solve this:
private void OnCollisionEnter(Collision collision)
{
if (collision.collider.tag == "Player")
{
// greating Parent's child let's name him Father :D
GameObject sharedParent = new GameObject("Father");
sharedParent.transform.position = collision.transform.position;
sharedParent.transform.rotation = collision.transform.rotation;
// making child and grandpa as a kinematic
collision.gameObject.transform.GetComponent<Rigidbody>().isKinematic = true;
gameObject.GetComponent<Rigidbody>().isKinematic = true;
// assigning relatives
sharedParent.transform.parent = collision.gameObject.transform;
transform.parent = sharedParent.transform;
}
}
Hey, thanks for looking into this, here is a gif of what is going on in my scene:
I tried with a box at (1,1,1) scale and one at (1.75,1.75,1.75) and got different results
So I tried again, this time with the (1,1,1) as the parent and got what you got:
So, in order for the object to not change scale, the parent object would need to be the one with (1,1,1) scale as it is in your example as well. I don't think I could feasibly make the arrow the parent to whatever I hit could I? Hopefully that makes sense.
@Alan$$anonymous$$W2 now i got your problem, yeap this is tricky Unity problem) But there is the simple solution, check updated answer!
So that is pretty much what I did as well. At the point of impact I created a new empty (like you did) but just told the arrow to follow the rotation and positions changes in the update function, completely unrelated to the parenting of the hit object, ins$$anonymous$$d of making it a child. When I did it your way, there was still distortion in the scaling for narrow scaled objects (one of the directions being .1). Like in the gifs below:
vs not making the arrow the child of the empty game object to the wall:
I do appreciate the time you spent helping me out!
Now if I could figure out the best way to make the camera's mid point and the characters bow release point align to get the arrow where you want it to.
Take everything I said in the last comment, and forget it all. I think I see what the difference is now. Here is a gif, similar to what you have going on, the parent is scaled and the soon to be child is not, notice there is no issues:
Now look at this second gif, where the only difference is the rotation of the soon to be parent block:
So, when the blocks have the same rotation, parenting has no effect on the scale. But if the child block and the parent block rotations differ, they will not scale correctly. Interesting. This final gif should make it more clear:
Answer by PedroAK · Jun 14, 2018 at 07:21 PM
you can set a bool variable on the arrow and put a trigger on its top so when it hits something this bool is activated and it stops the movement
That is similar to what I am doing, but this would require that the object that the arrow hits to remain still for it to look right I think.