So I just finished writing my movement script and my game seems like it has a low framerate. I booted up fraps and found that my game is running at 60FPS. What could be the issue? Also this is a top down RPG style game by the way.
Here's my movement script if that helps:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMovement : MonoBehaviour {
Vector2 _playerPosition;
public GameObject Player;
// Use this for initialization
void Start () {
_playerPosition = Vector2.zero;
}
// Update is called once per frame
public float speed = 3f;
void Update()
{
if (Input.GetKey(KeyCode.W))
{
transform.position += Vector3.up * speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.S))
{
transform.position += Vector3.down * speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.D))
{
transform.position += Vector3.right * speed * Time.deltaTime;
}
if (Input.GetKey(KeyCode.A))
{
transform.position += Vector3.left * speed * Time.deltaTime;
}
}
}
Watching YouTube tutorials can be real helpful in learning new things about Unity. look here at 4 min and you will see code that I would try for your transform like this:
if (Input.GetKey(KeyCode.D)){
transform.Translate(speed * Time.deltaTime,0f,0f); //x,y,z
}
The suggestion I had in the question's comment, I would put your if statements inside a method outside the update and call the method say every second like so, which Unity has a good community of question/answers as well
InvokeRepeating("MyMethod", 1f, 1f); //I believe this is every second
I would also make a suggest change to your code that would reduce the lines and allow for movement keys of left,right,up,down as well as A,D,W,S and us of joystick movements.
void Update(){
transform.Translate(speed * Input.GetAxis("Horizontal") * Time.deltaTime, 0f,
speed * Input.GetAxis("Vertical") * Time.deltaTime)
}
Related
This is my code to handle he simple player movement for a game object. It allows the user to move the object up and down, left and right, and enables rotation.
public class PlayerMovement : MonoBehaviour
{
public float moveSpeed = 10f;
public float rotateSpeed = 10f;
public Rigidbody2D rb;
Vector2 movement;
void Update()
{
movement.x = Input.GetAxis("Horizontal");
movement.y = Input.GetAxis("Vertical");
if (Input.GetKey(KeyCode.Space))
{
transform.Rotate(Vector3.forward * rotateSpeed * Time.fixedDeltaTime);
}
}
void FixedUpdate()
{
rb.MovePosition(rb.position + movement * moveSpeed * Time.fixedDeltaTime);
}
}
I am under the impression that:
Update() is called every gametick and
it is better suited for general detection, such as keypresses.
and that:
FixedUpdate() is called 50 times per second and
it is better for game object transformation.
So if my key input detection is in the Update() method
if (Input.GetKey(KeyCode.Space))
{
transform.Rotate(Vector3.forward * rotateSpeed * Time.fixedDeltaTime);
}
Then should my rotation code be in FixedUpdate(). If so, how do I get it to run there while still detecting the keypress in Update()?
FixedUpdate is used to be in-time with the physics system. You would use FixedUpdate when applying a force (or in your case, MovePosition) to a RigidBody.
As for your Rotate, you should do it in Update. That will give you the most accurate position for the next rendered frame (even if Update is called multiple times before the next frame). Also, you should use Time.deltaTime in your Update calculation. Like so:
transform.Rotate(Vector3.forward * rotateSpeed * Time.deltaTime);
Time.fixedDeltaTime is for FixedUpdate.
Ref: https://docs.unity3d.com/ScriptReference/MonoBehaviour.FixedUpdate.html
Ive been trying to make this Object move forward on its own and turn left or right in circular fashion if the left/right keys are pressed with unity using C#, this picture will make it clearer: http://prnt.sc/avmxbn
I was only able to make it move on its own and this is my code so far:
using UnityEngine;
using System.Collections;
public class PlayerBehaviour : MonoBehaviour {
Update(){ transform.localPosition += transform.forward *speed *Time.deltaTime
float speed = 5.0f;
// Use this for initialization
void Start () {
Debug.Log ("it's working?");
}
// Update is called once per frame
void Update () {
transform.localPosition += transform.forward * speed * Time.deltaTime;
}
void FixedUpdate(){
}
}
I have no idea, however, how to change left or right directions in circular paths like the picture linked demonstrates. Anyone able to help me? Thank you.
There are obvious errors in your code. You call Update() twice. The first time without a return type. You shouldn't do that. Start by deleting the first Update() and the code on the same line.
Then to answer your question you will have to look into getting input from the user. Use Input.GetKey() and pass it a KeyCode value such as KeyCode.Afor the 'A' key. So you can say:
if(Input.GetKey(KeyCode.A))
{
//do something(for example, Turn the player right.)
}
Then look into rotating the object using transform.Roate to rotate the player.
Attach this script to your moving object:
using UnityEngine;
public class MoveController : MonoBehaviour {
float angle = 1F;
float speed = 0.2F;
void Update ()
{
if ( Input.GetKey (KeyCode.LeftArrow) )
transform.Rotate(Vector3.up, -angle);
else if( Input.GetKey (KeyCode.RightArrow) )
transform.Rotate(Vector3.up, angle);
transform.Translate(Vector3.forward * speed);
}
}
The key point here is to separate your moving from your rotating functionality.
You can use this script for movement :
using UnityEngine;
public class MovementController : MonoBehaviour {
public Rigidbody rigidbody;
float angle = 0f;
const float SPEED = 1f;
float multiplier = 1f;
void FixedUpdate(){
if ( Input.GetKey (KeyCode.LeftArrow) )
angle -= Time.deltaTime * SPEED * multiplier;
else if( Input.GetKey (KeyCode.RightArrow) )
angle += Time.deltaTime * SPEED * multiplier;
rigidbody.velocity = new Vector2(Mathf.Sin(angle) * SPEED, Mathf.Cos(angle) * SPEED);
}
}
Multiplier value is inversely proportional to the radius.
Ive been trying to make this Object move forward on its own and turn left or right in circular fashion if the left/right keys are pressed with unity using C#, this picture will make it clearer: http://prnt.sc/avmxbn
I was only able to make it move on its own and this is my code so far:
using UnityEngine;
using System.Collections;
public class PlayerBehaviour : MonoBehaviour {
Update(){ transform.localPosition += transform.forward *speed *Time.deltaTime
float speed = 5.0f;
// Use this for initialization
void Start () {
Debug.Log ("it's working?");
}
// Update is called once per frame
void Update () {
transform.localPosition += transform.forward * speed * Time.deltaTime;
}
void FixedUpdate(){
}
}
I have no idea, however, how to change left or right directions in circular paths like the picture linked demonstrates. Anyone able to help me? Thank you.
There are obvious errors in your code. You call Update() twice. The first time without a return type. You shouldn't do that. Start by deleting the first Update() and the code on the same line.
Then to answer your question you will have to look into getting input from the user. Use Input.GetKey() and pass it a KeyCode value such as KeyCode.Afor the 'A' key. So you can say:
if(Input.GetKey(KeyCode.A))
{
//do something(for example, Turn the player right.)
}
Then look into rotating the object using transform.Roate to rotate the player.
Attach this script to your moving object:
using UnityEngine;
public class MoveController : MonoBehaviour {
float angle = 1F;
float speed = 0.2F;
void Update ()
{
if ( Input.GetKey (KeyCode.LeftArrow) )
transform.Rotate(Vector3.up, -angle);
else if( Input.GetKey (KeyCode.RightArrow) )
transform.Rotate(Vector3.up, angle);
transform.Translate(Vector3.forward * speed);
}
}
The key point here is to separate your moving from your rotating functionality.
You can use this script for movement :
using UnityEngine;
public class MovementController : MonoBehaviour {
public Rigidbody rigidbody;
float angle = 0f;
const float SPEED = 1f;
float multiplier = 1f;
void FixedUpdate(){
if ( Input.GetKey (KeyCode.LeftArrow) )
angle -= Time.deltaTime * SPEED * multiplier;
else if( Input.GetKey (KeyCode.RightArrow) )
angle += Time.deltaTime * SPEED * multiplier;
rigidbody.velocity = new Vector2(Mathf.Sin(angle) * SPEED, Mathf.Cos(angle) * SPEED);
}
}
Multiplier value is inversely proportional to the radius.
I have the following code for my 2D game, it makes object randomly wonder on the screen. What I am having issues with, is when an object looks at the point it is going to, I would like it to rotate as it moves forward. What is happening now, is it rotates instantly to the point it is going towards. So, how can I get it to rotate slowly and move forward at the same time?
using UnityEngine;
using System.Collections;
public class Wonder : MonoBehaviour {
protected Vector2 wayPoint;
protected float speed;
// Use this for initialization
void Start () {
speed = gameObject.GetComponent<Move>().playerSpeed;
wonder();
}
void wonder(){
wayPoint = Random.insideUnitCircle * 10;
}
// Update is called once per frame
void Update () {
Vector2 dir = wayPoint - new Vector2(transform.position.x, transform.position.y);
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(new Vector3(0, 0,Mathf.Atan2 (dir.y, dir.x) * Mathf.Rad2Deg - 90));
transform.position = Vector2.MoveTowards(transform.position, wayPoint, Time.deltaTime * speed);
float magnitude = (new Vector2(transform.position.x, transform.position.y) - wayPoint).magnitude;
if(magnitude < 3){
wonder();
}
}
}
Here is an example Image:
So, once the ship gets to its point another will be created and it will move there. I am thinking I will have to have a list of 5+ points, then calculate the arch the ship needs to take adding new points as the ship hits a way point then removing old ones after. I am not sure how to do this though...
using UnityEngine;
using System.Collections;
public class Wander : MonoBehaviour {
protected Vector3 velocity;
protected Vector2 waypoint;
protected float speed;
// Use this for initialization
void Start () {
speed = gameObject.GetComponent<Move>().playerSpeed;
RandomizeWaypoint();
}
void RandomizeWaypoint(){
waypoint = Random.insideUnitCircle * 10;
}
// Update is called once per frame
void Update () {
transform.position = Vector3.SmoothDamp( transform.position, waypoint, ref velocity, Time.deltaTime * speed );
transform.rotation = Quaternion.AngleAxis( Mathf.Atan2( velocity.y, velocity.x ) * Mathf.Rad2Deg, Vector3.forward );
if( Vector3.Distance( transform.position, waypoint ) < 3 ){
RandomizeWaypoint();
}
}
}
Untested. Vector3.SmoothDamp can be pretty handy. Note the spelling also.
So i have completed the Roll a ball tutorial from Unity that is a little game that uses a sphere with a rigidbody applied to it with some basic movement script found here.
What i want now is to take it a step further and introduce a somewhat more advanced movement script which also takes mouse input into play.
What i am trying to achieve is so to add force based on the local axis, so if i i move the mouse left the ball turns and the force is added in that direction. Let me show what code i have come up with (added to a simple sphere with rigidbody applied):
using UnityEngine;
using System.Collections;
public class playerController : MonoBehaviour {
public float turnSpeed = 2.0f;
public float moveSpeed = 250.0f;
void FixedUpdate() {
float h = turnSpeed * Input.GetAxis("Mouse X");
transform.Rotate(0, h, 0);
float moveHorizontal = Input.GetAxis("Horizontal");
float moveVertical = Input.GetAxis("Vertical");
Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);
rigidbody.AddForce(movement * moveSpeed * Time.deltaTime);
}
}
Ok so what is happening is that the ball is turning when i move the mouse, and the ball is rolling if i use the arrowkeys, but what i'm not managing to figure out after some trial and error is to get the ball moving in the direction it is turning.
How would you approach this particular scenario? Any help is as always much appreciated guys.
I managed to get around this and sharing for others to see.
I reference to the camera GameObject and use the camera.transform on the keys. Guess it is really basic but still.
public GameObject Camera;
public float moveSpeed = 0.0f;
if (Input.GetKey ("right") || Input.GetKey ("d")) {
rigidbody.AddForce( Camera.transform.right * moveSpeed * Time.deltaTime);
}
if (Input.GetKey ("left") || Input.GetKey ("a")) {
rigidbody.AddForce( -Camera.transform.right * moveSpeed * Time.deltaTime);
}
if (Input.GetKey ("up") || Input.GetKey ("w")) {
rigidbody.AddForce( Camera.transform.forward * moveSpeed * Time.deltaTime);
}
if (Input.GetKey ("down") || Input.GetKey ("s")) {
rigidbody.AddForce( -Camera.transform.forward * moveSpeed * Time.deltaTime);
}
Something Like this should do the trick::
if (Input.GetKey ("up") || Input.GetKey ("w")) {
rigidbody.AddForce( Camera.transform.forward * moveSpeed * Time.deltaTime);
rigidbody.AddRelativeTorque(vector3.right * speed)
//Note that rotation happens around the axis, so when moving (forward orback you will rotate on the vector3.right/left) and when moving( Right/left you will use the vector3.forward/back)
}