I want to make my spawned objects (enemy prefabs) movement speed up every 10 points my player collects.
This is my movement script, attached to my enemy prefab (so that it can be spawned in my game and move):
public static int movespeed = 20;
public Vector3 userDirection = Vector3.right;
public void Update()
{
transform.Translate(userDirection * movespeed * Time.deltaTime);
}
}
And this is my score script attached to my player:
public Text ScoreText;
public AudioClip Coinsound;
public Text Highscoretext;
public GameObject enemy;
Movement movement;
private int Score;
public int highScore = 0;
void Start ()
{
Score = 0;
SetScoreText ();
if (PlayerPrefs.HasKey ("Highscore"))
{
highScore = PlayerPrefs.GetInt("Highscore");
}
}
void OnTriggerEnter2D(Collider2D other)
{
if (other.gameObject.CompareTag ("Pick Up")) {
other.gameObject.SetActive (false);
Score = Score + 1;
SetScoreText ();
AudioSource.PlayClipAtPoint (Coinsound, transform.position);
}
}
As mentioned before I want to make my spawned enemy prefabs to move faster when my player collects every ten points. Thank you :)
You use the % symbol to do that. After adding 1 to Score, Check if there is a reminder when Score is divided by 10. If there is no remainder, increment. Don't increment of there is a remainder.
if (Score % 10 == 0){
//Increment movespeed variable from Movement script
Movement.movespeed += 4;
}
Put the code above in your OnTriggerEnter2D function.
For some reason, this looks very similar to another question but the OP failed to get that answer working.
Related
I am trying to get the enemy movement speed go faster than it was before the certain scored points. I am a novice programmer so if the code seems ugly please bear with it. If anyone could help me get through with this it would be really awesome. Thank You.
Here is my Score Managing code:
public class ScoreManager : MonoBehaviour
{
public float score;
public float pointsPerSecond;
public float highScore;
public bool scoreIncreasing;
public Text scoreText;
void Start()
{
score = 0;
if (PlayerPrefs.HasKey("HighScore")) // checks if player has HighScore or not
{
highScore = PlayerPrefs.GetFloat("HighScore"); //gets the value of stored highscore.
}
}
void Update()
{
if (scoreIncreasing) //checks if score is increasing or not
{
score += pointsPerSecond * Time.deltaTime; //increases score as per time
}
if (score > highScore) // checks if score is greater than highscore or not
{
highScore = score; //sets value of score to highscore
PlayerPrefs.SetFloat("HighScore", highScore); // stores the value of highscore
}
scoreText.text = ((int)score).ToString() + " Clicks";
//provieds the value of score to score text object.
}
}
and here is my enemy mover code:
public class EnemyMover : MonoBehaviour
{
[SerializeField]
private float tumble;
public float baseSpeed = 2f;
public float newSpeed;
public float multiplier;
public float scoreToNextLevel = 10f;
void Start ()
{
GetComponent<Rigidbody>().angularVelocity = Random.insideUnitSphere * tumble; //makes the object rotate
FindObjectOfType<ScoreManager>(); //caches the scoremanaging script
baseSpeed *= multiplier; //gives basespeed a value eg baseSpeed(2) * multiplier(2) = 4.
}
void Update ()
{
GoUp(); //calls method goup
EnemyMovement(); //calls method enemy movement
}
public void EnemyMovement()
{
if(FindObjectOfType<ScoreManager>().score > scoreToNextLevel)
//checks whether the condition is true
{
NewSpeed(); //calls method newspeed
SpeedUp(); // calls method speedup
}
multiplier += 1; // increases the value of multiplier by 1
}
public void GoUp()
{
transform.position += Vector3.up * baseSpeed * Time.deltaTime; //moves the enemy object upwards in y axis.
}
public void NewSpeed()
{
newSpeed = baseSpeed * multiplier * Time.deltaTime; // proves new speed with a value.
}
public void SpeedUp()
{
transform.position += Vector3.up * newSpeed; // moves enemy object upwards into y axis using new speed.
}
}
Thank you guys, i figured it out. I did it like this.
void Update ()
{
if (FindObjectOfType<ScoreManager>().score > scoreToNextLevel) // checks if score
is greater than score to next level, if yes then following codes are applied.
{
multiplier += 1f; // increases the value of multiplier by 1.
baseSpeed += multiplier;// adds the multiplier value to basespeed.
EnemyMovement();//calls the enemymovement method
scoreToNextLevel *= 2;// multiplies the score to next level by 2.
}
Hello guys i work on some reflex tapping game in unity and i need script for every 2 or more prefab destroy to add speed on my player and i need that constatly adding speed for 2 prefbas. Can someone help me whit that i do like this:
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Sphere"))
{
count = count + 1;
if(count >= highScore)
{
highScore = count;
PlayerPrefs.SetInt("highscore", highScore);
PlayerPrefs.Save();
}
SetCount();
if(count == 2)
{
rb.AddForce(0, 0, 50 * forwardForce * Time.deltaTime);
}
}
I would recommend making Speed a property of your Player class:
public class Player : MonoBehaviour
{
public float Speed;
}
You would need to make sure to multiply by this property when you move the player (I'm assuming your code is similar to this):
rigidbodyReference.AddForce(0, 0, 50 * Speed * Time.deltaTime);
Then, I would make a static GameManager class that will keep track of the number of prefabs:
public static class GameManager : MonoBehaviour
{
public static PrefabCount;
}
Finally, I would add a speedIncrement variable (exposed to the inspector) as a property of your Player class and modify your OnTriggerEnter method:
public float speedIncrement;
// ...
void OnTriggerEnter(Collider other)
{
// This will reduce unnecessary nesting in your code to make it easier to read
if (!other.gameObject.CompareTag("Sphere"))
return;
// Same thing as GameManager.PrefabCount = GameManager.PrefabCount + 1
GameManager.PrefabCount++;
if (GameManager.PrefabCount >= highScore)
{
highScore = GameManager.PrefabCount;
PlayerPrefs.SetInt("highscore", highScore);
PlayerPrefs.Save();
}
// Use the Modulus operator to determine if the PrefabCount is evenly divisible by 2
if (GameManager.PrefabCount % 2 == 0)
Speed += speedIncrement; // Increase speed by whatever value set in the inspector
}
I'm making a game that is similar to Space Shooter, and I would like to know how to prevent a player from shooting projectiles AFTER the ammo has depleted.
The two scripts below controls my player's movement and actions, and decreases the current projectile count each time the player hits spacebar.
Player script
using UnityEngine;
using System.Collections;
public class Player : MonoBehaviour {
//Movement speed of Player sprite
public float Speed = 20.5f;
//GameObject to store the projectile object
public GameObject Projectile;
// Update is called once per frame
void Update ()
{
//If left arrow key is pressed
if (Input.GetKey (KeyCode.LeftArrow))
//Move the player to the left
transform.Translate (new Vector2 (-Speed * Time.deltaTime, 0f));
//If right arrow key is pressed
if (Input.GetKey (KeyCode.RightArrow))
//Move the player to the right
transform.Translate (new Vector2 (Speed * Time.deltaTime, 0f));
//If the spacebar is pressed
if (Input.GetKeyDown (KeyCode.Space))
{
//Instatiate a new projectile prefab 2 units above the Player sprite
Instantiate (Projectile, transform.position + transform.up * 2, Quaternion.identity);
//Find the game object with the tag "Projectile" and call the DecreaseProjectileCount() function from the ProjectileTracker script
GameObject.FindGameObjectWithTag("Projectile").GetComponent<ProjectileTracker>().DecreaseProjectileCount();
}
}
}
ProjectileTracker script
using UnityEngine;
using System.Collections;
public class ProjectileTracker : MonoBehaviour {
//Variable to store the current projectile count
public GameObject ProjectileRef;
//Set the current projectile count to be 8
int CurrentProjectileCount = 8;
//Function to decrease the current projectile count
public void DecreaseProjectileCount()
{
//Decrease the current projectile count by 1
CurrentProjectileCount--;
//Print out the current projectile count
ProjectileRef.GetComponent<TextMesh> ().text = CurrentProjecileCount.ToString ();
}
}
Any form of help is appreciated!
The way i would personally do it:
ProjectileTracker tracker = GameObject.FindGameObjectWithTag("Projectile").GetComponent<ProjectileTracker>();
//If the spacebar is pressed
if (Input.GetKeyDown (KeyCode.Space) && tracker.ProjectileCount > 0)
{
//Instatiate a new projectile prefab 2 units above the Player sprite
Instantiate (Projectile, transform.position + transform.up * 2, Quaternion.identity);
//Find the game object with the tag "Projectile" and call the DecreaseProjectileCount() function from the ProjectileTracker script
tracker.ProjectileCount--;
}
...
using UnityEngine;
using System.Collections;
public class ProjectileTracker : MonoBehaviour {
//Variable to store the current projectile count
public GameObject ProjectileRef;
//Set the current projectile count to be 8
private int projectileCount = 8;
public int ProjectileCount
{
get { return projectileCount; }
set { SetProjectileCount(value); }
}
//Function to decrease the current projectile count
public void SetProjectileCount(int value)
{
projectileCount = value;
//Print out the current projectile count
ProjectileRef.GetComponent<TextMesh> ().text = value.ToString();
}
}
I'm making a 'run' game in Unity and I'm making a prototype with a ball, that has other balls following him. If the followers hit an object they get destroyed after some time. To make it so you don't run out of enemies I made a trigger that spawns new enemies. In the code this is the function Addzombies.
How do I make them spawn not on the same point, if i run it now they
start on eachother and bounce around as an explosion.
How do i make some start in the air, i tried it but they don't
spawn.
My code:
using UnityEngine;
using System.Collections;
public class Ball : MonoBehaviour {
public float InputForce;
public GUIText guiText;
public float rotationHorizontal;
public AudioClip ACeffect2;
public GameObject zombiePrefab;
void FixedUpdate() {
rigidbody.AddForce( Camera.main.transform.right * Input.GetAxis("Horizontal") * InputForce);
rigidbody.AddForce( Camera.main.transform.forward * Input.GetAxis("Vertical") * InputForce);
transform.position += Vector3.forward *InputForce * Time.deltaTime;
rotationHorizontal = Input.GetAxis("Horizontal") * InputForce;
rotationHorizontal *= Time.deltaTime;
rigidbody.AddRelativeTorque (Vector3.back * rotationHorizontal);
}
void OnCollisionEnter(Collision col){
if (col.gameObject.name == "Zombie") {
Debug.Log ("Player geraakt, nu ben je eigenlijk dood");
}
if (col.gameObject.name == "Obstakel1") {
Debug.Log ("Obstakel1 geraakt");
audio.PlayOneShot(ACeffect2);
InputForce = 0;
}
if (col.gameObject.name == "Obstakel2") {
Debug.Log ("Obstakel2 geraakt");
}
}
void AddZombies(int aantal){
for (int i = 0; i < aantal; i++){
GameObject go = GameObject.Instantiate(zombiePrefab, transform.position - new Vector3(0, 0, 7 + i),Quaternion.identity) as GameObject;
Zombie zb = go.GetComponent<Zombie>();
zb.target = gameObject.transform;
}
}
void OnTriggerEnter(Collider col) {
Debug.Log ("Enter" +col.name);
if (col.tag == "AddZombies"){
AddZombies(4);
}
}
void OnTriggerExit(Collider col) {
Debug.Log ("Leaving with" +col.name);
}
}
I will advice on how things could be done, but you will have to make changes to make it suit your requirement
public Transform zombiePrefab; // From the editor drag and drop your prefab
void addZombies()
{
// as you need them to be not on the same point
int randomX = Random.Range(-10.0F, 10.0F);
for (int i = 0; i < aantal; i++){
// make a transform
var zombieTransform = Instantiate(zombiePrefab) as Transform;
zombieTransform.position = new Vector3(randomX, 0, 7 + i);
transform.GetComponent<Rigidbody>().enabled = false;
// make it enable when you need and add force to make them fall
}
}
I would suggest passing the number of zombies to pass, and an integer representing the range of space that they can spawn in. Then just use UnityEngine.Random with said integer for each zombie to produce several different co-ordinates for spawning the zombies.
As for getting them to spawn in the air, just increase the y co-ordinate when you instantiate the zombie.
I have a player class in Unity which all works fine except for my ClosestTarget function. The function works how I wanted it to but now it only ever picks Cube 2 (The last element in the list) even if I'm closer to another cube.
The class is as shown:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Player : MonoBehaviour
{
public int health; //Current health
public int stamina; //Current stamina
public int maxHealth = 100; //Constant for max health
public int maxStamina = 500; //Constant for max stamina
protected CharacterController chCtrl; //Reference to the character controller
protected CharacterMotor chMotor; //Reference to the character motor
public float walkSpeed = 3; //Speed at which the player walks
public float runSpeed = 20; //Speed at which the player runs
public bool isWalking = false; //Check for whether the player is walking
public bool isRunning = false; //Check for whether the player is running
public bool isFatigued = false; //Check for whether the player is fatigued
public List<Transform> targets; //Create a list of transforms
public Transform currentTarget;
float distance = Mathf.Infinity;
// Use this for initialization
void Start ()
{
//Get the character controller assigned to the current game object
chCtrl = GetComponent<CharacterController> ();
//Get the character motor assigned to the current game object
chMotor = GetComponent<CharacterMotor> ();
//Set the stamina to the max stamina
stamina = maxStamina;
//Set the health to the max health
health = maxHealth;
//Initialise the targets list
targets = new List<Transform>();
//Call the function to retrieve all buttons in the scene
AddAllButtons();
}
// Update is called once per frame
void Update ()
{
//Call the function to set the speed of the player
SetSpeed ();
ClosestTarget();
}
public void SetSpeed ()
{
//Set the player to walking speed by default
float speed = walkSpeed;
//If the stamina is less than or equal to 0
if (stamina <= 0)
{
//Set the player as fatigued
isFatigued = true;
//Set the player to walking
speed = walkSpeed;
//Set stamina to 0
stamina = 0;
}
//If the stamina is greater than or equal to max stamina
if(stamina >= maxStamina)
{
//Set the stamina to the max stamina
stamina = maxStamina;
//Set the player as not fatigued
isFatigued = false;
}
//If the player is moving along either the x or y axis
if (Input.GetAxis("Horizontal") !=0 || Input.GetAxis("Vertical") !=0)
{
//If the player is fatigued
if(isFatigued == true)
{
//Set the player to walking speed
speed = walkSpeed;
//Player is not running
isRunning = false;
//Player is walking
isWalking = true;
//Start increasing stamina
stamina++;
}
//If the player is touching the ground and the user is either pressing left shift or right shift
else if (chCtrl.isGrounded && Input.GetKey ("left shift") || Input.GetKey ("right shift") && isFatigued == false )
{
//Set the player to running speed
speed = runSpeed;
//Player is running
isRunning = true;
//Player is not walking
isWalking = false;
//Start reducting stamina
stamina--;
}
else
{
//Set the player to walking speed
speed = walkSpeed;
//Player is not running
isRunning = false;
//Player is walking
isWalking = true;
//Start increasing stamina
stamina++;
}
}
else
{
//Player is not running
isRunning = false;
//Player is not walking
isWalking = false;
//Start increasing stamina
stamina++;
}
//Set the players speed to either walkSpeed or runSpeed
chMotor.movement.maxForwardSpeed = speed;
}
void AddAllButtons()
{
//Create an array that contains all game objects tagged with 'button'
GameObject[] buttons = GameObject.FindGameObjectsWithTag("Button");
//For each of the game objects in the array
foreach(GameObject button in buttons)
{
//Add the transform of the button
AddButton(button.transform);
}
}
void AddButton(Transform button)
{
//Add the transform of the button into the targets list
targets.Add(button);
}
void ButtonCheck(Transform button)
{
Vector3 dir = (button.position - transform.position).normalized;
float direction = Vector3.Dot(dir, transform.forward);
Debug.Log(direction);
if(Input.GetKeyDown(KeyCode.E))
if(direction > 0.7F && Vector3.Distance(currentTarget.position, transform.position) < 2.0F)
{
print("Button has been clicked");
}
}
void ClosestTarget()
{
foreach (Transform button in targets)
{
Vector3 diff = (button.position - transform.position);
float curDistance = Vector3.Distance(transform.position, button.position );
Debug.Log(curDistance);
if (curDistance < distance )
{
currentTarget = button;
distance = curDistance;
}
}
}
}
As said, the problem is with the ClosestTargets function. It's finding the distance for every cube but it only ever selects the last element in the targets list.
It still shows the distance from every cube in the console.
My guess: distance is class member and correctly initialised to Mathf.Infinity but it's never reset. So on the first call to ClosestTarget () Cube2 might be the one closest to player as Player.Update might called later. So distance contains a value too tiny (0?) for other objects to have a chance.
I use this extension method to find the closest gameObject (warning it uses linq):
public static GameObject ReturnClosestObject(this GameObject go, float radius, LayerMask layerMask)
{
Collider[] closeObjects = Physics.OverlapSphere(go.transform.position, radius, layerMask);
closeObjects = closeObjects.OrderBy((collider) => Vector3.Distance(collider.gameObject.transform.position, go.transform.position)).ToArray();
GameObject returnedObject = null;
if(closeObjects.FirstOrDefault().Exist())
{
returnedObject = closeObjects.FirstOrDefault().gameObject;
}
return returnedObject;
}
The downside to this method is that it will only detect objects that overlapwith the projected sphere and miss objects that are inside it completly. So I will often compliment it with this recursive function that projects a finit amount of sphere at various distances.
Note while they have similier names, the above is a extension method and below is a instance method. They work together hand and hand.
public GameObject FindClosestGameObject(int startingLookUpDistance, int maxLookUpDistance, int numberOfSteps)
{
GameObject closestGameObject = gameObject.ReturnClosestObject(startingLookUpDistance, LayerMasks.gameObjects);
bool gameObjectNotFound = (closestGameObject.Equals(null));
if(gameObjectNotFound)
{
if(startingLookUpDistance <= maxLookUpDistance)
{
float stepDistance = maxLookUpDistance / numberOfSteps;
return FindClosestBuildingObject((int)(startingLookUpDistance + stepDistance), maxLookUpDistance, numberOfSteps);
}
return null;
}
else
{
return closestGameObject;
}
}
This top method works by specifying your starting distance and your max distance, you then specify how many iterations of the function you want to perform. Based on the number of iterations it will cast a n spheres equal distances apart in between your start and stop bounds.