I have game when you are destroying boxes with ball witch you are bouncing with platform (standard 2d game). And I have power ups that are spawning and they are multiply number of balls and when ball touch a wall that is downstair its destroyed. I have program where is when number of balls is multyplyed it sets number of balls 1 but one thing doesn't work right.
SCRIPT ON BALL:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ball2 : MonoBehaviour
{
private Rigidbody2D rb;
public GameObject ball;
[SerializeField]
private int forceOne = 10;
[SerializeField]
private int forceTwo = 15;
private float balls;
public float numBalls = 1;
void Start()
{
rb = GetComponent<Rigidbody2D>();
rb.AddForce(new Vector2(forceOne * 25f, forceTwo * 25f));
balls = numBalls;
}
public void Copy()
{
Instantiate(ball, this.transform.position, Quaternion.identity);
balls ;
}
}
and I'm trying to connect this with my script on platform witch is:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class movement : MonoBehaviour
{
[SerializeField]
private float speed = 10f;
public int startBoxes = 120;
private int boxes;
private string MUL_TAG = "mul";
private float movementX;
private void Start()
{
boxes = startBoxes;
}
private void Update()
{
Movement();
}
public void Destroy()
{
boxes--;
if (boxes <= 0)
endGame();
}
private void endGame()
{
SceneManager.LoadScene("level_");
}
private void Movement()
{
movementX = Input.GetAxisRaw("Horizontal");
transform.position = new Vector3 (movementX, 0f, 0f) * Time.deltaTime * speed;
}
private void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag(MUL_TAG))
{
ball2 PBDM = FindObjectOfType<ball2>();
PBDM.Copy();
}
}
public void balls()
{
if (balls <= 0)
SceneManager.LoadScene("loseScreen");
}
}
but on this last part on balls function its an error: Operator '<=' cannot be applied to operands of type 'method group' and 'int'. I tryed to change int into float but it doesn't work. So my point is when all balls are destroyed you lose.
P.S I want to know if this: ball2 PBDM = FindObjectOfType(); is PBDM you can changes it or its actualy a think? For example:
ball2 TEXT = FindObjectOfType(); TEXT.Copy();
CodePudding user response:
There is no variable balls
declared anywhere in the movement
class. What, then, is it trying to compare with <=
? Well, the only thing that you've declared with that name is a method called balls
. Methods are not numbers, they are methods.
CodePudding user response:
The variable balls
is only defined as a private variable within the 'ball2' class. This is not accessible to anything except for that instance of the 'ball2' class. As a side note, if you run 'Copy()' on the ball, each new ball will get a separate instance of the 'balls' variable. They won't be the same value. You could create a game manager prefab, and make that copy and keep track of the balls instead. This is probably the better and more standard way to solve this issue. There are guides on Singletons and Game manager prefabs like this one, but here's an example:
public class GameManager : MonoBehaviour
{
private static _instance = null;
public static GameManager Instance
{
get
{
if (_instance == null)
{
_instance = this;
}
else
{
Destroy(gameObject);
}
return _instance;
}
}
private int _balls;
public int Balls
{
get => _balls;
set
{
int oldValue = _balls;
_balls = value;
OnBallsChanged(oldValue);
}
}
private void OnBallsChanged (int oldValue)
{
if (Balls <= 0)
{
SceneManager.LoadScene("loseScreen");
}
}
}
A simpler but, in my opinion, less elegant and less maintainable solution could be to make the 'balls' variable public and static. Then you'd get the 'balls' variable through 'ball2.balls' like so:
public class ball2 : MonoBehaviour
{
private Rigidbody2D rb;
public GameObject ball;
[SerializeField]
private int forceOne = 10;
[SerializeField]
private int forceTwo = 15;
public static float balls;
public float numBalls = 1;
... in the movement class
public void balls()
{
if (ball2.balls <= 0)
SceneManager.LoadScene("loseScreen");
}