- Home /
RayCast Loop?
I have two scripts for my enemy's health one which takes damage off, and the actual enemy's health, but it only takes damage off when I click the mouse button over and over where as I want it to take damage off when the LMB is held down because I have a machine gun. How would I change these scripts to do so?
Enemy Damage:
function Update(){
if (Input.GetButtonDown("Fire1")){
Shoot();
}
}
var shotSound: AudioClip;
var bloodPrefab: GameObject;
var sparksPrefab: GameObject;
function Shoot(){
if (shotSound) audio.PlayOneShot(shotSound);
var hit: RaycastHit;
if (Physics.Raycast(transform.position, transform.forward, hit)){
var rot = Quaternion.FromToRotation(Vector3.up, hit.normal);
if (hit.transform.tag == "Enemy"){
if (bloodPrefab) Instantiate(bloodPrefab, hit.point, rot);
hit.transform.SendMessage("ApplyDamage", 20, SendMessageOptions.DontRequireReceiver);
} else {
if (sparksPrefab) Instantiate(sparksPrefab, hit.point, rot);
}
}
}
Enemy's Health:
var health = 100;
function ApplyDamage(damage: int){
health -= damage;
if (health <= 0){
Destroy (gameObject);
}
}
Please format code properly by selecting it and using the code button.
Answer by WillTAtl · Nov 14, 2011 at 07:48 PM
GetButtonDown returns true only the first update after it is pressed, as you noticed already. You could just change "GetButtonDown" to "GetButton," which returns true every update that the button is still held down, but this would mean firing every single frame, which might not be what you want, and you'd have no way to tweak the fire rate, for example if you implemented multiple machine guns.
A better approach would be to use a coroutine, like so...
//Adding a variable you can configure in the inspector to adjust the rounds fired //per second var shotsPerSecond: float=15;
function Update() { //if the fire button was just pressed this frame... if (Input.GetButtonDown("Fire1")) { //launch Shoot() as a coroutine... StartCoroutine("Shoot"); } //if the fire button was just released... if (Input.GetButtonUp("Fire1")) { //stop the coroutine, so we'll stop firing StopCoroutine("Shoot"); } }
//slight mods to modify the shoot function to repeat with a delay function Shoot() { //loop forever... we'll end when StopCoroutine is called in Update() while(true) { / put all of your original shoot code here /
//this causes the function to suspend for
//some time before repeating the loop.
yield WaitForSeconds(1/shotsPerSecond);
//we're using 1/shotsPerSecond to convert shots-per-second into
//the seconds between shots. you could avoid the division by
//changing the var to fireDelay, but 15 shotsPerSecond is easier
//to understand in human terms than a fireDelay of 0.0666666667,
//at least in my opinion, and the performance cost is minimal.
} //end while
}
Answer by Ludiares.du · Nov 14, 2011 at 07:48 PM
Instead of using GetButtonDown, use GetButton, and use some delay system so it doesn't shoot every frame.
Your answer
![](https://koobas.hobune.stream/wayback/20220613042922im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
C# More Accurate or Larger Raycast 1 Answer
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Ray Casting Tutorial? 3 Answers
RayCast Delay? 1 Answer
Raycast Help 1 Answer