0
\$\begingroup\$

Well, let's say I have two planes, one which I am moving, and another one that I collide with, that has a different y rotation. I want to make that, once both planes collide, the plane the user controls changes it´s rotation to the collided plane rotation.I´ve achieved it simply equaling both planes transform.rotations, but that was just a testing, i would like to rotate the plane smoothly. I have tried with eulerAngles, and Quaternion.Lerps, but it doesn´t work, or I am not following well the sintaxis. I know that a rotation and the eulerAngles are different values. There seems to be a solution with the dotween scripts, but I would like to learn the right approach to do it, rather than make it directly with dotween. Here I paste the trigger enter code, with the methods I tried (are commented). I guess that the rotation origin would be another issue.

void OnTriggerEnter(Collider col)
{
    if (col.gameObject.tag == "Plane")
    {
        Debug.Log ("Yup...Angle: " + col.gameObject.transform.rotation.y);
        //this.transform.rotation = col.gameObject.transform.rotation;

        /*newAngle 0 (this.transform.eulerAngles.x, col.gameObject.transform.eulerAngles.y, this.transform.eulerAngles.z);
        this.transform.eulerAngles(newAngle, 2 * Time.deltaTime);*/
        this.transform.rotation = Quaternion.Lerp (this.transform.rotation, col.gameObject.transform.rotation, Time.deltaTime * 0.1f);
    }
}
\$\endgroup\$
0
\$\begingroup\$

You are most of the way there already.

The problem is, OnTriggerEnter only happens once. Quaternion.Lerp changes the value over time, at the speed specified by the timestep. Since it is only being called once, it will only move the rotation one step. In this case, .1f * Time.deltaTime is your step. This is a very small number. It needs to move that small of a step many many times until the two values are equal.

If you made the step equal to the difference between the two values, that single call would be the same as setting one equal to the other.

So we need to move Quaternion.Lerp to something like Update() where it will happen dozens/hundreds of times.

Basically this:

private Quaternion targetRotation;
private float rotationSpeed = 2;

void Update()
{
    transform.rotation = Quaternion.Lerp(transform.rotation, targetRotation, rotateSpeed * Time.deltaTime);
}

void OnTriggerEnter(Collider col)
{
    if (col.gameObject.tag == "Plane")
    {
        targetRotation = col.gameObject.transform.rotation;
    }
}
\$\endgroup\$
  • \$\begingroup\$ Oh, I though it detected multiple collision enters (like OnCollisionEnter() would do, by default). Mmmm but I don't think it would be optimal having it in an Update(), do you think a while can do the trick? Let's say something like: a boolean that turns true when the trigger enters, then while it's true, do the Quaternion.Lerp, and once both rotations are equal, turn the boolean false. All of course in a function that takes the rotation of the col.gameObject that the trigger takes as you are proposing \$\endgroup\$ – LinkWindcrafter Apr 7 '16 at 0:36
  • \$\begingroup\$ A while will not do the trick, it would freeze the entire game until the while loop exits unless you put it inside a Coroutine with a yield. OnTriggerEnter and OnCollisionEnter fire once per collision/trigger. OnTriggerStay and OnCollisionStay are what you are looking for if you want constant calls while the two colliders are touching. \$\endgroup\$ – Allen Apr 7 '16 at 11:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.