0

I have one issue in unity 2d with my object , when i shoot the arrow to the box collider to the other element , and when it hit and go into child i mean arrow become child of parent (BOX) the child start to rotate to the left and to the right .. I really want to disable left and right rotation of the child .. the box (parent) still need to rotate as same as it was before.. i have code like this and my arrow in rigidbody2d is on kinematic mode...

this is script of the arrow ..

{
    public float flySpeed = 20f;
    private Rigidbody2D arrowBody;
    private bool shouldFly;


    // Start is called before the first frame update
    void Start()
    {
        shouldFly = true;
        arrowBody = GetComponent<Rigidbody2D>();
    }

    // Update is called once per frame
    void Update()
    {
        if (shouldFly == true)
        {
            //make our pin fly
            arrowBody.MovePosition(arrowBody.position + Vector2.up * flySpeed * Time.deltaTime);
        }
    }

    private void OnTriggerEnter2D(Collider2D collision)
    {
        if(collision.tag == "target")
        {

            shouldFly = false;
            transform.SetParent(collision.gameObject.transform);


        } else if(collision.tag == "arrow")
        {

            SceneManager.LoadScene("quickGameOverScene");
        }
    }
}
Foggzie
  • 9,691
  • 1
  • 31
  • 48
  • Did you try [Rigidbody.freezeRotation](https://docs.unity3d.com/ScriptReference/Rigidbody-freezeRotation.html) – Ali Kanat Feb 21 '19 at 09:03
  • @AliKanat Where you mean i put it in if statement of the ontriggereneter2d ? Something like arrowBody.freezeRotation ? I need it rotating but only on with child not moving right and left on child just to go around with child on fixed position... – Antun Jovanić Feb 21 '19 at 10:42

1 Answers1

1

I am really confused what you are trying to do. I do not understand if you want to freeze rotation or movement so i will post answers for both. In order to prevent translations and rotations caused by parent object you can use LateUpdate like this:

Quaternion InitRot;
Vector3 InitPos;

void Start () {
    InitRot = transform.rotation;
    InitPos = transform.position;
}
void Update()
{
    //figuring out when to save position when attached to BOX
    if(gameObject.transform.parent == null)
    {
        InitRot = transform.rotation;
        InitPos = transform.position;
    }
}
void LateUpdate () {
    //If attached to box do not translate do not rotate
    if (gameObject.transform.parent != null)
    {
        transform.rotation = InitRot;
        transform.position = InitPos;
    }
}

You can have more information about this solution from here

EDIT Since the answer above did not work out for OP. I figured out what the actual problem is. OP's code is perfectly fine for moving the arrow but the problem is most likely where he rotates the box.

If he rotates the box using transform.Rotate(Vector3.forward* 90), there will be a distortion caused by same amount of rotation in each Update since frame times are not same in each Update. Therefore, he needs to rotate the box using Time.deltaTime for consistent rotation like this: transform.Rotate(Vector3.forward* 90*Time.deltaTime); This rotate the box same amount in each time interval and eliminate distortion. These are the scripts i used for the task and it works for me.

Script for the arrow:

public float flySpeed = 20f;
private Rigidbody2D arrowBody;
private bool shouldFly;
private Vector2 initPos;
private Quaternion initRot;
// Start is called before the first frame update
void Start()
{
    shouldFly = true;
    arrowBody = GetComponent<Rigidbody2D>();
    //arrowBody.isKinematic = true;
    initPos = gameObject.transform.position;
    initRot = gameObject.transform.rotation;
}

// Update is called once per frame
void Update()
{
    if (shouldFly == true)
    {         
        //make our pin fly
        arrowBody.MovePosition(arrowBody.position + Vector2.up * flySpeed * Time.deltaTime);
    }
    if(gameObject.transform.parent == null)
    {
        initPos = gameObject.transform.position;
        initRot = gameObject.transform.rotation;
    }

}
void LateUpdate()
{
    if (gameObject.transform.parent != null)
    {
        gameObject.transform.position = initPos;
        gameObject.transform.rotation = initRot;
    }
}

private void OnTriggerEnter2D(Collider2D collision)
{
    Debug.Log("Collision happened");
    if (collision.tag == "target")
    {          
        shouldFly = false;          
        transform.SetParent(collision.gameObject.transform);
    }
    else if (collision.tag == "arrow")
    {

        SceneManager.LoadScene("quickGameOverScene");
    }
}

And The script for rotating the box:

public float rotationSpeed = 70f;
void Update()
{
    transform.Rotate(Vector3.back, rotationSpeed * Time.deltaTime);
}
Ali Kanat
  • 1,888
  • 3
  • 13
  • 23
  • But i don't have vector3 nor quaternion scripts or objects i have only RigidBody 2d ..I don't have idea how to implement your code to mine code.. do i really need vector ? P.s. i want to freeze movement rotation need to be the same as the parent rotation.. I think i need to put code into this method from up (void OnTriggerEnter2D) into first if block ..but what i need to put to freeze movement from arrowBody i really dont know.. please give me example for my example if you have time and if you want.. thank you so much. – Antun Jovanić Feb 21 '19 at 11:29
  • May i ask you if i implement by some luck your code , i don't need to do anything more to freeze movement when i attached to parent .. becuase it seems for me there is no value to freeze movement.. Maybe because i am pretty new to unity.. or something else.. if you can and if you have free time , please help me . :) – Antun Jovanić Feb 21 '19 at 11:34
  • Sorry i forgot you work in 2D. So clarify if i am wrong. You want the arrow to stick to the BOX and move with it but no additional movement? Am i correct? Also it would be helpful for me if you can share a video of the issue. – Ali Kanat Feb 21 '19 at 11:36
  • Yes of course , arrow when is in box it goes right when box rotate and to left , it stays in box but going around i want when arrow goes into box to can not move to left or right but it need to stay in box because box is rotating, i can not find code to freeze that.. I can show you video ,but i tried to explain it to you .. so when arrow hit box it must not move to right or to left it need to be fixed on that place because box is always rotating and arrow need to be at that position...now my arrow going to right and to left when box rotating.. it seems i need to freeze something but idk what.. – Antun Jovanić Feb 21 '19 at 11:40
  • So you want arrow to stay at the same position where it hit the box even though box is rotating clokcwise or counterclockwise? Is this correct? – Ali Kanat Feb 21 '19 at 11:48
  • Yes it must rotate as box rotates clockswise or counter... but it must not rotate Arrow body to left or right , so it need to be fixed into same poisition in box , but it must rotate with box but not to the left with body or right only to rotate how it was hitten before and stay into same position in box , and when box rotates arrow on the same place rotates into circle but arrow body must be freezed so it must not move to left or right when box rotates... .. I hope i answered you clearly – Antun Jovanić Feb 21 '19 at 11:53
  • Okay i understood the problem. I will work on it and edit my answer. – Ali Kanat Feb 21 '19 at 12:04
  • I hope you will know how to edit it to get it working into my code.. I think you will achieve it as you seems really smart as your reputation tell me.. I don't have idea where to find the solution or how to code it.. I searched a lot on google and seems like noone had problem like me ..thank you one more time for your time. – Antun Jovanić Feb 21 '19 at 12:30
  • Okay i think i figured it out. The problem is how you rotate the box. Can you share the line where you rotated the cube? – Ali Kanat Feb 21 '19 at 12:32
  • Yes of course here is my script for box rotation.................. public class targetRotationScript : MonoBehaviour { public float rotationSpeed = 70f; void update () { transform.Rotate(Vector3.back, rotationSpeed * Time.deltaTime); } } p.s. also at the box rotation constraint is selected for X and Y , Z is not disabled in constraints...maybe that help you.. thank you – Antun Jovanić Feb 21 '19 at 12:39
  • I appreciate your edit but that will not fix the problem as i mention in last comment i use Time.delta time..... like this , this is my code :: transform.Rotate(Vector3.back, rotationSpeed * Time.deltaTime); } I dont know what is going on and why arrow rotate to left and right with body.. please help me to find another solution,... because this is not a problem in rotation of box.. – Antun Jovanić Feb 21 '19 at 12:50
  • How did you make your rigidbody kinematic? Because that is the only thing i changed from your script and it works for me. – Ali Kanat Feb 21 '19 at 12:52
  • https://imgur.com/a/DsNfYTh , this is my rigibody kinematic for the arrow .. and it doesn't have any constraints... I hope you will find the solution and i hope i will fix it as fast as possible... So arrow when get into box it must not move to left or to right when box rotate.. – Antun Jovanić Feb 21 '19 at 12:57
  • So [this](https://drive.google.com/open?id=1jMilkoM_6BR2QE42o_IComda8K0kTXPF) is not what you want? – Ali Kanat Feb 21 '19 at 13:04
  • No because arrow when hit the box need to stay like this | not like this / or like this \ I dont know how to explain it when you put pin into box like on the video one way of the pin is going to left side and it need to be at right angle ... i dont't know how to explain i hope you now know what i want to achieve.. the arrow need to stay like this | into box not go left or right when box rotate.. ... – Antun Jovanić Feb 21 '19 at 13:13
  • On the video end of the arrow goes to left when box rotate , same issue as mine issue .. i want to achieve to stay same as it is when hit the box so when box rotate arrow stay the same not going to left or right at the end of it ... so no moves when hit the box – Antun Jovanić Feb 21 '19 at 13:15
  • Then my initial script was correct. I edited the Arrow Script in the answer with `Vector2` please try that. – Ali Kanat Feb 21 '19 at 13:19
  • Although it does not matter whether it is `Vector2` or `Vector3` – Ali Kanat Feb 21 '19 at 13:24
  • 1
    Thank you so much I will try it in 4,5 hours but i think now you get me what i need and i think you really made it how i want.. I want to go home from job to finish my application because your solution i bet will fix it. Thank you so much for your time , I live in Munich 3 months from now and We are not far away.. if you want you can send me email to cikatuna@gmail.com , I want to stay in contact with you .. mabye in future we can make something together ... THANK YOU , VIELEN DANK – Antun Jovanić Feb 21 '19 at 13:25
  • So when i use it it can be Vector2 or Vector3 it doesn't matter in 2d games ? Thank you so much man , without you i could not achieve my goals i am 99% sure that this solution will work without any problems... – Antun Jovanić Feb 21 '19 at 13:27
  • Well for `transform` component vector2 or vector3 does not matter. All your sprites have z = 0 mostly. So don't worry about that part. You are welcome :) I will send you an email. – Ali Kanat Feb 21 '19 at 13:28