- Home /
After rotation, object moves forward in old (mouse) direction.
Hi there.
2nd try in explaining my problem.
I'm moving my spaceship forward in the mouse direction. (The below script is attached to the spaceship) When I press 'L' my ships turns the the nearest enemy. But when I move forward again (trying to move close to the nearest enemy) my ship immediately turns back to the position it left right before I pressed L. As explained in these drawings.
How does this happen? Is it because I work with 2 different Quaternion rotations? I can't get my head around it. But it is probably very simple... I need to have it work like this:
See (full) script below:
public class PlayerMovement : MonoBehaviour
{
[SerializeField] float movementSpeed = 35f;
Transform t;
private bool moveObject;
public float mouseSensitivity = 100.0f;
public float clampAngle = 80.0f;
private float rotY = 0.0f;
private float rotX = 0.0f;
void Awake()
{
t = transform;
moveObject = true;
Vector3 rot = transform.localRotation.eulerAngles;
rotY = rot.y;
rotX = rot.x;
}
void Update()
{
Move();
MousepointedMovement();
if (Input.GetButtonDown("Vertical-"))
{
moveObject = true;
}
}
void MousepointedMovement()
{
float mouseX = Input.GetAxis("Mouse X");
float mouseY = -Input.GetAxis("Mouse Y");
rotY += mouseX * mouseSensitivity * Time.deltaTime;
rotX += mouseY * mouseSensitivity * Time.deltaTime;
rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);
Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
transform.rotation = localRotation;
}
void Move()
{
if (moveObject == true)
{
t.position += t.forward * movementSpeed * Time.deltaTime * Input.GetAxis("Vertical-");
}
}
public void AutoTarget(Transform target)
{
if (Input.GetKeyDown(KeyCode.L))
{
moveObject = false;
Vector3 relativePos = target.position - transform.position;
Quaternion rotation = Quaternion.LookRotation(relativePos);
transform.rotation = rotation;
}
}
}
Good day.
You really pretend us to read all this code to explain you something that is not correct, when you did not writed the code... Please make an acceptable post with an acceptable question giving only the info we need.
Hi @tormentoarmagedoom , Well, yeah I don't really know what to expect. It's always hard to formulate a question with the least information possible. I'm not a coder by nature, that is why I'm asking for help in the first place. I can understand the C# language, but not write it on a deeper level.
So, yes I sticked some codes from tutorials together and so far it's really working. I'm sorry for posting such a long script, but I thought people (who might be interested) need it to understand what's going on. But from your comment I understand the 'question' itself is also not clear, right?
I'll try and formulate is better. Thanks for taking the effort to reflect on my post, and a good day to you too.
@yaourt , as I understand correctly, the main issue is that the Input.GetAxis("$$anonymous$$ouse X") & Input.GetAxis("$$anonymous$$ouse Y")
do not change (when I autoTarget), so when those values stay the same, --> the Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
stays the same?
So when the script leads back to void $$anonymous$$ousepointed$$anonymous$$ovement()
it still 'thinks' is has the correct (but old) information? Do I need to tell how much the object has rotated (when pressed L)?
Hope you can give me another hint to get me moving forward with this. THNX!
Yes something like that. $$anonymous$$ousepointed$$anonymous$$ovement()
has no info about any autoTarget so it turns your object based on your mouse position when you reactivate it. Depending on what kind of result you want, you should probably detect mouse movement and then able your $$anonymous$$ousepointed$$anonymous$$ovement()
. Or create a float which contains your current rotation, you totally change it when you auto target, and add a rotation based on mouse movement... Or you can also move your mouse position. A lot of different ways to do this kind of thing, all depends on the specific interaction type you decide to use. As I said Debug.Log every line, every value, one after the other if needed, and you should be able to solve your problem by your own :p
detecting mousemovement or creating a float. Both sound great. I will let you know asap when (and if) those worked! Thank you.
Answer by ngerbens · Nov 11, 2018 at 10:25 PM
@yaourt , well I solved it, thanks to your help!
And like most of the times, and thankfully, it was very easy. But I couldn't have seen it without your direction. I learned a lot.
It was actually just a matter of updating the float 'rotY'
& 'rotX'
after the autotarget rotation. That's it. Plus I implemented the mouse movement detection you mentioned and used it as a trigger to set mouseMovement to true after the auto-rotation.
Just in case it might be useful to someone ever visiting this question, here's the updated script:
public class PlayerMovement : MonoBehaviour
{
[SerializeField] float movementSpeed = 35f;
Transform t;
private bool moveObject = true;
private bool mousePointing = true;
public float mouseSensitivity = 100.0f;
public float clampAngle = 80.0f;
private float rotY = 0.0f;
private float rotX = 0.0f;
void Awake()
{
t = transform;
Vector3 rot = transform.localRotation.eulerAngles;
rotY = rot.y;
rotX = rot.x;
}
void Update()
{
float mouseX = Input.GetAxis("Mouse X");
float mouseY = -Input.GetAxis("Mouse Y");
rotY += mouseX * mouseSensitivity * Time.deltaTime;
rotX += mouseY * mouseSensitivity * Time.deltaTime;
rotX = Mathf.Clamp(rotX, -clampAngle, clampAngle);
Move();
MousepointedMovement();
if (Input.GetAxis("Mouse X") < 0 || Input.GetAxis("Mouse X") > 0)
{
mousePointing = true;
}
if (Input.GetButtonDown("Vertical-"))
{
moveObject = true;
}
}
void MousepointedMovement()
{
Quaternion localRotation = Quaternion.Euler(rotX, rotY, 0.0f);
transform.rotation = localRotation;
}
void Move()
{
if (moveObject == true)
{
t.position += t.forward * movementSpeed * Time.deltaTime * Input.GetAxis("Vertical-");
}
}
public void AutoTarget(Transform target)
{
if (Input.GetKeyDown(KeyCode.L))
{
moveObject = false;
mousePointing = false;
Vector3 relativePos = target.position - transform.position;
Quaternion targetRotation = Quaternion.LookRotation(relativePos);
transform.rotation = targetRotation;
Vector3 floatingRotation = transform.localRotation.eulerAngles;
rotY = floatingRotation.y;
rotX = floatingRotation.x;
if (transform.rotation == targetRotation)
{
mousePointing = true;
moveObject = true;
}
}
}
}
PS I still have to clean some stuff up, like setting the 'mousePointing' to true doesn't make any sense since it already goes by itself when the mouse moves...
Answer by yaourt · Oct 11, 2018 at 09:52 AM
It seems that you constantly update rotation with MousepointedMovement(); Even if you copy/paste code, try to comment lines and debug.log to understand what's happening and when each function is called, it's much faster than trying to explain your problem and waiting for response!
Well, I tried to debug a lot (and continue to do so), I'm wrestling with this thing for a while now. I'm not trying to get easy info here. I want to learn something. Learn how this works.
I just simply do not understand how the $$anonymous$$ousepointed$$anonymous$$ovement(); doesn't update my new rotation.
Why doesn't Input.GetAxis("$$anonymous$$ouse X" + "$$anonymous$$ouse Y") 'update' the input, since I am turned around, and the input should be updated?
Now I think I don't understand your problem... Do you call AutoTarget from an other script? If you log a string in AutoTarget does it print when you press L? If you Log your mouseX and mouseY, does it return what you expect? Try to comment out everything applying rotation, add a few logs and see if everything is fired at the right time. Then you could be able to know if your problem is a function call when you don't want it, or a wrong rotation/position calculation.
$$anonymous$$y Autotarget is called from another script, yes. The autotarget functions perfectly. When I press L my player rotates to the object. I also checked $$anonymous$$ouseX & Y, they do not change when my player turns to the (auto)target, which is correct I assume.
The problem is: When I press L (autotarget), I have to set the $$anonymous$$ousepointed$$anonymous$$ovement() to 'false' otherwise my player won't turn to my autotarget obviously . When I set my $$anonymous$$ousepointed$$anonymous$$ovement() back to 'true', my player immediately turns back to the previous mouse pointed position (like in the drawings).
$$anonymous$$aybe I have to use a coroutine for my autotarget moment? Didn't try it yet. But that seems like an ugly solution?