- Home /
Child transforms screwed up by parent's rotations
The transforms of children get changed whenever I rotate their parents. The problem manifests itself in several ways:
EXHIBIT A: I have a turret object that rotates on the horizontal axis using Quaternion.RotateTowards. I have a childed camera parented to the turret at zero localRotation but set a bit higher (y+1). The camera is controlled by MouseLook and I Raycast from the camera using its transform.forward in order to set targets for the turret.
When the turret is at rest (pointing forward) I can raycast accurately, but when it is rotated more than +-15 degrees, the Raycasts go off target. They start off in the right place, but shoot either higher (+rotation) or lower (-rotation) than the center of the screen.
EXHIBIT B: I have a muzzle childed and placed a certain distance forward of the turret. It has zero localRotation. When firing, a projectile is instantiated, using the muzzle's transform.forward.
Again, when the turret is at rest, the projectile speeds straight from the muzzle. But when the turret is rotated, the projectile goes off target, either flying into the sky or slamming into the ground in front of the turret.
EXHIBIT C: I have a particle system childed to the muzzle that is supposed to create a jet of smoke particles forward every time I fire the gun. I have noticed that it sprays the smoke EVERYWHERE, even if the projectile is on target.
As you can see, there are TWO jets of smoke.
CONCLUSION: I have tried eliminating most other scripts that affect the rotations until only the turret rotates, but same deal. Raycasts and projectiles still go off target. I even tried using Camera.ScreenPointToRay, but same result.
I also guarded the child's transforms by resetting their localPositions and localRotations every frame. No joy.
One way I mitigated this was to not make the muzzle and camera children of the turret and simply set their position every frame. It works to a point, but might end up giving me more problems down the road.
CODES: Here are the codes I use to rotate and RayCast:
function RotateTurretTo (aimpoint:Vector3) {
var turretRotation = Quaternion.LookRotation(aimpoint-turret.position, Vector3.up);
turret.rotation = Quaternion.RotateTowards(turret.rotation, turretRotation, turretSpeed);
}
function Fire() {
if (canFire) {
var shot = new Instantiate(bullet,muzzle.position,muzzle.rotation);
shot.rigidbody.velocity += this.rigidbody.velocity;
canFire = false;
}
}
function CommandTarget () {
var ray = new Ray(viewportCommander.transform.position,viewportCommander.transform.forward);
var hit : RaycastHit;
if (Physics.Raycast (ray, hit, 10000, targetMask)) {
if (hit.transform.gameObject.layer == 15) {
gunner.target = hit.transform;
}
if (hit.transform.gameObject.layer == 10) {
gunner.targetPosition = hit.point;
}
}
}
I've been tearing my hair out for a long while now. If anyone knows how to solve this or even offer insight, it would be greatly appreciated.
ADDENDUM: Added an EXHIBIT C. On further experimentation, I found that lowering the time scale made the problem even worse.
Look into local space rather than world or global space(i forget the exact term) - this will change whether you are rotating relative to the parent or global xyz axies
Hmm. I actually transferred over from using local space since it didn't work well with my targeting code. I'll see if it makes a difference when I get back to my computer. Cheers.
No joy. localRotations chuff my rotating code. Badly.
function RotateTurret(aimpoint:Vector3) {
var targetVector = aimpoint - turret.position;
var localVector = turret.InverseTransformDirection(targetVector);
var targetRotation = Quaternion.LookRotation(localVector,Vector3.up);
turret.localRotation = Quaternion.RotateTowards(turret.localRotation , targetRotation, 2);
}
It doesn't center on the aimpoint, and spazzes out when it goes from +1 to -1 degrees.
Answer by Jan_Julius · Sep 10, 2014 at 01:40 PM
I will get back to this, but have you tried putting an empty game object to where you want them to spawn and then just spawn them there instead?
Yes, that is the $$anonymous$$uzzle object indicated in the Fire method. It is parented to the turret.
Try putting a non rotated object in your scene and getting the rotation from that.
Place an empty game object with (0,0,0) rotations and try getting the rotation from that object just to see what that does.
Hmm. So I made the muzzle copy an empty gameObject's rotation, like you said, and it still occasionally goes off target.
On closer inspection, the projectile seems to follow the local X rotation of the turret whenever it does screw up. Like something was resetting the muzzle's local rotation to zero every so often. I'll have to look deeper into this.