I am creating a 3D Shooter and I am trying to make an enemy deal damage to the player every set seconds. I have made the enemy deal damage with a raycast but it deals the damage way too fast.
I thought using yield return new WaitForSeconds(2) would take 1 damage away from the player every 2 seconds but it deals damage to the player a lot faster.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyMove : MonoBehaviour
{
public Transform target;
public Transform player;
public float enemySpeed;
public int moveTrigger = 1;
public int isAttacking;
public float distanceFromPlayer;
void Update()
{
distanceFromPlayer = Vector3.Distance(target.transform.position, player.transform.position);
if (distanceFromPlayer <= 10 && moveTrigger == 1)
{
transform.LookAt(target);
StartCoroutine(EnemyDamage());
}
if (distanceFromPlayer <10 && moveTrigger == 1 && distanceFromPlayer >3)
{
transform.Translate(Vector3.forward * enemySpeed * Time.deltaTime);
}
}
IEnumerator EnemyDamage()
{
RaycastHit PlayerHit;
if (Physics.Raycast(target.transform.position, target.transform.forward, out PlayerHit))
{
Debug.Log(PlayerHit.transform.name);
Target target = PlayerHit.transform.GetComponent<Target>();
if (target != null)
{
yield return new WaitForSeconds(2);
GlobalHealth.playerHealth -= 1;
yield return null;
}
}
}
}
You are starting a coroutine in every update loop so every frame your damage coroutine gets called and applies your 1 damage after 2 seconds.
If you want a damage over time effect the suggestion of using an game tick timer is correct, but if you want your enemy to only be able to attack every x seconds you need to implement some kind of cooldown on your damage function. For example add up Time.deltaTime until the time you want has past, and only then the enemy is able to deal damage again. You can do that with a boolean.
As mentioned in other answers, you are starting a new coroutine each frame. You should do all your waiting and looping inside your coroutine, as execution exits and re-enters your coroutine from the yeild statment. This is how you would write this to work
// in update
if (distanceFromPlayer <= 10 && moveTrigger == 1){
transform.LookAt(target);
if(!isAttacking)
StartCoroutine(EnemyDamage());
}
IEnumerator EnemyDamage()
{
isAttacking = true;
while(distanceFromPlayer <= 10){ // in range
RaycastHit PlayerHit;
if (Physics.Raycast(target.transform.position, target.transform.forward, out PlayerHit)){
Target target = PlayerHit.transform.GetComponent<Target>();
if (target != null){
GlobalHealth.playerHealth -= 1;
yield return new WaitForSeconds(2);
}
}
}
isAttacking = false; // out of range
yield return null;
}
You can use FixedUpdate → set a local variable bool alreadyShoot = false.
In your EnemyDamage() add a if(!alreadyShoot) before damages application and set alreadyShoot to true after damages application.
In FixedUpdate you can set alreadyShoot to false.
You can choose an other solution to set alreadyShoot to false instead of FixedUpdate (for example a coroutine that trigger each seconds, ...)
in update loop, check when two seconds have passed when the player is in range
float timeInRange = 0.0f;
bool inRange = false;
if (distanceFromPlayer <= 10 && moveTrigger == 1)
{
inRange = true;
}
else
{
inRange = false;
timeInRange = 0;
}
if (inRange)
{
timeInRange += Time.DeltaTime;
}
if (timeInRange > 2.0f)
{
GlobalHealth.playerHealth -= 1;
timeInRange = 0.0f;
}
Related
I am very new to c# and I've come across a problem with my enemy spawner. I am making an endless top-down shooter, and after 20 enemies have been spawned and then destroyed, the enemies stop appearing. My score counter continues to increase though, which leads me to believe they're somehow being destroyed.
Here is the enemy spawn controller:
void Update()
{
if (!spawningObject && GameController.EnemyCount < spawnSettings[0].maxObjects)
{
spawningObject = true;
float pick = Random.value * totalWeight;
int chosenIndex = 0;
float cumulativeWeight = enemySpawnables[0].weight;
while(pick > cumulativeWeight && chosenIndex < enemySpawnables.Count - 1)
{
chosenIndex++;
cumulativeWeight += enemySpawnables[chosenIndex].weight;
}
StartCoroutine(SpawnObject(enemySpawnables[chosenIndex].type, Random.Range(spawnSettings[0].minWait / GameController.DifficultyMultiplier, spawnSettings[0].maxWait / GameController.DifficultyMultiplier)));
Spawn();
}
}
private IEnumerator SpawnObject(string type, float time)
{
yield return new WaitForSeconds(time);
randomSpawnPoint = Random.Range(0, enemySpawners.Length);
randomEnemy = Random.Range(0, enemy.Length);
enemyPool.SpawnObject(enemySpawners[randomSpawnPoint].position, transform.rotation);
spawningObject = false;
GameController.EnemyCount++;
}
And here is the enemy controller (attached to enemy prefab):
public void Start()
{
myRB = GetComponent<Rigidbody>();
player = FindObjectOfType<PlayerController>();
}
private void OnEnable()
{
player = FindObjectOfType<PlayerController>();
}
void Update()
{
if (health <= 0)
{
Die();
}
}
void FixedUpdate()
{
transform.LookAt(player.transform.position);
myRB.velocity = (transform.forward * moveSpeed);
//Falling
if(myRB.velocity.y < 0)
{
myRB.velocity += Vector3.up * Physics.gravity.y * (fallMultiplier - 1) * Time.deltaTime;
}
}
public void Die()
{
print("Enemy" + this.gameObject.name + " has died!");
EnemySpawn.instance.enemyPool.ReturnObject(this.gameObject);
player.GetComponent<PlayerController>().points += pointsToGive;
ScoreController.scoreValue += 1;
}
The only thing that should affect enemy health is the bullet. Here is the part of the bullet controller that affects enemy health:
public void OnTriggerEnter(Collider other)
{
if(other.tag == "Enemy")
{
triggeringEnemy = other.gameObject;
triggeringEnemy.GetComponent<EnemyController>().health -= damage;
PlayerController.instance.bulletPool.ReturnObject(gameObject);
}
}
The issue always happens after 20 enemies have been spawned/destroyed and 20 points have been achieved. Before then, enemy movement is normal and everything seems to be working as it should. It could very well be something very simple that I'm missing, but I'd appreciate any help!
When you do engage logic mistake good way to find it is Visual Studio debugging.
Here is good official article about whole process - https://docs.unity3d.com/Manual/ManagedCodeDebugging.html.
I would place breakpoint right at start of Update method to see that EnemyCount increases over time and then you will understand that you forgot to do decrement it.
The main goal is to move the object between the positions with a delay. This is working fine but other things are not working.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Waypoints : MonoBehaviour
{
public GameObject objectPrefab;
public LineRenderer lineRenderer;
public List<Transform> pointsToMove;
public float speed;
public bool go = false;
private List<GameObject> objectsToMove;
private List<Vector3> positions;
void Start()
{
objectsToMove = new List<GameObject>();
//Spawn objects and start movement
}
private void Update()
{
if (go && lineRenderer.positionCount > 0 && CurvedLineRenderer.linesSet)
{
positions = GetLinePointsInWorldSpace();
foreach(Transform objToMove in pointsToMove)
{
positions.Add(objToMove.position);
}
for (int i = 0; i < 3; i++)
{
objectsToMove.Add(Instantiate(objectPrefab, transform.parent));
StartCoroutine(Move(i));
}
go = false;
}
}
private IEnumerator Move(int i)
{
//Wait interval
yield return new WaitForSeconds(i * 10);
bool stillTraveling = true;
int pointIndex = 0;
float threshold = 0.1f;
while (stillTraveling)
{
//Check if close to point
if (Vector3.Distance(objectsToMove[i].transform.position, positions[pointIndex]) < threshold)
{
//Check if can move next point
if (pointIndex + 1 > positions.Count - 1)
{
stillTraveling = false;
}
//If not stop moving
else
{
pointIndex++;
}
}
//Move towards point
objectsToMove[i].transform.position = Vector3.MoveTowards(objectsToMove[i].transform.position, positions[pointIndex], speed * Time.deltaTime);
yield return null;
}
}
List<Vector3> GetLinePointsInWorldSpace()
{
var pointsToMove = new Vector3[lineRenderer.positionCount];
//Get the positions which are shown in the inspector
lineRenderer.GetPositions(pointsToMove);
//the points returned are in world space
return pointsToMove.ToList();
}
}
I'm updating once the positions in the Update.
I'm using StartCoroutine once in the Update to send the objects to move between the waypoints with a delay.
private void Update()
{
if (go && lineRenderer.positionCount > 0 && CurvedLineRenderer.linesSet)
{
positions = GetLinePointsInWorldSpace();
foreach(Transform objToMove in pointsToMove)
{
positions.Add(objToMove.position);
}
for (int i = 0; i < 3; i++)
{
objectsToMove.Add(Instantiate(objectPrefab, transform.parent));
StartCoroutine(Move(i));
}
go = false;
}
}
It's working by sending the objects to move with delay between the waypoints, but now I have some other problems.
Because I'm using StartCoroutine for the delay and because I'm setting the go flag to false then the speed value have no affect on the moving objects at run time and I'm not sure how to solve it so the speed will have a factor affecting the moving objects.
Another problem or not a problem but not sure how to do it is how to Update in run time the positions List ? Here in the Update I'm updating the List once :
positions = GetLinePointsInWorldSpace();
foreach(Transform objToMove in pointsToMove)
{
positions.Add(objToMove.position);
}
but I want that if the amount of positions in the function GetLinePointsInWorldSpace or/and the amount of pointsToMove have changed to update the positions List at rune time. I could just call this part in the update nonstop but I'm not sure of it will be too expensive ?
Last problem or how to do is how to make the object to move to move between the waypoints non stop over again from the start or moving backward when getting the last waypoint ? Again because using StartCoroutine for the delay everything is happening once.
If you want to move an object from one point to another, you should use Mathf.Sin(). The is using the sine function, and you put in the amount of cycles times Mathf.PI times 2. Here is what you would write:
float period = 2f;
Vector3 a; //the first point the object goes to
Vector3 b; //the second point that the object goes to
void Update()
{
float cycles = period * Time.time * Mathf.PI;
float amplitude = Mathf.Sin(cycles);
Vector3 location = Vector3.Lerp(a, b, amplitude);
Transform.position = location;
}
I then use Vector3.Lerp to interpolate between point a and point b. This isn’t what you were doing, but it is a much simpler way you can do it.
Vector3 a; //the first point the object goes to
Vector3 b; //the second point that the object goes to
void Update()
{
float cycles = period * Time.time;
Vector3 location = Vector3.Lerp(a, b, cycles);
Transform.position = location;
}
This one is for bringing the object just strait to point b and not back.
If you want there to be a delay between when it moves, here is the script:
float period = 2f;
float waitTime;
bool AtoB = true;
Vector3 a; //the first point the object goes to
Vector3 b; //the second point that the object goes to
void Start()
{
StartCoroutine(“Oscillator”);
}
IEnumerator Oscillator
{
float amplitude;
if (AtoB)
{
amplitude += Time.deltaTime * period;
}
else
{
amplitude -= Time.deltaTime * period;
}
amplitude = Mathf.Clamp(amplitude, 0, 1);
Vector3 location = Vector3.Lerp(a, b, amplitude);
Transform.position = location;
if (amplitude == 1)
{
AtoB = false;
yield return new WaitForSeconds(waitTime);
}
if else (amplitude == 0)
{
AtoB = true;
yield return new WaitForSeconds(waitTime);
}
else
{
yield return false;
}
}
I am somewhat new to C# and currently programming a method for instantiating objects in the Unity Editor.
The problem I am having with the code below is a logical error as follows: Instead of objects being created with 10 seconds in between, they are all spawned at the same time.
It is clear to me that this is a logical error. I find this hard to debug because it more so seems that my code for the timer simply isn't running. I've scratched my head as to why, can anyone help an aspiring rookie out? Thanks.
private void CreateObjects(GameObject objectToSpawn, float timer = 0.0f, float timerMax = 10.0f)
{
//If count of objects is less than the maximum constant, instantiate more at random web positions.
while (spiderCount < 7)
{
//StartCoroutine("SpiderGeneration");
timer += Time.deltaTime;
if (timer >= timerMax)
{
//spiderArray = GameObject.FindGameObjectsWithTag("spider");
//spiderCount = spiderArray.Length;
Debug.Log("spawnTime is set to true via ObjectGeneration");
//Generate a random number to choose from a series of set spawn points.
randPos = Random.Range(1, 4);
if (randPos == 1)
{
//Instantiate(object, position, quat);
Instantiate(objectToSpawn, rand1, transform.rotation);
Debug.Log("SPAWN 1");
timer = 0.0f;
}
else if (randPos == 2)
{
Instantiate(objectToSpawn, rand2, transform.rotation);
Debug.Log("SPAWN 2");
timer = 0.0f;
}
else if (randPos == 3)
{
Instantiate(objectToSpawn, rand3, transform.rotation);
Debug.Log("SPAWN 3");
timer = 0.0f;
}
else
{
Debug.Log("OBJECT GEN ERROR");
}
}
}
}
You could approach this in another way and code it simply using the Update() method that Unity calls every frame.
private int spiderCount;
private float timer;
public float TimerMax;
public List<Transform> spawnPoints = new List<Transform>(0);
private void Update ( )
{
timer += Time.deltaTime;
if ( spiderCount < 7 && timer >= TimerMax )
{
if ( spawnPoints.Count == 0 ) { Debug.LogError ( "You don't have any spawn points!" ); return; }
var spawnPointIndex = UnityEngine.Random.Range ( 0, spawnPoints.Count );
Instantiate ( objectToSpawn, spawnPoints[spawnPointIndex], transform.rotation );
++spiderCount;
timer = 0;
}
}
Not knowing how you'd like to set up your scene though, you might want ALL 7 spiders to appear straight away, with a 10 second (TimeMax) delay after that? But, either way, this should get you started.
I believe your issue is that this isn't being run in the update function. I'm fairly certain this would work if you were to call for the method to run in the update function and remove the while loop. This is because the Update() function runs once every frame, so when you add Time.deltaTime to a value, it will always only increase by 1 every second (allowing the timer you have here to work), however, what you have here does not add Time.deltaTime once every frame, it adds it recursively as long as your while(spiderCount < 7) returns true, this causes it to happen a bunch of times on the first frame, because it is reaching the timer value required on that first frame as is adding to the timer many times until it meets the criteria of the while function. This should definitely work if you do the following (also I read that you said you have the method in your FixedUpdate() method, you should only use FixedUpdate for physics updates, rather place it in your Update() method):
void Update()
{
CreateObjects({input the parameters here});
}
private void CreateObjects(GameObject objectToSpawn, float timer = 0.0f, float timerMax = 10.0f)
{
//If count of objects is less than the maximum constant, instantiate more at random web positions.
if (spiderCount < 7)
{
timer += Time.deltaTime;
if (timer >= timerMax)
{
randPos = Random.Range(1, 4);
if (randPos == 1)
{
//Instantiate(object, position, quat);
Instantiate(objectToSpawn, rand1, transform.rotation);
Debug.Log("SPAWN 1");
timer = 0.0f;
}
else if (randPos == 2)
{
Instantiate(objectToSpawn, rand2, transform.rotation);
Debug.Log("SPAWN 2");
timer = 0.0f;
}
else if (randPos == 3)
{
Instantiate(objectToSpawn, rand3, transform.rotation);
Debug.Log("SPAWN 3");
timer = 0.0f;
}
else
{
Debug.Log("OBJECT GEN ERROR");
}
}
}
}
I am fairly certain this should work, otherwise you can just use coroutines(which I would personally use), like so:
private void Start()
{
StartCoroutine(CreateObjects({input parameters here}));
}
IEnumerator CreateObjects(GameObject objectToSpawn, float timer = 0.0f, float timerMax = 10.0f)
{
//Wait for the allotted time amount (in this case 10 seconds)
yield return new WaitForSeconds(timerMax);
randPos = Random.Range(1, 4);
if (randPos == 1)
{
//Instantiate(object, position, quat);
Instantiate(objectToSpawn, rand1, transform.rotation);
Debug.Log("SPAWN 1");
timer = 0.0f;
}
else if (randPos == 2)
{
Instantiate(objectToSpawn, rand2, transform.rotation);
Debug.Log("SPAWN 2");
timer = 0.0f;
}
else if (randPos == 3)
{
Instantiate(objectToSpawn, rand3, transform.rotation);
Debug.Log("SPAWN 3");
timer = 0.0f;
}
else
{
Debug.Log("OBJECT GEN ERROR");
}
//If the spider count less than required, start the coroutine again to spawn another
if(spiderCount < 7)
{
StartCoroutine(CreateObjects({input parameters here}));
}
}
If you have any questions at all let me know, I am sure this isn't difficult at all to fix, just let me know if you need anything cleared up! (I also apologize if the beginning is a tad confusing to read, I confused myself at first and it shows through haha, but I cleared up when I got to the code)
Alright I have figured it out. To anyone reading this that had to same issues as me, my advice is as follows:
So you want a coroutine to start in the update function and not start multiple coroutines every frame, right? You need to set a flag for the coroutine. That was the answer. I simply set a one-time flag to activate upon starting the coroutine that prevents any more from starting until you decide to run it again.
Here is the code.
(Also I wanna say thanks to everyone that helped me out with this! I was able to find the right answer thanks to everyones input :) )
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class spiderGenerator : MonoBehaviour
{
public GameObject player;
public GameObject spiderPrefab;
public GameObject[] spiderArray = new GameObject[7];
public int spiderCount = 0;
private int randPos;
private Vector3 rand1;
private Vector3 rand2;
private Vector3 rand3;
bool inRange = false;
bool spawnerFlag = false;
// Start is called before the first frame update
void Start()
{
player = GameObject.FindGameObjectWithTag("Player");
rand1 = new Vector3(20.49f, 66.671f, 56.98f);
rand2 = new Vector3(8.88f, 66.671f, 61.65f);
rand3 = new Vector3(-1f, 66.671f, 65.52f);
}
// Update is called once per frame
void Update()
{
spiderArray = GameObject.FindGameObjectsWithTag("spider");
spiderCount = spiderArray.Length;
if (player.transform.position.z < 78 && player.transform.position.z > 47 && player.transform.position.x < 25 && player.transform.position.x > -6 && player.transform.position.y < 70 && player.transform.position.y > 60)
{
inRange = true;
}
else
{
inRange = false;
}
if (inRange == true && spawnerFlag == false)
{
StartCoroutine(CreateObjects(spiderPrefab));
Debug.Log("Coroutine CreateObjects for {0} STARTED", spiderPrefab);
spawnerFlag = true;
}
}
IEnumerator CreateObjects(GameObject objectToSpawn, float timerMax = 10.0f)
{
while (inRange == true && spiderCount < 7)
{
yield return new WaitForSeconds(timerMax);
Debug.Log("spawn for {0} is set to true via ObjectGeneration", objectToSpawn);
//Generate a random number to choose from a series of set spawn points.
randPos = Random.Range(1, 4);
if (randPos == 1)
{
//Instantiate(object, position, quat);
Instantiate(objectToSpawn, rand1, transform.rotation);
Debug.Log("SPAWN 1");
}
else if (randPos == 2)
{
Instantiate(objectToSpawn, rand2, transform.rotation);
Debug.Log("SPAWN 2");
}
else if (randPos == 3)
{
Instantiate(objectToSpawn, rand3, transform.rotation);
Debug.Log("SPAWN 3");
}
else
{
Debug.Log("OBJECT GEN ERROR");
}
}
Debug.Log("Coroutine TERMINATED");
yield break;
}
// need to put everything below the wait for 10 seconds to get results.
}
I have created a script that makes an enemy deal damage over time to a player from a raycast but it is making Unity crash once I'm in the required range for the enemy to move and deal damage. Anyone know why?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyMove : MonoBehaviour
{
public Transform target;
public Transform player;
public float enemySpeed;
public int moveTrigger = 1;
public bool isAttacking;
public int AttackTirgger;
public float distanceFromPlayer;
void Update()
{
distanceFromPlayer = Vector3.Distance(target.transform.position, player.transform.position);
if (distanceFromPlayer <= 10 && moveTrigger == 1)
{
transform.LookAt(target);
if (!isAttacking)
StartCoroutine(EnemyDamage());
}
if (distanceFromPlayer < 10 && moveTrigger == 1 && distanceFromPlayer > 3)
{
transform.Translate(Vector3.forward * enemySpeed * Time.deltaTime);
}
}
IEnumerator EnemyDamage()
{
isAttacking = true;
while (distanceFromPlayer <= 10)
{ // in range
RaycastHit PlayerHit;
if (Physics.Raycast(target.transform.position, target.transform.forward, out PlayerHit))
{
Target target = PlayerHit.transform.GetComponent<Target>();
if (target != null)
{
GlobalHealth.playerHealth -= 1;
yield return new WaitForSeconds(2);
}
}
}
isAttacking = false; // out of range
yield return null;
}
}
If I try to explain what your code does (in pseudo code) :
if(distance_to_target < 10)
{
lookAt(taget)
move_forward() //so you get closer from the target
while(distance < 10)
{
do_stuff() //the stuff doesn't change distance
}
}
When your distance became smaller than 10, and due to your transform.Translate() it stay < 10 forever, so here you have a while(true) → makes unity crash
I am looking for a help with make a delay in Unity in Update function.
I created something like this below. The cube is moving rotates once and then is waiting > rotates once > waiting ....
And there is my question. How i can make cube rotates constantly for some time instead of once. For Example: Wait 2sec, rotating constantly 5sec, Wait 2sec, rota....
I thinked about replace
ForCube.transform.Rotate (10, 10, 10);
by rotating Animation. But I want create it with transform.Rotate. Is there any option to do this?
using UnityEngine;
using System.Collections;
public class Ruch : MonoBehaviour
{
public float speed = 5;
public GameObject ForCube;
bool work = true;
// Use this for initializat
void Start ()
{
ForCube = GameObject.Find ("Cube");
Debug.Log (ForCube);
}
// Update is called once per frame
void Update ()
{
if (work) {
StartCoroutine (WaitSome ());
}
}
private IEnumerator WaitSome ()
{
work = false;
yield return new WaitForSeconds (3f);
ForCube.transform.Rotate (10, 10, 10);
work = true;
}
}
At the moment it looks like to me you are using a StartCoroutine which will work fine, but if you want maybe a little more control over when to rotate and when to stop you can use the Time.deltaTime The time in seconds it took to complete the last frame (Read Only).http://docs.unity3d.com/ScriptReference/Time-deltaTime.html
So basically you have yourself a float variable called Rotate which is lets say 10f
Then inside of your Update function
void Update ()
{
if(Rotate > 0)
{
Rotate -= Time.deltaTime;
ForCube.transform.Rotate (10, 10, 10);
}
}
Then when Rotate is equal to 0 it will stop, but then you can use your work bool to start a new timer.
One big think to take in is to use the Time.deltaTime, if you don't use this and you just use an int or whatever variable type the timer will differ depending on the FPS of the game for the player.
Let me know if you need anymore help :)
Instead of using coroutines, you can do it directly in the update function like this:
[SerializeField]
private float timeToWait; //In seconds
[SerializeField]
private float timeToRotate; //In seconds
private float timer = 0;
private bool waiting = true; //Set this to false if you want to rotate first, wait later
void Update()
{
if(!waiting) RotateYourObjectALittleBit(); //Call your own function or do whatever you want
timer += Time.deltaTime;
if(timer >= timeToWait && waiting) {
waiting = false;
timer = 0;
}
else if(timer >= timeToRotate && !waiting) {
waiting = true;
timer = 0;
}
}
This code is untested, so please let me know if you require further clarification or if it doesn't work.
Thanks everyone for fast Answer and help to solve my problem. I really appreciate that.
I created something like this:
Version 1.0
When the space key is down the cube start rotating for RotateTime, after this the Timer reset to start value(RotationTime), and u can click again button for rotate.
using UnityEngine;
using System.Collections;
public class Ruch : MonoBehaviour
{
public GameObject ForCube;
public float RotateTime = 5;
public float Timer = 0;
private bool Rotate = false;
// Use this for initializat
void Start ()
{
Timer = RotateTime;
ForCube = GameObject.Find ("Cube");
Debug.Log (ForCube);
}
// Update is called once per frame
void Update ()
{
//Start Rotating When Press Space Key
if (Input.GetKeyDown (KeyCode.Space)) Rotate = true;
else if (!(Input.GetKeyDown (KeyCode.Space))&&Timer <=0) Rotate = false;
RotateForSec (ref Timer);
}
//Function to Rotate for X sec
void RotateForSec(ref float sec)
{
if (Rotate && sec > 0) {
Debug.Log (Time.time);
ForCube.transform.Rotate (10, 10, 10);
sec -= Time.deltaTime;
}
//Reset Rotating Time after rotating
if (!Rotate && sec <= 0) Timer = RotateTime;
}
}
Version 2.0
The rotating of cube continues for 5 seconds and then automatically without pressing a key it wait some time and start over rotating. Again again and again ...
public GameObject ForCube;
public float RotateTime = 5;
public float Timer = 0;
public float PauseTime = 0;
private bool Pause = false;
private bool Rotate = true;
// Use this for initializat
void Start ()
{
Timer = RotateTime;
PauseTime = RotateTime;
ForCube = GameObject.Find ("Cube");
Debug.Log (ForCube);
}
// Update is called once per frame
void Update ()
{
//Start Rotating When Press Space Key
if (Rotate)
Pause = false;
else if (!Rotate) {
Pause = true;
}
if (!Pause)
RotateForSec (ref Timer);
else RotatePause ();
}
//Function to pause PauseTime sec
void RotatePause()
{
if (PauseTime > 0) {
PauseTime -= Time.deltaTime;
} else {
Pause = false;
Rotate = true;
PauseTime = RotateTime;
}
}
//Function to Rotate for X sec
void RotateForSec(ref float sec)
{
if (Rotate && sec > 0) {
Debug.Log (Time.time);
ForCube.transform.Rotate (10, 10, 10);
sec -= Time.deltaTime;
} else Rotate = false;
//Reset Rotating Time after rotating
if (!Rotate && sec <= 0) Timer = RotateTime;
}
}
Its working but what you think about that, is it done correctly or it is a bad way?