Reputation: 157
I'm working through a book and have come to an issue. it's a top down shooting game that has the player rotate with the mouse and move with the keyboard. problem is when testing if either the mouse or the keyboard set off movement the image vibrates. If i push the arrow keys it moves in a circle the longer I hold the key the wider the circle. Below is the script I'm working with.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class PlayerBehaviour : MonoBehaviour
{
//movement modifier applied to directional movement
public float playerSpeed = 2.0f;
//current player speed
private float currentSpeed = 0.0f;
/*
* Allows us to have multiple inputs and supports keyboard,
* joystick, etc.
*/
public List<KeyCode> upButton;
public List<KeyCode> downButton;
public List<KeyCode> leftButton;
public List<KeyCode> rightButton;
//last movement made
private Vector3 lastMovement = new Vector3();
// Update is called once per frame
void Update()
{
//rotates ship to face mouse
Rotation();
//moves ship
Movement();
}
void Rotation()
{
//finds mouse in relation to player location
Vector3 worldPos = Input.mousePosition;
worldPos = Camera.main.ScreenToWorldPoint(worldPos);
/*
get x and y screen positions
*/
float dx = this.transform.position.x - worldPos.x;
float dy = this.transform.position.y - worldPos.y;
//find the angle between objects
float angle = Mathf.Atan2(dy, dx) * Mathf.Rad2Deg;
/*
* The transform's rotation property uses a Quaternion,
* so we need to convert the angle in a Vector
* (The Z axis is for rotation for 2D).
*/
Quaternion rot = Quaternion.Euler(new Vector3(0, 0, angle + 90));
// Assign the ship's rotation
this.transform.rotation = rot;
}
// Will move the player based off of keys pressed
void Movement()
{
// The movement that needs to occur this frame
Vector3 movement = new Vector3();
// Check for input
movement += MoveIfPressed(upButton, Vector3.up);
movement += MoveIfPressed(downButton, Vector3.down);
movement += MoveIfPressed(leftButton, Vector3.left);
movement += MoveIfPressed(rightButton, Vector3.right);
/*
* If we pressed multiple buttons, make sure we're only
* moving the same length.
*/
movement.Normalize();
// Check if we pressed anything
if (movement.magnitude > 0)
{
// If we did, move in that direction
currentSpeed = playerSpeed;
this.transform.Translate(movement * Time.deltaTime * playerSpeed, Space.World);
lastMovement = movement;
}
else
{
// Otherwise, move in the direction we were going
this.transform.Translate(lastMovement * Time.deltaTime * currentSpeed, Space.World);
// Slow down over time
currentSpeed *= .9f;
}
}
/*
* Will return the movement if any of the keys are pressed,
* otherwise it will return (0,0,0)
*/
Vector3 MoveIfPressed(List<KeyCode> keyList, Vector3 Movement)
{
// Check each key in our list
foreach (KeyCode element in keyList)
{
if (Input.GetKey(element))
{
/*
* It was pressed so we leave the function
* with the movement applied.
*/
return Movement;
}
}
// None of the keys were pressed, so don't need to move
return Vector3.zero;
}
}
Upvotes: 1
Views: 1539
Reputation: 3629
I studied your code for a while and could not find anything wrong with it. So I tested it myself and it works perfectly.
So I suppose there's something wrong with your scene. You might for example have your player object be a child of some object that rotates your axes: this would cause problems I suppose.
Have a new, empty scene. Add a new GameObject (a 3D cube for example, or a 2D sprite) and assign PlayerBehaviour to it. Now test: it should work perfectly.
Upvotes: 1