0
\$\begingroup\$

I'm trying to code a turret to angle towards a target, where I have one part of the turret only rotating on the left/right, and I want to animate another part to only angle up/down. I've got the left/right (RotateTowardsTarget) working, but I can't get the up/down (AngleTowardsTarget) to work, it seems to also rotate the object as well as angle it.

turretXRotation is a child of turretYRotation. These objects form the top of a gun turret, so the base will rotate, and the gun barrel will angle towards the target

/// <summary>
/// Orient the turret weapon towards the target.
/// </summary>
/// <param name="lookPosition"></param>
private void OrientWeaponsTowards(Vector3 lookPosition)
{
    RotateTowardsTarget(lookPosition);
    AngleTowardsTarget(lookPosition);
}

/// <summary>
/// Rotate towards the target.
/// </summary>
/// <param name="lookPosition"></param>
private void RotateTowardsTarget(Vector3 lookPosition)
{
    // Determine which direction to rotate towards
    Vector3 targetDirection = lookPosition - transform.position;

    // The step size is equal to speed times frame time.
    float singleStep = weaponRotationSpeed * Time.deltaTime;

    // Rotate the forward vector towards the target direction by one step
    Vector3 newDirection = Vector3.RotateTowards(
        turretYRotation.transform.forward,
        targetDirection,
        singleStep,
        0.0f
    );

    // Draw a ray pointing at our target in
    //Debug.DrawRay(turretYRotation.transform.position, newDirection, Color.red, 3);

    newDirection.y = 0;
    // Calculate a rotation a step closer to the target and applies rotation to this object
    turretYRotation.transform.rotation = Quaternion.LookRotation(newDirection);
}

/// <summary>
/// Angle towards the target.
/// </summary>
/// <param name="lookPosition"></param>
private void AngleTowardsTarget(Vector3 lookPosition)
{
    // Determine which direction to rotate towards
    Vector3 targetDirection = lookPosition - turretXRotation.transform.position;

    // The step size is equal to speed times frame time.
    float singleStep = weaponRotationSpeed * Time.deltaTime;

    // Rotate the forward vector towards the target direction by one step
    Vector3 newDirection = Vector3.RotateTowards(
        turretXRotation.transform.forward,
        targetDirection,
        singleStep,
        0.0f
    );

    // Draw a ray pointing at our target in
    //Debug.DrawRay(turretXRotation.transform.position, newDirection, Color.red, 3);

    // Calculate a rotation a step closer to the target and applies rotation to this object
    turretXRotation.transform.rotation = Quaternion.LookRotation(newDirection);
}

Does anyone know how I can just make the `turretXRotation` only change it's X value to aim towards the target? I've tried similar stuff to the rotating, by zeroing out some of the x/y/z coords, but I can't seem to crack it.
\$\endgroup\$
3
  • \$\begingroup\$ Before you try anything else, did you make sure the anchor of the gun barrel is set to the base of the barrel and not the center? So that you're not accidentally rotating around a random point in space. \$\endgroup\$
    – basklein
    Jun 5, 2020 at 4:09
  • \$\begingroup\$ Also, in what way is it not working right now? I think I have an idea, but could you maybe elaborate or post some screenshots? \$\endgroup\$
    – basklein
    Jun 5, 2020 at 4:14
  • \$\begingroup\$ Yeah the axis is set correctly. By not working it rotates every axis towards the target to the barrel on it's own is looking at the target, whereas I only want it to change the X rotation to point up/down towards the target \$\endgroup\$
    – TMH
    Jun 5, 2020 at 8:40

1 Answer 1

0
\$\begingroup\$

OK, this answer may sound a bit weird, but from what you've posted it looks like you're aiming the two parts separately at the same thing. So right now the gun barrel is probably rotating very weirdly, but is in the end still looking at the target as intended.

Now the bottom part of the turret is working fine, which makes sense, since that part just looks at the target normally, but ignores any vertical rotation. However, what you really should be doing when aiming the barrel, is aiming it as if the bottom part were already rotated correctly and facing the target.

Solution 1:

The fix would be to do this:

Vector3 look = Quaternion.LookRotation(newDirection).eulerAngles;
turretXRotation.transform.localRotation = Quaternion.Euler(look.x, 0, 0);

Solution 2:

A really easy but quite hacky way to do it would be to create an invisible game object inside the turret that tracks the target 1 to 1, then have the segments of the turret rotate towards those rotation values. That way you leave all the hard stuff for Unity to figure out.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .