- Home /
Making bullet holes in enemies.
Hi! I am making an fps based on the fps tutorial. I have a raycast machine gun and a enemy robot. The enemy robot looks like this:
As you can see, the robot has armor and some exposed skin. Is there a way to make bullet holes on the armor and blood spurts on the skin?
Damage receiver:
var hitPoints = 100.0;
var deadReplacement : Transform;
var dieSound : AudioClip;
function ApplyDamage (damage : float) {
// We already have less than 0 hitpoints, maybe we got killed already?
if (hitPoints <= 0.0)
return;
hitPoints -= damage;
if (hitPoints <= 0.0)
{
Detonate();
}
}
function Detonate () {
// Destroy ourselves
Destroy(gameObject);
// Play a dying audio clip
if (dieSound)
AudioSource.PlayClipAtPoint(dieSound, transform.position);
// Replace ourselves with the dead body
if (deadReplacement) {
var dead : Transform = Instantiate(deadReplacement, transform.position, transform.rotation);
// Copy position & rotation from the old hierarchy into the dead replacement
CopyTransformsRecurse(transform, dead);
}
}
static function CopyTransformsRecurse (src : Transform, dst : Transform) {
dst.position = src.position;
dst.rotation = src.rotation;
for (var child : Transform in dst) {
// Match the transform with the same name
var curSrc = src.Find(child.name);
if (curSrc)
CopyTransformsRecurse(curSrc, child);
}
}
Machine Gun script:
var playerWeapons : GameObject;
var range = 100.0;
var fireRate = 0.005;
var force = 5.0;
var damage = 0.5;
var bulletsPerClip = 1000;
var clips = 5;
var reloadTime = 1;
private var hitParticles : ParticleEmitter;
var muzzleFlash : Renderer;
var reload : AudioClip;
private var bulletsLeft : int = 0;
private var nextFireTime = 0.0;
private var m_LastFrameShot = -1;
function Start () {
hitParticles = GetComponentInChildren(ParticleEmitter);
// We don't want to emit particles all the time, only when we hit something.
if (hitParticles)
hitParticles.emit = false;
bulletsLeft = bulletsPerClip;
}
function LateUpdate() {
if (muzzleFlash) {
// We shot this frame, enable the muzzle flash
if (m_LastFrameShot == Time.frameCount) {
muzzleFlash.transform.localRotation = Quaternion.AngleAxis(Random.value * 360, Vector3.forward);
muzzleFlash.enabled = true;
if (audio) {
if (!audio.isPlaying)
audio.Play();
audio.loop = true;
}
} else {
// We didn't, disable the muzzle flash
muzzleFlash.enabled = false;
enabled = false;
// Play sound
if (audio)
{
audio.loop = false;
}
}
}
}
function Fire () {
if (bulletsLeft == 0)
return;
// If there is more than one bullet between the last and this frame
// Reset the nextFireTime
if (Time.time - fireRate > nextFireTime)
nextFireTime = Time.time - Time.deltaTime;
// Keep firing until we used up the fire time
while( nextFireTime < Time.time && bulletsLeft != 0) {
FireOneShot();
nextFireTime += fireRate;
}
}
function FireOneShot () {
var direction = transform.TransformDirection(Vector3.forward);
var hit : RaycastHit;
// Did we hit anything?
if (Physics.Raycast (transform.position, direction, hit, range)) {
// Apply a force to the rigidbody we hit
if (hit.rigidbody)
hit.rigidbody.AddForceAtPosition(force * direction, hit.point);
// Place the particle system for spawing out of place where we hit the surface!
// And spawn a couple of particles
if (hitParticles) {
hitParticles.transform.position = hit.point;
hitParticles.transform.rotation = Quaternion.FromToRotation(Vector3.up, hit.normal);
hitParticles.Emit();
}
// Send a damage message to the hit object
hit.collider.SendMessageUpwards("ApplyDamage", damage, SendMessageOptions.DontRequireReceiver);
}
bulletsLeft--;
// Register that we shot this frame,
// so that the LateUpdate function enabled the muzzleflash renderer for one frame
m_LastFrameShot = Time.frameCount;
enabled = true;
// Reload gun in reload Time
if (bulletsLeft == 0)
Reload();
}
function Reload () {
playerWeapons.GetComponent(PlayerWeapons).enabled = false;
// Wait for reload time first - then add more bullets!
yield WaitForSeconds(reloadTime);
playerWeapons.GetComponent(PlayerWeapons).enabled = true;
// We have a clip left reload
if (clips > 0) {
clips--;
bulletsLeft = bulletsPerClip;
audio.PlayOneShot(reload, 1.0 / audio.volume);
}
}
function GetBulletsLeft () {
return bulletsLeft;
}
Answer by jacobschellenberg · Jul 30, 2013 at 05:31 PM
Considering the machine gun is using a raycast, if the point of impact is indeed the enemy armor, spawn a bullet hole decal. If the impact is skin, spawn a blood particle effect. You could figure out which is which by perhaps placing a collider box around the areas you determine to be armor or skin. Upon impact, ask which collider is hit and spawn the correct decal or particle effect to the point of impact.
Great, thank you! I'm a noob so sorry if the question was obvious.