Hello everybody so my program is quite a simple one,what i'm trying to do is do have to objects and destroy one of them by pressing either H for hero or E for enemy damage is random but i made it very close so they go down quickly , non the less i can't seem to figure it out after hours of trying and googling please help, because it's still not working :(
So the first script is placed in the both objects i have a cube named Hero with a Tag named Hero as well,and the second object is a sphere with the name Enemy and with the same name of the Tag.
This is the script they both own :
public class Character : MonoBehaviour
{
public float HP = 100;
public float minDmg = 23f;
public float maxDmg = 25f;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public float DamageDealt()
{
float damage;
damage = Random.Range(minDmg, maxDmg);
return damage;
}
}
And the second script is placed onto the camera which should be fine i think ?
public class FightControl : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
GameObject _hero = GameObject.Find("Hero");
GameObject _villain = GameObject.Find("Enemy");
//object se pravi da bi moglo da se preuzme var iz Character u obkejtu _hero
Character chscript = _hero.GetComponent<Character>();
//object se pravi da bi moglo da se utice na hp u objectu _villain
Character chscripta = _villain.GetComponent<Character>();
if (Input.GetKeyDown(KeyCode.H))
{
float dmg = chscript.DamageDealt();
chscripta.HP = chscript.HP - dmg;
if (chscripta.HP <= 0)
{
Destroy(_villain);
}
}
if (Input.GetKeyDown(KeyCode.E))
{
Character chscript1 = _villain.GetComponent<Character>();
float dmg1 = chscript1.DamageDealt();
Character chscript1a = _hero.GetComponent<Character>();
chscript1a.HP -= dmg1;
if(chscript1a.HP <= 0)
{
Destroy(_villain);
}
}
}
// Update is called once per frame
void Update()
{
}
}
Your second script is not working because you are running everything only once.
The Start() method runs only once once the game object has been enabled. You are reading input during the start method, but not during any other frames.
Consider moving some of your code to the Update() method so that you are reading the input every frame:
void Update()
{
if (Input.GetKeyDown(KeyCode.H))
{
float dmg = chscript.DamageDealt();
chscripta.HP = chscript.HP - dmg;
if (chscripta.HP <= 0)
{
Destroy(_villain);
}
}
if (Input.GetKeyDown(KeyCode.E))
{
Character chscript1 = _villain.GetComponent<Character>();
float dmg1 = chscript1.DamageDealt();
Character chscript1a = _hero.GetComponent<Character>();
chscript1a.HP -= dmg1;
if(chscript1a.HP <= 0)
{
Destroy(_villain);
}
}
}
Rather than finding the game object during runtime, you could consider creating a reference and configuring the hero/villain references by dragging the gameobject to the inspector after making this change to your code. You can do this for both Components and GameObjects, so with the following code you should have 4 "slots" in your inspector:
public class FightControl : MonoBehaviour
{
public GameObject _hero;
public GameObject _villain;
public Character chscript;
public Character chscripta;
//... the rest of your code (the Update() method above)
Related
The first script (JumpFromMicrophone) I have created is a script where based on my MICROPHONE audio input, the game object (player) moves up on the Y axis. The game object also automatically moves forward using speed on the Z axis.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class JumpFromMicrophone : MonoBehaviour
{
public AudioSource source;
public AudioLoudnessDetection detector;
public Vector3 minPosition;
public Vector3 maxPosition;
public float speed = 2;
public float loudnessSensibility = 100;
public float threshold = 0.1f;
// The duration of the smooth transition
public float smoothTime = 0.1f;
private Vector3 velocity = Vector3.zero;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
float loudness = detector.GetLoudnessFromMicrophone() * loudnessSensibility;
if (loudness < threshold)
loudness = 0;
else
loudness = (loudness - threshold) / (1 - threshold);
// Calculate the target position, keeping the current X and Z values
Vector3 targetPosition = Vector3.Lerp(minPosition, maxPosition, loudness);
targetPosition.x = transform.localPosition.x;
targetPosition.z = transform.localPosition.z;
// Smoothly move the object towards the target position
transform.localPosition = Vector3.SmoothDamp(transform.localPosition, targetPosition, ref velocity, smoothTime);
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
// reloads the scene if obstacle hits player
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Obstacle")
{
SceneManager.LoadScene("Game");
}
}
}
The second script (RNP) created records this audio picked up by the MICROPHONE and then plays it back to the player using a recording from a generated AudioSource. This is done using MaxRecordingTime, which I am fine using as I am going to relate it to timed game audio once this issue has been resolved.
public class RNP : MonoBehaviour
{
// The AudioClip that will be recorded
public AudioClip recordedClip;
// The maximum recording time in seconds
public int maxRecordingTime = 10;
void Start()
{
// Start the recording and playback coroutine
StartCoroutine(RecordAndPlayback());
}
IEnumerator RecordAndPlayback()
{
// Start recording from the default microphone
recordedClip = Microphone.Start(null, true, maxRecordingTime, 44100);
// Wait for the specified number of seconds
yield return new WaitForSeconds(maxRecordingTime);
// Stop the recording
Microphone.End(null);
// Create an AudioSource to play the recorded audio
AudioSource audioSource = gameObject.AddComponent<AudioSource>();
audioSource.clip = recordedClip;
audioSource.loop = false;
audioSource.Play();
// Wait for the audio to finish playing
yield return new WaitWhile(() => audioSource.isPlaying);
// Destroy the AudioSource
Destroy(audioSource);
}
}
However, the second script seems to clash with the first and implementing the second script does not allow for some aspects of the first script to work, I am beginning to think it might be something to do with the use of the Microphone for both scripts clashing, but I have no idea how to solve this issue so that both work together without disabling one another.
The JumpOnMicrophone script does not allow the player to move up the Y axis when the RNP script is added as a compenent onto the game object (player), but the player still moves along the Z axis.
Some fixes I have attemped that did not work:
Placing the 2nd script on another GameObject rather than the player
Combining both scripts
If anyone could help me figure this out, it would be greatly appreciated.
*** EDIT ***
AudioLoudnessDetection script
public class AudioLoudnessDetection : MonoBehaviour
{
public int sampleWindow = 64;
private AudioClip microphoneClip;
// Start is called before the first frame update
void Start()
{
MicrophoneToAudioClip();
}
// Update is called once per frame
void FixedUpdate()
{
}
public void MicrophoneToAudioClip()
{
string microphoneName = Microphone.devices[0];
microphoneClip = Microphone.Start(microphoneName, true, 20, AudioSettings.outputSampleRate);
}
public float GetLoudnessFromMicrophone()
{
return GetLoudnessFromAudioClip(Microphone.GetPosition(Microphone.devices[0]), microphoneClip);
}
public float GetLoudnessFromAudioClip(int clipPosition,AudioClip clip)
{
int startPosition = clipPosition - sampleWindow;
if (startPosition < 0)
return 0;
float[] waveData = new float[sampleWindow];
clip.GetData(waveData, startPosition);
// compute loudness
float totalLoudness = 0;
for (int i = 0; i < sampleWindow; i++)
{
totalLoudness += Mathf.Abs(waveData[i]);
}
return totalLoudness/ sampleWindow;
}
}
Alright, so here's what's happening: When I hit play and left click to shoot, unity editor freezes and I have to do the old Ctrl + Alt + Del, now, I am almost certain this script is the source of the issue, because when a bullet is shot, this script is immediately added to it, so here's the script(It's called BulletLife.cs, just letting you know)
using System.Timers;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using UnityEngine;
public class BulletLife : MonoBehaviour
{
public GameObject bullet;
public double bulletLifeSpan = 3;
bool bulletLifeEnded;
public LayerMask targetMask;
bool hasHitTarget;
// Start is called before the first frame update
void Start()
{
var bulletAge = new System.Timers.Timer(bulletLifeSpan * 1000);
bulletAge.Elapsed += OnTimedEvent;
bulletAge.AutoReset = false;
while(hasHitTarget == false && bulletLifeEnded == false) {
hasHitTarget = Physics.CheckSphere(bullet.transform.position, bullet.transform.localScale.y, targetMask);
}
Destroy(bullet);
Debug.Log("Finish");
}
private void OnTimedEvent(System.Object Source, ElapsedEventArgs e) {
bulletLifeEnded = true;
}
}
Also, here's the Shoot.cs script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Shoot : MonoBehaviour
{
public Transform gun;
public GameObject bullet;
public LayerMask targetMask;
public float bulletSpeed = 1000f;
bool hasHitTarget = false;
// Update is called once per frame
void Update()
{
if(Input.GetButtonDown("LeftClick")) {
GameObject bulletInstance;
bulletInstance = Instantiate(bullet, gun.position, new Quaternion(gun.rotation.w, gun.rotation.x, gun.forward.y, gun.rotation.z));
bulletInstance.AddComponent<Rigidbody>();
bulletInstance.GetComponent<Rigidbody>().useGravity = false;
bulletInstance.GetComponent<Rigidbody>().AddForce(gun.up * bulletSpeed);
bulletInstance.AddComponent<BulletLife>();
bulletInstance.GetComponent<BulletLife>().bullet = bulletInstance;
}
}
}
NOTE: I am using Unity 2019.4.15f1
Well everytime you instantiate a bullet in Start you do
while(hasHitTarget == false && bulletLifeEnded == false)
{
hasHitTarget = Physics.CheckSphere(bullet.transform.position, bullet.transform.localScale.y, targetMask);
}
this loop will never finish since none of the conditions is changed inside the loop. There either is a hit or not .. but then the parameters for the raycast are never changed, the position isn't updated since you are still in the same frame => endless loop => freeze the main thread completely.
What you rather wanted to do is move that thing to Update which is called once a frame like e.g.
//public GameObject bullet; // not needed
public double bulletLifeSpan = 3;
//bool bulletLifeEnded; // not needed
public LayerMask targetMask;
//bool hasHitTarget; // not needed
void Start()
{
var bulletAge = new System.Timers.Timer(bulletLifeSpan * 1000);
bulletAge.Elapsed += OnTimedEvent;
bulletAge.AutoReset = false;
}
private void Update()
{
if(Physics.CheckSphere(transform.position, transform.localScale.y, targetMask))
{
Destroy(gameObject);
Debug.Log("Finish");
}
}
private void OnTimedEvent(System.Object Source, ElapsedEventArgs e)
{
Destroy(gameObject);
Debug.Log("Finish");
}
Or make it a single Coroutine
// If Start returns IEnumerator it is automatically started as Coroutine
// So no need to start an extra routine
private IEnumerator Start()
{
// Keeps track of how long your bullet exists already
var bulletAge = 0f;
while(bulletAge < bulletLifeSpan && !Physics.CheckSphere(transform.position, transform.localScale.y, targetMask))
{
// Increase by the time passed since last frame
bulletAge += Time.deltaTime;
// "Pause" this routine, render this frame
// and continue from here in the next frame
yield return null;
}
Destroy(gameObject);
Debug.Log("Finish");
}
Btw note that in Shoot you can shorten this a lot
void Update()
{
if(Input.GetButtonDown("LeftClick"))
{
// Note that your quaternion made no sense -> simply pass in the gun.rotation
var bulletInstance = Instantiate(bullet, gun.position, gun.rotation);
var rb = bulletInstance.AddComponent<Rigidbody>();
rb.useGravity = false;
rb.AddForce(gun.up * bulletSpeed);
var life = bulletInstance.AddComponent<BulletLife>();
// Assigning the gameObject reference is completely unnecessary
// within BulletLife simply use "gameObject" as show before
}
}
You could shorten this even more by making sure these components already exist on your prefab object and are configured correctly. Then you wouldn't need any of these line but just Instantiate it.
And finally you shouldn't use thisCheckSphere at all but rather let Unity handle its Collision detection itself and use OnCollisionEnter and configure your Collision Layers according to your needs!
The issue with your solution is: If your bullet moves fast it might simply pass a target without your CheckSphere noting it namely if its velocity is higher then localScale.y * 2.
Your Start method is blocking, thus freezing your game.
You'll have to use Update or a Coroutine to make your hit tests.
public class BulletLife : MonoBehaviour
{
public GameObject bullet;
public double bulletLifeSpan = 3;
bool bulletLifeEnded;
public LayerMask targetMask;
bool hasHitTarget;
// Start is called before the first frame update
void Start()
{
StartCoroutine(CheckHit(0, bulletLifeSpan));
}
private IEnumerator CheckHit(float interval, float lifetime){
bool checkEveryFrame = interval <= 0;
WaitForSeconds wait = checkEveryFrame ? null : new WaitForSeconds(interval);
while(lifetime > 0){
yield return wait;
lifetime = lifetime - (checkEveryFrame ? Time.deltaTime : interval);
hasHitTarget = Physics.CheckSphere(bullet.transform.position, bullet.transform.localScale.y, targetMask);
}
bulletLifeEnded = true;
Destroy(bullet);
Debug.Log("Finish");
}
}
I am building a little platformer, where the player can collect coins. Since there are sometimes 100+ spinning coins in one scene, I decided to render only coins that are in within a certain proximity to the player.
This worked before - but on a phone the levels with many coins tend to have some lags. With the coins the removed, my FPS was at straight 60. So this is what I did:
public class AddCoinScript : MonoBehaviour
{
public static int coinCounter = 0; // static cause we will only want ONE counter and not many instances of the coin value
private Text coinText;
private float disBetweenBirdyAndEnemy;
private GameObject birdy;
private Renderer rndr;
private BoxCollider2D bx2D;
private bool canAnimate = false;
private float startAnimDistance = 20;
private bool coinCollected = false;
void Start()
{
coinText = GameObject.Find("Coin Text").GetComponent<Text>(); // Get the Coin Text Element
coinText.text = "x" + coinCounter.ToString();
birdy = GameObject.Find("Birdy");
rndr = GetComponent<Renderer>();
bx2D = GetComponent<BoxCollider2D>();
rndr.enabled = true;
bx2D.enabled = true;
}
void FixedUpdate()
{
disBetweenBirdyAndEnemy = Vector3.Distance(birdy.transform.position, this.transform.position);
if (disBetweenBirdyAndEnemy <= startAnimDistance)
{
if(!coinCollected)
{
rndr.enabled = true;
bx2D.enabled = true;
}
}
else
{
rndr.enabled = false;
bx2D.enabled = false;
}
coinText.text = "x" + coinCounter.ToString();
}
void OnTriggerEnter2D(Collider2D col)
{
if (col.gameObject.name == "Birdy") // detect collision with ground game object
{
AddCoinAndRemoveHitBoxAndSprite();
}
}
private void AddCoinAndRemoveHitBoxAndSprite()
{
coinCounter++;
coinCollected = true;
rndr.enabled = false;
bx2D.enabled = false;
PlayCoinSound();
}
private void PlayCoinSound()
{
AudioSource aS = GameObject.Find("GetCoinSound").GetComponent<AudioSource>();
aS.Play();
}
}
The results are good. The coins render in the scene only when the player is close enough to them. However, once deployed onto my phone - the coins don't render at all any more. As if the players distance towards the coins is different on my phone than it is on my pc.
What am I missing?
I can't see anything obviously wrong with this, but if it is a distance check gone wrong, you could try disabling the entire coin and enable them only if they're on the screen.
A solution which would work with all resolutions is something along the lines of this:
private bool IsOnScreen(Vector3 worldPosition)
{
Vector3 screenPoint = camera.WorldToViewportPoint(worldPosition);
return screenPoint.x > 0
&& screenPoint.x < 1
&& screenPoint.y > 0
&& screenPoint.y < 1;
}
A separate problem that could be solved is that your coin script is responsible for far too many things. Right now every coin
Knows how many coins the player has and can modify that number
Knows about and is modifying the UI text for coins on start
Is responsible for enabling/disabling its own components, when you could just destroy the gameObject when it's collected
Finds an audio gameObject and playing a sound
Because of all these responsibilities you'll have a harder time solving issues within this class. Consider having some sort of CoinManager class which can keep track of how many coins the player has (instead of every single coin knowing about the coin count).
Your class might look something like this
public class CoinManager : MonoBehaviour
{
private Camera camera;
[SerializeField] private AudioClip coinCollectedSound;
[SerializeField] private AudioSource audioSource;
[SerializeField] private List<CoinScript> coins;
[SerializeField] private int coinCount;
[SerializeField] private Text coinLabel;
// This could be called by some spawner class that
// adds coins to the scene
public void AddCoin(CoinScript coin)
{
coins.Add(coin);
}
public void CoinCollected(CoinScript coin)
{
Destroy(coin.gameObject);
coinCount++;
audioSource.PlayOneShot(coinCollectedSound);
// Alternatively, if you have a dedicated audio source
// for coin sounds you can just use audioSource.Play();
}
private void Update()
{
// Iterate over all the coins we know about
foreach (var coin in coins)
{
// Now that we have a method that tells us whether a
// coin is on the screen or not, we can enable and disable
// all the coins at the same time in one place
coin.transform.enabled = IsOnScreen(coin.transform.position);
}
}
private void Awake()
{
// Gets the main camera in the scene
// https://docs.unity3d.com/ScriptReference/Camera-main.html
camera = Camera.main;
coins = new List<CoinScript>();
}
private bool IsOnScreen(Vector3 worldPosition)
{
Vector3 screenPoint = camera.WorldToViewportPoint(worldPosition);
return screenPoint.x > 0
&& screenPoint.x < 1
&& screenPoint.y > 0
&& screenPoint.y < 1;
}
}
I don't have Unity in front of me so the above is off the top of my head.
I am trying to spawn some GameObjects in game based on the current player position, essentially trying to make an infinite runner type of game...I made a function so I can spawn the pylons with it but for some reason the function gets called only once per frame, It does not get called the second time with a different parameter.
Why does the second call of the function not work?
This is my code:
public class CameraScript : MonoBehaviour {
public float cameraSpeed = 1;
public float horizontalSpeed;
private int spawnIndex;
public float spawnNormPylonDis;
public float spawnCoinPylonDis;
private int currPosition ;
public GameObject[] pilons;
public GameObject spawnMainPoint;
public Transform[] spawnPoints;
public Transform[] coinsSpawnPoint;
public float enamySpeed;
private int currentPoint;
public Transform[] pointPosition;
// Use this for initialization
void Start () {
//This spawns the Pilons.
spawnMainPoint.transform.position = pointPosition [0].position;
currPosition = (int) transform.position.z;
}
// Update is called once per frame
void FixedUpdate () {
spawnMainPoint.transform.position = Vector3.MoveTowards (spawnMainPoint.transform.position, pointPosition[currentPoint].position, Time.deltaTime * horizontalSpeed);
SpawnPylon (pilons[1],spawnPoints,spawnNormPylonDis,"Check function");
SpawnPylon (pilons [0], spawnPoints, spawnCoinPylonDis,"Check the second function");
GetComponent<Rigidbody> ().velocity = transform.forward * cameraSpeed;
//the next if statements make the Pilons spawn randomly and corectly.
if (spawnMainPoint.transform.position == pointPosition [currentPoint].position) {
currentPoint++;
}
if (currentPoint == pointPosition.Length) {
currentPoint = 0;
}
}
/*This function spanws the a GameObject randomly at a GameObject's position and it takes 2 arguments :
Argument 1: type GameObject
2: type Transform[]*/
void SpawnPylon (GameObject whatSpawn,Transform[] whereSpawn,float spawnDistance,string plm)
{
bool hasSpawnedPylon = false;
if (currPosition != (int)transform.position.z)
{
if ((int)transform.position.z % spawnDistance == 0)
{
Debug.Log (plm);
if (!hasSpawnedPylon)
{
//this makes the GameObject spawn randomly
spawnIndex = Random.Range (0, spawnPoints.Length);
//This is instantiationg the GameObject
Instantiate (whatSpawn, whereSpawn [spawnIndex].position, whereSpawn [spawnIndex].rotation);
//this makes shore that the GameObject is not spawned multiple times at aproximetley the same position.
currPosition = (int)transform.position.z;
}
}
}
else
{
hasSpawnedPylon = false;
}
}
}
Here I have a picture with the script in the inspector:
Script Inspector
And here is the console, trying to figure it out by using Debug.Log () for the calls of the function.
Using Debug.Log for the calls.
I tested it and it works fine under some conditions. The problem most likely is that your spawnNormPylonDis and spawnCoinPylonDis are public variables that are the same in the inspector, or spawnNormPylonDis is a multiple of spawnCoinPylonDis, pretty much with your code, you cannot have spawnNormPylonDis be 1. If they are then in the SpawnPylon function because it has already spawned one. You yourself commented.
//this makes shore that the GameObject is not spawned multiple times at aproximetley the same position.
currPosition = (int)transform.position.z;
I tested this with values of 2 and 3 and both functions got called, however, it would skip the second function if they were both divisible (6).
Therefore you got bottlenecked at this line of code because you set the currPosition after the first function call.
if (currPosition != (int)transform.position.z)
By making a basic wrapper function all is well in the world! So we set the currPosition after we checked both spawning calls, and voila, problem solved.
void SpawnPylon(int index, Transform[] spawnPoint, float dist, string debug)
{
if ((int)transform.position.z % dist == 0)
{
//Debug.Log(debug);
//this makes the GameObject spawn randomly
spawnIndex = Random.Range(0, spawnPoints.Length);
//This is instantiationg the GameObject
GameObject go = Instantiate(pilons[index], spawnPoint[spawnIndex].position, spawnPoint[spawnIndex].rotation) as GameObject;
go.name = string.Format("ID: {0}", index);
}
}
private void SpawnMultiplePylons()
{
if (currPosition != (int)transform.position.z)
{
SpawnPylon(1, spawnPoints, spawnNormPylonDis, "Spawn1");
SpawnPylon(0, spawnPoints, spawnCoinPylonDis, "Spawn2");
currPosition = (int)transform.position.z;
}
}
I tested this and it worked. I hope that it also works for you!
This is unity 2d angry bird style game example. I working on resetter codes. Resetter code below (I changed some parts). I using ball on this project instead of birds. So, I want to if ball is stoped after to throw load new ball to catapult. But It doesn't work correctly. First of all. I wrote if ball count == 0 clone the object. But its alwaws clonning when ball was stoped. On the other hand I cant use cloned object for throwing. Cloned object not on the catapult. Sorry for my bad english but this problem my last
phase on this game.
for example
https://www.dropbox.com/s/h3gwinw8chyeh59/error.png?dl=0
This is game tutorial link.
http://unity3d.com/learn/tutorials/modules/beginner/live-training-archive/making-angry-birds-style-game
using UnityEngine;
using System.Collections;
public class Resetter : MonoBehaviour {
public Rigidbody2D projectile; // The rigidbody of the projectile
public float resetSpeed = 0.025f; // The angular velocity threshold of the projectile, below which our game will reset
private float resetSpeedSqr; // The square value of Reset Speed, for efficient calculation
private SpringJoint2D spring; // The SpringJoint2D component which is destroyed when the projectile is launched
public int BallCount; // I using this value for I need new ball or not
public Rigidbody2D projectileSD; // Ball
void Start ()
{
BallCount = 1;
// Calculate the Resset Speed Squared from the Reset Speed
resetSpeedSqr = resetSpeed * resetSpeed;
// Get the SpringJoint2D component through our reference to the GameObject's Rigidbody
spring = projectile.GetComponent <SpringJoint2D>();
}
void Update () {
// If the spring had been destroyed (indicating we have launched the projectile) and our projectile's velocity is below the threshold...
if (spring == null && projectile.velocity.sqrMagnitude < resetSpeedSqr) {
// ... call the Reset() function
// Reset ();
if (BallCount == 0 );
{
ObjeyiKlonla();
}
}
}
void ObjeyiKlonla() { // Clone object
Rigidbody2D clone;
clone = Instantiate (projectileSD, transform.position, transform.rotation) as Rigidbody2D;
clone.velocity = transform.TransformDirection (Vector3.forward * 1);
BallCount ++;
}
void OnTriggerExit2D (Collider2D other) {
// If the projectile leaves the Collider2D boundary...
if (other.rigidbody2D == projectile) {
// ... call the Reset() function
//Reset ();
}
}
void Reset () {
// The reset function will Reset the game by reloading the same level
//Application.LoadLevel (Application.loadedLevel);
BallCount =0;
}
}
Try this.
void Update(){
if(projectile.GetComponent <SpringJoint2D>() && projectile.velocity.sqrMagnitude < resetSpeedSqr)
{
if (BallCount <= 0 );
{
ObjeyiKlonla();
}
}
}