- Home /
[Solved] How to disable function in same script? C#
using UnityEngine;
public class RaycastShoot : MonoBehaviour
{
[SerializeField]
private float range = 300f;
[SerializeField]
private float timer;
private RaycastHit hit;
private Transform myTransform;
void Start()
{
myTransform = transform;
}
void Update()
{
timer -= Time.deltaTime;
if (timer < 0)
{
timer = 0;
Shoot();
}
timer += Time.deltaTime;
if (timer >= .2)
{
Shoot() = false;
}
}
void Shoot ()
{
if (Input.GetButton("Fire1"))
{
Debug.DrawRay(myTransform.TransformPoint(0, 0, 1f), myTransform.forward, Color.green, 3);
if (Physics.Raycast(myTransform.TransformPoint(0, 0, .1f), myTransform.forward, out hit, range))
{
if (hit.transform.CompareTag("Enemy"))
{
Debug.Log("Enemy" + hit.transform.name);
}
else
{
Debug.Log("Not an enemy");
}
}
}
}
}
I am trying to make a timer to disable the Shoot() function in void Update. Help?
Thank you both for answering my question! thanx :)
Answer by JVene · Jul 13, 2018 at 08:12 PM
The particular way you've posed your question brings up an interesting topic, a technique referred to as "delegates".
Now, for a simple situation you could just create a bool, say "shouldShoot", which the shoot function honors by returning immediately when false (or alternatively, only does something if shouldShoot is true).
That works, and is typically a great choice for simple use cases.
However, you specifically asked for help with line 30 in which this won't compile:
shoot() = false;
This doesn't compile because the () operator treats shoot as a function call, and since that function returns a void, that void can't be assigned to false. If shoot returned a valid type in which such an assignment made sense, it might compile, but probably wouldn't do what you want. This latter explanation is the basis for text like:
GetComponent<Script>().Function();
Where GetComponent returns a Script object, which can be used as any object to call a member function (or, if it were appropriate, assign to something - a dubious choice, but perhaps syntactically appropriate in the right circumstances, like setting a property).
However, what you are thinking is the notion of treating Shoot as if it were a variable you could change, even though it is a function.
That's what delegates offer.
To use this technique for your goal, you'd need to declare a delegate to a function of the same signature of your Shoot function with something like:
delegate void ShootFunc();
At this point, ShootFunc is a type. The type is a delegate to a function that returns void and takes no parameters (though it could take parameters in other contexts and return a type if you required).
Next, you create a member variable in your script using this type. Something like:
ShootFunc Shoot;
It is important to note that Shoot is now a variable. It represents a function call, but it is a variable. In this declaration the variable is null, so using it would generate an exception.
Next, you create two "Shoot" type functions, something like:
void DoShoot(){....}
void DontShoot(){....}
These two functions now represent two possible ways a call to Shoot would respond. To enable shooting, you assign Shoot to one or the other function with something like:
Shoot = DoShoot;
This is what you'd want to do with Shoot() = true (which doesn't work, you know). Instead, you're assigning the delegate so it calls DoShoot, and shooting is thus performed any time code does:
Shoot();
Now, to disable shooting, you do something like:
Shoot = DontShoot;
Whatever the real function DontShoot does, it does not shoot. Maybe it makes a strange "no-shot" sound, or warning, or whatever.
This is how you can make a single function call used throughout your code change the behavior among several possible options.
Shoot, a member variable of the type delegate to a void f() function type, can be assigned to select specific behavior among any number of possible actual functions, mutating behavior based on circumstances you choose.
It is a bit more sophisticated than is typically applied to a "shoot/don't shoot" option, but I was prompted by your peculiar fashion of the question which indicates you're thinking along the lines of delegates, and you may have reason to use this in more complex scenarios, and you might enjoy avoiding bools but use a more sophisticated technique that offers cleaner code as a result.
Cheers @SynergyStudios
Answer by bolkay · Jul 13, 2018 at 07:47 PM
Use booleans
using UnityEngine;
public class RaycastShoot : MonoBehaviour
{
//Create a boolean variable
private bool shoot=true;
[SerializeField]
private float range = 300f;
[SerializeField]
private float timer;
private RaycastHit hit;
private Transform myTransform;
void Start()
{
myTransform = transform;
}
void Update()
{
timer -= Time.deltaTime;
if (timer < 0)
{
timer = 0;
Shoot();
}
timer += Time.deltaTime;
if (timer >= .2)
{
shoot=false;
//Shoot() = false;
}
}
void Shoot ()
{
if (Input.GetButton("Fire1")&&shoot==true)
{
Debug.DrawRay(myTransform.TransformPoint(0, 0, 1f), myTransform.forward, Color.green, 3);
if (Physics.Raycast(myTransform.TransformPoint(0, 0, .1f), myTransform.forward, out hit, range))
{
if (hit.transform.CompareTag("Enemy"))
{
Debug.Log("Enemy" + hit.transform.name);
}
else
{
Debug.Log("Not an enemy");
}
}
}
}
}
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
Avatar constructor returns null 1 Answer