I'm making a 2D game with Unity. Recently, I've implemented a shooting system. I wanted to change bullets direction based on the player's facing but since the flipping code was changing the local scale based on velocity (.01 and -.01), the bullets were suspended in the air when the player was not moving but was shooting. I ended up using local scale and a bool variable but there are still some problems. Since this code was changing the local scale to 1, the player size was getting so bigger at the start of the game. I wanted the player to have a float type scale which is smaller and more suitable for my game, so I parented an empty object to the player and this solved the problem but now it shakes weirdly at the start of the game . This is a GIF that shows the shaking problem. I thought it is definitely due to the scale change but after removing that line of code, I could see it again. So it might have another reason but I don't know what is that. Also, the previous code was using Input.GetAxis
(which was helpful for supporting gamepad) but now I can't seem to find a way to use it again without getting errors because the code has been changed.
In general, my goal is fixing these problems:
- The player's shaking at the start of the game
- A way to use
Input.GetAxis
to support the left analog stick and D-pad like the past - A flipping code that flips the player and its children but does not cause any problems for the bullets direction and shooting system
Here's my player script.
using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
public class NewPlayer : PhysicsObject
{
[Header("Attributes")]
[SerializeField] private float jumpPower = 10;
[SerializeField] private float maxSpeed = 1;
[Header("References")]
[HideInInspector] public bool isFacingLeft;
//Singleton instantation
private static NewPlayer instance;
public static NewPlayer Instance
{
get
{
if (instance == null) instance = GameObject.FindObjectOfType<NewPlayer>();
return instance;
}
}
void Update()
{
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
rb2d.velocity = new Vector2(maxSpeed, rb2d.velocity.y);
GetComponent<SpriteRenderer>().flipX = true;
isFacingLeft = false;
}
else if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
rb2d.velocity = new Vector2(-maxSpeed, rb2d.velocity.y);
GetComponent<SpriteRenderer>().flipX = false;
isFacingLeft = true;
}
else if (grounded)
{
rb2d.velocity = new Vector2(0, rb2d.velocity.y);
}
if (Input.GetButtonDown("Jump") && grounded)
{
rb2d.velocity = new Vector2(rb2d.velocity.x, jumpPower);
}
}
}
This is from the old script where I used both velocity and local scale for flipping. (this and my current script inherit from another script called Physics Object which handles the physics and has a definition for target velocity.
void Update()
{
targetVelocity = new Vector2(Input.GetAxis("Horizontal") * maxSpeed, 0);
if (Input.GetButtonDown("Jump") && grounded)
{
velocity.y = jumpPower;
}
//Flip the player's localScale.x if the move speed is greater than .01 or less than -.01
if (targetVelocity.x < -.01)
{
transform.localScale = new Vector2(-1, 1);
}
else if (targetVelocity.x > .01)
{
transform.localScale = new Vector2(1, 1);
}
}
}
And this is the weapon script. Here, I used isFacingLeft
parameter to change the bullets direction.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Weapon : MonoBehaviour
{
public GameObject bullet;
public Transform firePoint;
private bool isShooting;
[SerializeField]
private float shootDelay = .5f;
private void Update()
{
if (Input.GetButtonDown("Fire1"))
{
isShooting = true;
GameObject b = Instantiate(bullet);
b.GetComponent<Bullet>().StartShoot(NewPlayer.Instance.isFacingLeft);
b.transform.position = firePoint.transform.position;
Invoke("ResetShoot", shootDelay);
}
void ResetShoot()
{
}
}
}