So when I instantiated invaders it worked when i did 2 of them, but as soon as i tried to instantiate more than 2 (created a variable float addInvaders, and an if statement if addInvader is equal to 5) my game literally just crashes. It runs for a second, and I see it create like a million invaders then it Unity doesn't respond anymore. Wondering what I'm doing wrong, and what I can do to fix. I think this is all the code you need, please let me know I'll add additional code if need be.
//globals
float addInvader = 0f;
bool spawnInvader = true;
public GameObject invaders;
void Update()
{
SpawnInvaders ();
while (addInvader == 5f)
{
spawnInvader = false;
}
}
void SpawnInvaders()
{
if (spawnInvader)
{
Vector3 newPos = transform.position;
Quaternion roto = transform.rotation;
newPos.x = 900f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
if (addInvader >= 1f)
{
newPos.x = newPos.x - 200f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
}
}
return;
}
I don't have enough reputation to comment so I'll try to answer instead.
It appears you created an infinite loop :
while (addInvader == 5f)
{
spawnInvader = false;
}
Change it to :
if (addInvader >= 5f)
{
spawnInvader = false;
}
It should stop crashing.
Related
I'm making a ladder for my Unity game. Nothing much happens when you hover over it (that's normal). I want to freeze gravity by setting gravityscale 0 whenever the up arrow key is pressed (or w). Thankfully that works. Unfortunately though whenever I go down, gravity is still 0 but somehow my character falls back to the ground.
Here's my player code. Sorry the formatting is very bad; I just deleted the things that didn't have to do with ladders so you won't read irrelevant details.
// ladder
public float climb;
public float climbspeed;
public float gravitystore;
public bool laddered;
public GameObject laddercheck;
public float upaxis;
public xpositionladdercheck ladderx;
// Start is called before the first frame update
void Start()
{
ladderx = FindObjectOfType<xpositionladdercheck>();
jumptimecounter = Jumptime;
jumpscriptbetter = FindObjectOfType<BetterJump>();
gameover = false;
respawnscreen = FindObjectOfType<RespawnIntermission>();
lives = 5;
atkindex = FindObjectOfType<attackindex>();
scale =transform.localScale;
basicattackscript = FindObjectOfType<BasicAttack>();
basicattacksupply = 0;
rb = GetComponent<Rigidbody2D>();
gravitystore = rb.gravityScale;
}
// Update is called once per frame
private void Update()
{
horimove = Input.GetAxis("Horizontal");
if (isDead == false)
{
upaxis = Input.GetAxis("Vertical");
anim.SetFloat("run", Mathf.Abs(horimove));
if (Input.GetKeyDown(KeyCode.Space) && laddered)
{
jumpladder();
}
anim.SetFloat("run", Mathf.Abs(horimove));
if (laddered && Mathf.Abs(upaxis) > .01)
{
rb.gravityScale = 0;
climbm();
} else if (!laddered)
{
rb.gravityScale = gravitystore;
}
if (laddered&&Input.GetKeyDown(KeyCode.Space))
{
StartCoroutine("jumpable");
}
rb.velocity = new Vector2(speed * horimove * Time.fixedDeltaTime, rb.velocity.y);
if (Input.GetKey(KeyCode.Space) && OnGround)
{
jump();
}
}
}
IEnumerator jumpable()
{
laddercheck.SetActive(false);
yield return new WaitForSeconds(.8f);
laddercheck.SetActive(true);
}
void climbm()
{
if (laddered)
{
if (upaxis > .1f) {
} else if (!laddered)
{
rb.constraints = RigidbodyConstraints2D.FreezeRotation;
}
rb.velocity = Vector2.up * climbspeed * upaxis *Time.deltaTime;
transform.position = new Vector2(ladderx.ladderxpos, rb.position.y);
// the ladder.x things is just a script that gets the x position of the ladder but it works well so ignore that.
}
}
public void jump()
{
}public void jumpladder()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector2.up * jumpforce * Time.fixedDeltaTime);
}
}
}
}
I set mass to the lowest (.0001) and still the same thing happens. I didn't include the ladderx position script or the sensing that I'm even on a ladder script but that's irrelevant to the question. It senses everything just fine and the xposition script works well as well.
I figured it out. For some reason I had to set the Physics2D.gravity to new Vector2 (0,0); whenever I climb the ladder. Then I made a vector 2 physgravity variable that stores the natural gravity and set it back to that whenever I leave the ladder.
public Vector2 physgravity;
physgravity = Physics2D.gravity;
Physics2D.gravity = new Vector2(0f, -9.81f);
private void Update()
{
if (!laddered)
{
Physics2D.gravity = new Vector2(0f, -9.81f);
}
____________________ (later on in the script)
if (laddered && Mathf.Abs(upaxis) > .01)
{
rb.gravityScale = 0;
Physics2D.gravity = new Vector2(0, 0);
rb.velocity = new Vector2(0, 0);
climbm();
I am creating a clone of Billiards and I cannot work out how to stop the player from interacting with and launching the ball while it is still moving; below is my attempt. I have placed an if statement that checks whether the ball is moving on both the mouseDrag and mouseUp functions. I have also tried using isSleeping() but this caused the ball to not move at all.
If possible I would like to apply this method to all of the balls and not just the cue ball; so that all balls have to have stopped before any actions may happen. This is currently in my "player" script, if I should move it a GameManager script please let me know.
private void Update()
{
speed = rb.velocity.magnitude;
if (speed < 0.5)
{
rb.velocity = new Vector3(0, 0, 0);
}
}
void OnMouseDrag()
{
if (speed == 0)
{
mousePointB.GetComponent<SpriteRenderer>().enabled = true;
currDistance = Vector3.Distance(mousePointA.transform.position, transform.position);
if (currDistance <= 3f)
{
spaceLimit = currDistance;
}
else
{
spaceLimit = maxDistance;
}
shootPower = Mathf.Abs(spaceLimit) * shootPowervar;
Vector3 dimxy = mousePointA.transform.position - transform.position;
float difference = dimxy.magnitude;
mousePointB.transform.position = transform.position + ((dimxy / difference) * currDistance * -1);
mousePointB.transform.position = new Vector3(mousePointB.transform.position.x, mousePointB.transform.position.y, -0.8f);
shootDirection = Vector3.Normalize(mousePointA.transform.position - transform.position);
}
else
{
}
}
void OnMouseUp()
{
if (speed == 0)
{
mousePointB.GetComponent<SpriteRenderer>().enabled = false;
arrow.GetComponent<SpriteRenderer>().enabled = false;
circle.GetComponent<SpriteRenderer>().enabled = false;
Vector3 push = shootDirection * shootPower * -1;
GetComponent<Rigidbody2D>().AddForce(push, ForceMode2D.Impulse);
}
else
{
}
}
if your test speed == 0 is not functional, you could record the last position of the ball, and set a boolean isMoving = true, if actual position of ball is different thant the last, then record the lastposition and so on
Vector3 LastPosition;
bool isMoving;
void Update()
{
isMoving = BallPosition == LastPosition;
:
:
}
void OnMOuseDrag()
{
if(!isMoving) return;
}
void OnMOuseUp()
{
if(!isMoving) return;
}
I'm trying to create a 2D platform game in unity, when I try and make the character double jump, it won't work. I was wondering if i could get any help.
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
public float maxSpeed = 3;
public float speed = 50f;
public float jumpPower = 150f;
public bool grounded;
public bool canDoubleJump;
private Rigidbody2D rb2d;
private Animator anim;
void Start ()
{
rb2d = gameObject.GetComponent<Rigidbody2D>();
anim = gameObject.GetComponent<Animator>();
}
void Update ()
{
anim.SetBool("Grounded", grounded);
anim.SetFloat("Speed", Mathf.Abs(rb2d.velocity.x));
if(Input.GetAxis("Horizontal") < -0.1f)
{
transform.localScale = new Vector3(-1, 1, 1);
}
if(Input.GetAxis("Horizontal") > 0.1f)
{
transform.localScale = new Vector3(1, 1, 1);
}
if(Input.GetButton("Jump"))
{
if(grounded)
{
rb2d.AddForce(Vector2.up * jumpPower);
canDoubleJump = true;
}
else
{
if (canDoubleJump)
{
canDoubleJump = false;
rb2d.velocity = new Vector2(rb2d.velocity.x, 0);
rb2d.AddForce(Vector2.up * jumpPower);
}
}
}
}
void FixedUpdate()
{
Vector3 easeVelocity = rb2d.velocity;
easeVelocity.y = rb2d.velocity.y;
easeVelocity.z = 0.0f;
easeVelocity.x *= 0.75f;
float h = Input.GetAxis("Horizontal");
//fake friction / easing x speed
if(grounded)
{
rb2d.velocity = easeVelocity;
}
//moving player
rb2d.AddForce((Vector2.right * speed) * h);
//limiting speed
if(rb2d.velocity.x > maxSpeed)
{
rb2d.velocity = new Vector2(maxSpeed, rb2d.velocity.y);
}
if(rb2d.velocity.x < -maxSpeed)
{
rb2d.velocity = new Vector2(-maxSpeed, rb2d.velocity.y);
}
}
}
The problem is that you're checking if the Jump button is currently in the down state. Pressing and releasing the button often takes place over multiple frames (i.e. Update() is called many times in the duration of button press).
There are two ways you can fix this problem.
The easiest (and probably best) is to make this alteration:
if(Input.GetButtonDown("Jump"))
GetButtonDown only returns true for the frame in which the button was first pressed, and false until it is released and pressed again.
The other is to include a second variable that prevents the activation of the second block until after the button is released. This is less ideal, but shows what's going on behind the scenes of GetButtonDown.
var isButtonDown = false;
Update() {
if(Input.GetButton("Jump"))
{
if(grounded)
{
rb2d.AddForce(Vector2.up * jumpPower);
canDoubleJump = true;
isButtonDown = true;
}
else if(!isButtonDown)
{
if (canDoubleJump)
{
canDoubleJump = false;
rb2d.velocity = new Vector2(rb2d.velocity.x, 0);
rb2d.AddForce(Vector2.up * jumpPower);
}
}
}
else {
isButtonDown = false;
}
}
Note that this does not address the "fall off a platform and jump once" that the double-jump ability typically includes. I'll leave that as an exercise to the reader.
I'm working on a project where I'm trying to make my character move by jumping at an angle. Right now during the frame updates, the character will pivot back and forth and when the right key is pressed, they will jump. This code causes them to jump at an angle, but they always return to their original position.
Additionally, I have two characters who start on opposite sides of the stage, but when I start the game they teleport to the same position. I've spent a lot of time reviewing my code but I can't seem to get this to work. Any help you can provide?
using UnityEngine;
using System.Collections;
public class Freg : MonoBehaviour {
public GameObject Tounge;
public float gravity;
public float tempScale = 1;
public float MaxJump = 8f;
public float MinJump = 0.1f;
static float yVector = 0;
static float xVector = 0;
static bool grounded = true;
bool isleft = false;
Vector3 farthestleft;
Vector3 farthestright;
// Use this for initialization
void Start () {
farthestleft = new Vector3 (-33.7f, 50.2f, 24.8f);
farthestright = new Vector3 (22.56f, 54.83f, -15.12f);
}
void OnTriggerEnter (Collider other) {
if (other.GetComponent<Collider> ().tag == "Ground") {
grounded = true;
yVector = 0;
//xVector = 0;
Vector3 onGround = new Vector3 (transform.position.x, -4.86f, transform.position.z);
transform.position = onGround;
} else
grounded = false;
}
// Update is called once per frame
void Update () {
/*if (Input.GetKey (KeyCode.UpArrow) == true) {
Tounge.transform.localScale.Set (1, 0.5f, 1);
} else {
Tounge.transform.localScale.Set (1, 1, 1);
}*/
if (grounded == false) {
yVector -= gravity;
}
if (Input.GetKeyDown (KeyCode.UpArrow) == true && grounded == true) {
MinJump += 0.5f;
} else if (MinJump > 0.1f){
yVector += MinJump;
xVector += MinJump;
MinJump = 0.1f;
grounded = false;
}
Vector3 stuff = new Vector3 (transform.localPosition.y + xVector, transform.position.y + yVector, transform.position.z);
transform.position = stuff;
float t = Mathf.PingPong (Time.time * 0.5f * 2.0f, 1.0f);
transform.eulerAngles = Vector3.Lerp (farthestright, farthestleft, t);
}
}
it looks like you should update the current position during the if statements, rather than after that way on each update, the actual position is moving based on the decision rather than just the end of the loop.
The weirdest thing keeps happening and I can not figure out why. Instead of just setting up like 20 different prefabs, I wanted to instatiate them in my code. I am making a Space Invaders C# game and I got the first row of invaders to spawn fine using the code found below. Literally no issues at all, and they move how I want them too as well. But as soon as I set up my second row the transform.position syntax that I used for the first row, suddenly does not apply and it just sets my transform.position.x to 0. I do have another class that MIGHT be the reason, but so far I have not found any solution to this problem. Thanks for help in advance.
//GameController Class
//
//globals
//
Quaternion roto;
public Vector3 newPos;
public float addInvader
bool spawnInvader = true;
public GameObject invaders;
//
void Update()
{
newPos = transform.position;
roto = transform.rotation;
newPos2 = transform.position;
roto2 = transform.rotation;
if (addInvader <= 0f)
{
SpawnInvaders ();
}
if (addInvader > 0f)
{
SpawnInvaders ();
}
if (addInvader > 5f)
{
spawnInvader = false;
}
if (add2Invader <= 0f)
{
//invaderSrow();
}
if (add2Invader > 0f)
{
//invaderSrow();
secondrow = false;
}
}
void SpawnInvaders()
{
if (spawnInvader)
{
if (addInvader < 1f)
{
newPos.x = 900f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 1f)
{
newPos.x = 700f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 2f)
{
newPos.x = 500f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 3f)
{
newPos.x = 300f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 4f)
{
newPos.x = 100f;
newPos.y = 0f;
newPos.z = 800f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
if (addInvader == 5f)
{
newPos.x = -600f;
//newPos2.x = newPos2.x - 200f;
newPos.y = 0f;
newPos.z = 500f;
roto.z = 180f;
Instantiate (invaders, newPos, roto);
addInvader++;
}
}
return;
}
void invaderSrow()
{
InvaderController F = new InvaderController();
//F.newX = newPos2.x;
if (secondrow)
{
if (add2Invader < 1f)
{
newPos.x = -800f;
newPos.y = 0f;
newPos.z = 500f;
roto.z = 180f;
//Instantiate (invaders2, newPos, roto);
add2Invader++; //add2Invader should be 1 now....
//secondrow = false;
}
if (add2Invader == 1f)
{
newPos2 = transform.position;
newPos2.x = -800f + 200f;
//F.newX = -800f;
//F.newX = newPos2.x + 200f;
newPos2.y = 0f;
newPos2.z = 500f;
roto2.z = 180f;
//Instantiate (invaders3, newPos2, roto2);
add2Invader++;
}
}
return;
}
//InvaderController class
//
//globals
//
public float newX;
public float invaderSpeed;
public float resistance;
public GameObject Invader;
public GameObject explosion;
Quaternion rotation;
//
void Awake()
{
firstxoff = true;
}
// Update is called once per frame
void Update ()
{
if (firstxoff == true)
{
firstmove ();
}
moveX1 ();
}
void firstmove()
{
Vector3 newPos = transform.position;
newPos.x -= invaderSpeed;
transform.position = newPos;
if (newPos.x < -900f) //moves z
{
Vector3 newPosZ = transform.position;
newPosZ.z -= invaderSpeed;
float x = -900f;
newX = x;
newPosZ.x = newX;
transform.position = newPosZ;
}
}
void moveX1()
{
Vector3 newPos = transform.position;
if (newPos.z <= 500f)
{
Vector3 newPosX = transform.position;
newX = newX + invaderSpeed;
float z = 500f;
newZ = z;
newPosX.z = newZ;
newPosX.x = newX;
transform.position = newPosX;
if (newPosX.x > -900f)
{
newX = newX + (invaderSpeed + 7f);
firstxoff = false;
}
}
}
in moveX1() you are using newX , is it possible you are sometimes calling moveX1 before firstMove ? if so then newX would be undefined and 0.
Figured it out. Added a newX = newPosX.x; line at the start of my moveX1() function :D thanks everyone who tried!