- Home /
Im trying to make the enemy flash red when the bullet hits them
I am making a 3D game in unity and I want the enemies to flash red whenever the bullet hits them. This is my code, right now nothing happens when i shoot the enemy. Would appreciate some help on this
void Shoot()
{
MuzzleFlash.Play();
MuzzleFlash1.Play();
CurrentAmmo--; //if player shoots, ammo decreases
RaycastHit hit;
if (Physics.Raycast(FPSCam.transform.position, FPSCam.transform.forward, out hit, gunrange))
{
Debug.Log(hit.transform.name);
EnemyTarget target = hit.transform.GetComponent<EnemyTarget>();
if (target != null)
{
target.DamageTaken(gundamage);
num = Random.Range(0, enemyparticles.Length);
Instantiate(enemyparticles[num], hit.point, Quaternion.LookRotation(hit.normal)); //picks a random blood splatter from an array
StartCoroutine(redd());
IEnumerator redd()
{
GetComponent<Renderer>().material.color = collideColor;
yield return new WaitForSeconds(1.0f);
GetComponent<Renderer>().material.color = normalColor;
}
}
}
GameObject Impact = Instantiate(GunImpact, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(Impact, 0.1f);
}
Answer by Malek-Bakeer · Nov 16, 2020 at 12:21 PM
Hello, please check the following:
1- First make sure that the Debug.Logs you're doing are actually showing up in the console. 2- Secondly I can see that the enemy target is another object and this is the shooting script which I assume is attached to a gun, if so then the following code should be like this:
//This
StartCoroutine(redd());
IEnumerator redd()
{
GetComponent<Renderer>().material.color = collideColor;
yield return new WaitForSeconds(1.0f);
GetComponent<Renderer>().material.color = normalColor;
}
//Should be replaced with this
StartCoroutine(redd(target));
IEnumerator redd(EnemyTarget target)
{
target.GetComponent<Renderer>().material.color = collideColor;
yield return new WaitForSeconds(1.0f);
target.GetComponent<Renderer>().material.color = normalColor;
}
So @Gabimela what you were doing is changing the color of the gun itself.
Let me know if I helped <3
Best of luck, Malek
Hi there, its co$$anonymous$$g up with this error : Assets\Scripts\Gun.cs(106,46): error CS0136: A local or parameter named 'target' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
Hello, sorry I forgot about that.
You can do one of the following:
1- ($$anonymous$$ost recommended) - $$anonymous$$ove all of the IEnumerator redd(...) method to after the Shoot() method, which should look like this: void Shoot() {
$$anonymous$$uzzleFlash.Play();
$$anonymous$$uzzleFlash1.Play();
CurrentAmmo--; //if player shoots, ammo decreases
RaycastHit hit;
if (Physics.Raycast(FPSCam.transform.position, FPSCam.transform.forward, out hit, gunrange))
{
Debug.Log(hit.transform.name);
EnemyTarget target = hit.transform.GetComponent<EnemyTarget>();
if (target != null)
{
target.DamageTaken(gundamage);
num = Random.Range(0, enemyparticles.Length);
Instantiate(enemyparticles[num], hit.point, Quaternion.LookRotation(hit.normal)); //picks a random blood splatter from an array
StartCoroutine(redd(target));
}
}
GameObject Impact = Instantiate(GunImpact, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(Impact, 0.1f);
}
IEnumerator redd(EnemyTarget enemy)
{
enemy.GetComponent<Renderer>().material.color = collideColor;
yield return new WaitForSeconds(1.0f);
enemy.GetComponent<Renderer>().material.color = normalColor;
}
OR
2- (Not recommended) - Just simply rename the target to anything else inside the IEnumerator which should look like this: //From this StartCoroutine(redd(target)); IEnumerator redd(EnemyTarget target) {
target.GetComponent().material.color = collideColor; yield return new WaitForSeconds(1.0f); target.GetComponent().material.color = normalColor; }
//To this
StartCoroutine(redd(target));
IEnumerator redd(EnemyTarget anyNameYouWant)
{
anyNameYouWant.GetComponent<Renderer>().material.color = collideColor;
yield return new WaitForSeconds(1.0f);
anyNameYouWant.GetComponent<Renderer>().material.color = normalColor;
}
Hello, i have trtied this and i am not getting any errors but it just still doesn't do anything!
Answer by Pokedlg3 · Nov 16, 2020 at 12:27 PM
In visual Studio Code is giving an alert that the redd routine is mentioned but does nothing?
Also try to create an enemy public GameObject and then, in the enumerator, place it like this:
IEnumerator redd() { enemie.transform.GetComponent<Renderer>().material.color = color.red; yield return new WaitForSeconds(1.0f); enemie.transform.GetComponent<Renderer>().material.color = null; }
try this and answer the question above, maybe the routine is not working.
hi, when i try this, theres an error that says: error CS0037: Cannot convert null to 'Color' because it is a non-nullable value type and error CS0103: The name 'color' does not exist in the current context
Answer by jackmw94 · Nov 16, 2020 at 01:29 PM
I believe the reason why you're not seeing an colour changes is because to alter shader settings via a material, you need to be using the Set... functions on the material. GetComponent<Renderer>().material.SetColor("_Color", Color.red);
This "_Color" is the shader's property ID. To find out this ID for the shader you're using, find the enemy in scene, find the material that the renderer is using, scroll down to the shader properties and click on the cog in the corner, here you can go to 'Edit Shader'. The first thing you'll see is a list of the properties, you'll want to copy the ID of the value you want to set in code. So if you see _BaseColor("MyColor", Color) = (1,1,1,1)
, the ID is "_BaseColor" and not "MyColor".
Also just a side note but you'll need to think about what behaviour you want to see if you hit the enemy again before 1 second is up. At the moment if this happens the 1st coroutine will be waiting and the 2nd coroutine will start and set the colour to red again, then the 1st coroutine will finish and turn the red colour off meaning the second hit won't keep the enemy red for the whole second. If this is fine then great, however if you don't want this you can always store a reference to the coroutine and stop the previous one before starting a new one to prevent previous hits reverting the colour.
private Coroutine _hitColourChange = null;
...
if (_hitColourChange != null)
{
StopCoroutine(_hitColourChange);
}
_hitColourChange = StartCoroutine(redd());
Hope this helps, let me know if you need clarification! :)
Your answer
Follow this Question
Related Questions
Coroutines white death causes? 0 Answers
Rotating enemy with direction 1 Answer
Multiple Cars not working 1 Answer
Distribute terrain in zones 3 Answers
RPGStatSystem tutorial problem with clases visibility? 1 Answer