- Home /
Orbital cannon jitters while following/facing mouse position
Hello everyone, I have a simple scenario where a flying 2d dynamic Rigibody "Spaceship" gameobject floating in space using addforce and addtorque (translation and rotation). A child (of "Spaceship") gameobject "Cannon" that orbits around the spaceship relative to the current mouse position. The cannon can only move between object x and y (limited angle) and is always facing the mouse position while in range. See the picture below for more details:
Everything was ok. But after implementing a camera script that follows the spaceship (in LateUpdate and it´s attached to the main camera), the orbital cannon starts to jitter while the ship is moving. My guess is that the mouse position (ScreenToWorldPoint) is now changing constantly while the camera is moving and the orbital cannon is trying to follow and face the position. Probably that´s what´s causing this weird jitter motion!! You can have a look at the OrbitalCannon controller. The cannon object does not have a 2d Rigibody component attached to it. Only the spaceship does.
using UnityEngine;
public class OrbitalCannonController : MonoBehaviour
{
public float SlidingSpeed = 1;
private Transform orbitalCannon;
private float orbitRadius;
private float currentAngle;
private Vector3 centerToMouseVector; // vector from Ship center to the world mouse position
private Vector3 nexPosition;
void Awake()
{
orbitalCannon = this.transform; // cach transform.
orbitRadius = Vector2.Distance(Ship.position, orbitalCannon.position);
centerToMouseVector = orbitalCannon.position - Ship.position;
}
private void Update()
{
//get the vector between mouse position (projected in game world) and the center of the circle (Ship)
centerToMouseVector = Camera.main.ScreenToWorldPoint(Input.mousePosition) - Ship.position;
centerToMouseVector.z = 0; // zero z axis since we are using 2d
float x = Vector2.SignedAngle(centerToMouseVector, Ship.up);
if ((x > 20 && x < 70) || centerToMouseVector.magnitude < orbitRadius) return;
// we normalize the new direction so you can make it equal to the radius length
// then we add it to the circle (aka Ship) center position
nexPosition = Ship.position + (orbitRadius * centerToMouseVector.normalized);
// get the correct angle between the circle (Ship) and mouse position in the world space
currentAngle = Mathf.Atan2(centerToMouseVector.y, centerToMouseVector.x) * Mathf.Rad2Deg;
orbitalCannon.position = Vector3.MoveTowards(orbitalCannon.position, nexPosition, Time.deltaTime * SlidingSpeed); // lerp cannon to the position
orbitalCannon.rotation = Quaternion.Euler(new Vector3(0, 0, currentAngle - 90)); // rotate orbital cannon to face the mouse.
}
}
Can anyone help me solve this problem? What am I doing wrong here? And if there is any better/optimized approach to achieve the same control, I would love to know it (using rotateAround() or something similar) because I believe that the current implementation is a performance overkill.
No. Only one with a simple script attached to it
using UnityEngine;
public class CameraController : $$anonymous$$onoBehaviour {
public GameObject Target; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
void Start ()
{
// distance between the player's position and camera's position.
offset = transform.position - Target.transform.position;
}
void LateUpdate ()
{
// Follow target
transform.position = Target.transform.position + offset;
}
}
I tried to move the whole calculation stuff to LateUpdate but it didn´t work. Any suggestions?
Answer by Igor_Vasiak · Aug 17, 2017 at 03:06 PM
Try to put the calculation stuff in FixedUpdate(). If it doesn't work change the camera’s script’s calculation to Update() or FixedUpdate().
This is what every method do:
Update runs every frame, just before LateUpdate.
LateUpdate runs just after Update does, and runs just before the Camera renders.
FixedUpdate runs on a constant timing, and by default as close as possible to the physics calculation.
Let me know if it worked.
Thank you for answering. Yes, It´s working if you put the calculation stuff inside "FixedUpdate" function or changing camera script´s calculation from "LateUpdate" to "Update". But It's generally a bad idea to use FixedUpdate for anything except physics. $$anonymous$$aybe not in my case because the mother ship movement is calculated inside "Fixedupdate". As for using "Update" ins$$anonymous$$d "lateUpdate" for the camera script, I would rather not do that because the camera is always tracking objects that might have moved inside Update already. So am I right? Any child of the 2d rigibody physics Spaceship, like the orbital cannon for example (or any other child) must have their stuff calculated inside FixedUpdate? Because they carry the physics behavior from the parent with them?
Yep. That should be it. I mean, I don't know if every single child object needs to have the things implemented inside FixedUpdate(), but at least the ones that will move and use physics on their own.
I'm glad to know that I helped you out.
I think so. But we still need to ask an expert about it just to be sure. Anyway, thank you for helping me sir :)
Your answer
Follow this Question
Related Questions
Flip over an object (smooth transition) 3 Answers
Cube Gravity - Apply Gravity to a Curve 0 Answers
Unity C# 2D Adding Velocity on rotation 1 Answer
Can't do Quaternion.AngleAxis twice. 1 Answer