- Home /
Quaternion using global values instead of local. Please help :(
Hi, I am trying to have the turret rotate to where it should for the bullet to be fired correctly at the target. In this script I have it calculate what angle the bullet should be fired at. That part works perfectly. However, whenever this rotates the turret, it seems to use the global rotation instead of the local. Please note this script is attached to a parent object of the turret being rotated. What am I doing wrong? I used Debug.Log to determine that the turretRot variable is giving 270 degrees extra in the Y value because of the global rotation. I really am struggling with this and have been for a while, I would be thankful for any help at all. Thank you all. :)
EDIT: Would it just be easier (and less CPU intensive) to use a Bezier curve with different points, and have the bullet use a simple MoveTowards function to go to each point? I already have this set up I just thought this way that I am trying would look better and be more optimized. Is this true?
public class AngleCalculator : MonoBehaviour {
[SerializeField]
Transform cannonBase;
[SerializeField]
Transform turret;
[SerializeField]
Transform firePoint;
[SerializeField]
GameObject projectilePrefab;
[SerializeField]
float cooldown = 1;
private float currentSpeed;
private float currentAngle;
private float lastShotTime;
public float turnSpeed;
public float shootDelay;
private bool isTarget;
private Quaternion lookRotation;
public Transform currentTarget;
private float turretAng;
public void SetTargetWithSpeed(Vector3 point, float speed, bool useLowAngle)
{
currentSpeed = speed;
Vector3 direction = point - firePoint.position;
float yOffset = direction.y;
direction = direction - (Vector3.Dot(direction, Vector3.up) * Vector3.up);
float distance = direction.magnitude;
float angle0, angle1;
bool targetInRange = LaunchAngle(speed, distance, yOffset, Physics.gravity.magnitude, out angle0, out angle1);
if (targetInRange)
currentAngle = angle0;
//currentAngle = useLowAngle ? angle1 : angle0;
SetTurret(direction, currentAngle * Mathf.Rad2Deg);
}
public void Fire()
{
GameObject p = Instantiate(projectilePrefab, firePoint.position, Quaternion.identity);
p.GetComponent<Rigidbody>().velocity = turret.forward * currentSpeed;
lastShotTime = Time.time;
}
//
private void SetTurret(Vector3 dir, float turretAngle)
{
isTarget = true;
lookRotation = Quaternion.LookRotation(dir);
turretAng = turretAngle;
}
// Update is called once per frame
void FixedUpdate () {
//SetTargetWithSpeed(target.transform.position, initialFireSpeed, useLowAngle);
if(isTarget == true)
{
Vector3 turretRot = new Vector3(-turretAng, lookRotation.eulerAngles.y, lookRotation.eulerAngles.z);
Debug.Log(turretRot);
Vector3 rotation = Vector3.MoveTowards(cannonBase.rotation.eulerAngles, lookRotation.eulerAngles, Time.deltaTime * turnSpeed);
Vector3 rotation2 = Vector3.MoveTowards(turret.rotation.eulerAngles, turretRot, Time.deltaTime * turnSpeed);
cannonBase.rotation = Quaternion.Euler(0f, rotation.y, 0f);
turret.rotation = Quaternion.Euler(rotation2.x, rotation2.y, 0f);
}
else if(currentTarget == null && !isTarget)
{
isTarget = false;
}
}
public void CalculateAngle(Transform target, float initialFireSpeed, bool useLowAngle)
{
SetTargetWithSpeed(target.position, initialFireSpeed, useLowAngle);
currentTarget = target;
StartCoroutine(WaitFire());
}
public IEnumerator WaitFire()
{
yield return new WaitForSeconds(shootDelay);
Fire();
}
/// <summary>
/// Calculates the two possible initial angles that could be used to fire a projectile at the supplied
/// speed to travel the desired distance
/// </summary>
/// <param name="speed">Initial speed of the projectile</param>
/// <param name="distance">Distance along the horizontal axis the projectile will travel</param>
/// <param name="yOffset">Elevation of the target with respect to the initial fire position</param>
/// <param name="gravity">Downward acceleration in m/s^2</param>
/// <param name="angle0"></param>
/// <param name="angle1"></param>
/// <returns>False if the target is out of range</returns>
private bool LaunchAngle(float speed, float distance, float yOffset, float gravity, out float angle0, out float angle1)
{
angle0 = angle1 = 0;
float speedSquared = speed * speed;
float operandA = Mathf.Pow(speed, 4);
float operandB = gravity * (gravity * (distance * distance) + (2 * yOffset * speedSquared));
// Target is not in range
if (operandB > operandA)
return false;
float root = Mathf.Sqrt(operandA - operandB);
//High Angle
angle0 = Mathf.Atan((speedSquared + root) / (gravity * distance));
//Low Angle
angle1 = Mathf.Atan((speedSquared - root) / (gravity * distance));
return true;
}
}
Your answer
Follow this Question
Related Questions
Smooth rotation to child object 1 Answer
Quaternions local/world 1 Answer
Flight Movement with Banking 2 Answers
Trouble with Camera Rotation Math 2 Answers
Random.rotationUniform clarification 4 Answers