Unity3D: killing them softly

I promised to write, and there’s not much to write about lately, and I’m kinda busy and determined to finally finish Railyard this week, but promise is a promise – new portion of Unity3D tips and tricks for beginners comin’ right up.

Trick #1

You need some nice visuals to kill an object in the scene, be it blown up, burnt or just shot in the head. Most basic “death” effect that leaves no traces of the previously existing object is dissolution – as seen in Doom 3 or Unreal 3 (or Bureau XCOM, not sure about that one) after shooting some bullets in some alien’s head, or in this picture of Hogwarts’ shield failing:

NewHogwartsDH

This effect can be achieved with built-in alpha cutoff shader. First, you’ll need a separate “death” material with a shader from “Transparent/Cutout” group, that you’ll apply to your renderer when kill sequence is initiated. Second, you’ll need a separate texture for your object with an alpha that looks like this (note, making those clouds less blurry will not look good on small objects while dissolving):

clouds

Third, you’ll need to animate the cutoff value on your material from 0 to 1.0f in your code:

renderer.material.SetFloat("_Cutoff", timeElapsed);

That’s it, you’re done dissolving your enemies. Oh, you wanted glowing edges too? That’s not beginners’ stuff, and requires a custom shader, you can read about it in this forum post.

Trick #2

This really comes in handy when you got a particle effect attached to the object you destroying. Particles got their own lifetime and just removing them from a scene in an instant is not cool. So what should you do?

First, make sure your particle systems are on separate GameObjects within hierarchy. This will let you detach them on parent’s destruction – like this (this should be called from script attached to root GameObject):

void OnDestroy() {
    transform.DetachChildren();
}

Now all the particle systems are detached from their parent, but maintain their position/rotation/scale. Two moments here: 1) if your particle systems are looped, you should stop them now and 2) if you stopped them before detaching and they have “play on awake” ticked, they will start emitting again after detaching.

Second part – how to avoid cluttering. When stopped, PSs still consume memory, so you have to kill them somehow after they completely done. A simple script I wrote will help:

using UnityEngine;
using System.Collections;

public class SelfDestruct : MonoBehaviour {

    private bool sequenceInitiated = false;

    void Update() {
        if (transform.parent == null && !sequenceInitiated) {
            sequenceInitiated = true;
            float destructIn = 3;
            if (particleSystem != null) {
                destructIn = particleSystem.duration;
                particleSystem.Stop();
            }
            StartCoroutine(SelfDestructionIn(destructIn));
        }
    }

    IEnumerator SelfDestructionIn(float seconds) {
        yield return new WaitForSeconds(seconds);
        Destroy(transform.gameObject);
    }
}

When detached from a parent (means parent == null) the script will initiate a self-destruction sequence, which length is determined by particle system if current gameObject has one, and also stops the emitter. Just attach this script to a gameObject with a particle system inside your actor’s hierarchy.

More tricks to follow, requests accepted.

Tags:

Leave a comment