Hello, I have recently been trying to rotate an object at a constant speed, but I failed to do so. You see the "LookAt" moves fast at first but as it begins to come closer to the designated rotation it slows down. Thank in advance
Have you tried using any of the examples here: http://docs.unity3d.com/Documentation/ScriptReference/Transform.Rotate.html Alternatively, you can create an animation clip using the animation editor in Unity.
Hello and thank you for replying, Yes I have tried that but you see what I'm trying to do is make it look at a moving object ( slowly, constant speed) But not rotating it using buttons/inputs. Is there a way to modify the look at so that it will not slow down before reaching the target ?
Can you post your current code? I'm having trouble trying to understand the functionality you're looking for. Is it something like SmoothLookAt (http://wiki.unity3d.com/index.php/SmoothLookAt_CS) except without the easing effect?
LookAt should not be slowing down, it should be following the object constantly. Could you try and describe precisely what the function you wish to achieve is?
Hi, i know exactly what you mean with constant rotation speed, i used this in my game to rotate at a constant rate towards my reticle (try the game in my signature to see it in action, press U to slow down time if it is to fast) just use: http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.RotateTowards.html if you don't get any results respond, i can post my code in ~8hours when i get home from work... EDIT: -a nice little trick for constant speed is using an empty gameObject(just for having a transform) rotating around another gameObject that uses LookAt to look at the empty gameObject -or http://docs.unity3d.com/Documentation/ScriptReference/Transform.RotateAround.html using the position of itself
Thank you for replying gentlemen. Mart... You do really understand my problem. You see theres a turret. A pivot in it and some empty transform 3 meters in front of it . The empty transform rotates AROUND THE PIVOT that is in the turret. And the turret turns toward the transform that is 3Meters in front of the pivot. World of Tanks players ( Not advertising or anything!!! ) would understand like you mart .but it looks like someone has the same issue as me . I will try your suggestion as soon as I get home from school.. Thank you.
Ok, so I have tried to do what you mentioned above , but I couldn't figure out how to "Get It To Work". Please be patient with me, I'm not much of a proggramer/scripter .
This is my solution, it allows to cap the rotation speed to a certain amount of degree/s, call it every Update: Code (csharp): private void ShipRotationLimited(){ //LIMITED Rotation caused by Movement of Reticle Quaternion limitedRotation = new Quaternion(0F,0F,0F,0F); Quaternion rotation = Quaternion.LookRotation(rt.reticleOrigin - thisTransform.position); //lock rotation, yaw only rotation.eulerAngles = new Vector3(0,rotation.eulerAngles.y,0); //rotates the Ship to Reticle with fixed speed limitedRotation = Quaternion.RotateTowards(thisTransform.rotation, rotation, degsPerSec * Time.deltaTime); thisTransform.rotation = limitedRotation; } if you need a unlimited offsetRotation like i do in my game for recoil (rotations caused by recoil are not capped by my degsPerSec) Code (csharp): private void ShipRotation(){ //Using Model as rotation origin //LIMITED Rotation caused by Movement of Reticle Quaternion limitedRotation = new Quaternion(0F,0F,0F,0F); Quaternion rotation = Quaternion.LookRotation(rt.reticleOrigin - shipModelTransform.position); //lock rotation, yaw only rotation.eulerAngles = new Vector3(0,rotation.eulerAngles.y,0); //rotates the Ship to Reticle with fixed speed limitedRotation = Quaternion.RotateTowards(lastLimitedRotation, rotation, degsPerSec * Time.deltaTime); lastLimitedRotation = limitedRotation; //save limitedRotation for next frame //UNLIMITED rotation caused by Recoil: //independently from maxDegree/s rotate additionaly by the recoil and add it to the limited rotation //this makes rotations caused by recoil independent from the maxRot/s //so this should behave like an maxDeg/s-indepenent rotation Offset! Quaternion unlimitedRotation = new Quaternion(0F,0F,0F,0F); //calculate Angle Difference Quaternion shipToGhostReticleRotation = Quaternion.LookRotation(rt.ghostReticleOrigin - thisTransform.position); Quaternion shipToReticleRotation = Quaternion.LookRotation(rt.reticleOrigin - thisTransform.position); unlimitedRotation = Quaternion.Inverse(shipToReticleRotation) *shipToGhostReticleRotation; //APPLY the combined Rotation (addition of 2 quats is done by mutliplying them, subtraction by multiplying the inverse) thisTransform.rotation = limitedRotation * unlimitedRotation; } Description: -This Function is Called Every Update() -it rotates my ship (shipModelTransform) with a constant speed (degsPerSec) to my reticleOrigin (rt.reticleOrigin, this is a position so you have to put a Vector 3 in there) -but this rotation is only applied for the y-axis, check the axis you need, the y axis is the axis parallel to gravity Unlimited Rotation: -The unlimited Rotation offsets the Rotation making the ship point to a recoil reticle which can be moved with infinite speed to simulate recoil (very nice effect for better shooting experience for a top down shooter) -to use it you have to have another position (rt.ghostReticleOrigin) -this position should be the reticle's position + a recoilVector that grows when shooting and decreases over time (just look at my game in the signature, the recoil affected reticle is the ghostreticle)
Thanks for Replying Maart, You're soloution is a bit "Advanced" for a novice like me. i do not really have much knowledge about C#. Perhaps you can point out the important part from the code that limits the rotation speed ? Thank you
yeah ,just edited the post since i found a way to improve my script now, just use the first box and you should be fine: thisTransform.rotation -> your turret that has to rotate, e.g. this could be: myTurret.transform.rotation rt.reticleOrigin -> your position you want to target, e.g. this could be: myReticle.transform.position or your cursor position with cam.ScreenPointToRay(Input.mousePosition).GetPoint(cam.position.y); //getPoint gets a specific distance to the camera
erm... All this is fine and dandy, there is a simple way to do this: Use the target position to find the rotation point of the turret by swapping that location to the local space, then setting it's Y to zero, then back to world space. Next, store the current rotation, do a LookAt with the turret, using it's Up vector. Now, do a Quaternion.RotateTowards using the orignal rotation, the look rotation and the traverse speed times the deltaTime. Code (csharp): var turretTraverseSpeed:float = 40; function MoveTurret(target:Transform){MoveTurret(target.position);} function MoveTurret(target:Vector3){ var lookAt:Vector3 = transform.InverseTransformPoint(target); lookAt.y = 0; lookAt = transform.TransformPoint(lookAt); var rotation:Quaternion = transform.rotation; transform.LookAt(lookAt, transform.up); var lookRotation:Quaternion = transform.rotation; transform.rotation = Quaternion.RotateTowards(rotation, lookRotation, turretTraverseSpeed * Time.deltaTime); } http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.RotateTowards.html
not that obvious but for sure easier than my approach question: does that "lookAt.y = 0;" generate more instructions in background? since in c# i am not allowed to set the y of a Vector directly (always have to assign the whole vector) since i asked the above, i always wondered what LookAt() does in background, is it cheaper than LookRotation? just curious, maybe you know
LookAt is fairly cheap. Though I am not the Quaternion master here. The lookAt.y is a generic Vector3 assignment. Notice that lookAt was created on the line previous. It has no real extra processing value or importance other than to make sure that the LooAt point is on the same plane as the turret. Using this you have no x rotation when you do the actual LookAt. At no point do I specifically set a position or rotation element here. So: transform.position.y = 3; is never done. (this can be done in US, but not in CS) LookRotation is a portion of LookAt, so obviously it is greater than the sum of LookRotation. How much more, I do not know. These are mathematical functions though. They are incredibly quick. You could always set up a test to see how much of an impact this has in the overall picture. (run it 10000 times in one frame and see if your frame rate drops.)
Code (csharp): lookAt.y = 0; Is equivalent in performance to Code (csharp): lookAt = new Vector3 (lookAt.x, 0, lookAt.z);
Thank you gentlemen, I will try to put your suggestions in my game and see how it works. I will reply if I have any issues but at the moment i appreciate the help Thanks guys. EDIT: Worked like a charm... I dont know what to say. Thank you bigmisterb, Marrt and all who tried to help.