Arg… the loop (part 2)

I didn’t realise how much effort looping the map was going to be. I’ve still got visible tearing and shadow issues at the edges and now an – albeit minor – audio problem. Unity comes with a great method for playing audio at the correct volume based on the distance between the listener and the audio source. It’s built in! But all that goes out of the window with a looped level. ugh. For example; If the player (listener) is close to one edge of the map and an explosion happens at the opposite end of the map the built in method won’t play the sound (or play it very quietly) as the player and explosion appear – to Unity – to be far apart. Only they aren’t. In the looped view they are side by side.

To handle this I’ve had to write my own simple audio controller to adjust sounds that would be affected by the loop. Essentially any sound that needs it’s volume adjusted based on the perceived (not actual) distance from the player.

public void GroundExplosion(Vector3 position) {
    //Select a random explosion sound from an array of sound clips
    AudioClip boom = groundExplosions[Random.Range(0, groundExplosions.Length)];
    audioPlayer.PlayOneShot(boom, VolumeToPlay(position));
}

private float VolumeToPlay(Vector3 position) {
    //Get the distance on Z between the objects
    float distance = Mathf.Abs(player.transform.position.z - position.z);

    //Is the distance greater than the half length of the map?
    if (distance > (map.length / 2)) {

        //Remove the excess (i.e. get the excess above the half and remove from the Distance)
        distance = Mathf.Abs(distance - map.length);
    }
        
    //Return a value (Between 0 and 1) based on the max distance, closest distance, current distance)
    return Mathf.InverseLerp(map.length / 2, 0, distance);
}

My audio controller is handling quite a number of different sounds and I only need to worry about distance on the Z axis, but hopefully this is enough to show how it’s managing it. I wonder what “the loop” will throw at me next. Cheers, J

Blender

It’s been a while since my last update. Things on the game front have been moving along fairly nicely although building the models is rather more taxing than I thought it would be. My relationship with Blender is a bit of a love/hate thing. SO much seems counter intuitive but it’s clearly such a powerful tool that I’m going to do my best to move past my frustrations.

Game Progress

Obviously it’s still early days regarding the models so don’t be too harsh 😉 Follow the link below to see a rather large (30 Mb) gif of the progress so far.

Continue reading →

Arg… the loop

Getting the map to loop has been a massive pain. To be specific, instantly transporting the player from one end to the other is easy, it’s filling in the blanks at each end with a view from soon to be reached other end that is the problem. So far the best solution I’ve come up with is essentially having two extra cameras on either side of the main camera at a map length distance away so as the player reaches the end of the map the “chase” cam fills in the blanks. This required setting the camera objects clear flags to Depth only, and adjusting its depth.

Camera

This solution hasn’t been ideal as there is visible tearing at the edge of the map (plus problems with shadows and other rendering hassles) so I am trying to find something better as I continue on other aspects.

Unity Health Bar Slider

This took me way longer to discover than I thought it would. I’d implemented a UI Slider to display health (actually I’m using it as a fuel gauge but the principle remains the same) which worked fine but I wanted to change the colour as the players health/fuel reduced, and then flash if perilously low. Many of the examples I encountered online seemed overly complex for what I assumed should be a fairly easy and common task. I’m not sure why a simple solution – like the one below – isn’t more readily searchable (or perhaps my google-fu isn’t what it used to be)…

using UnityEngine;
using UnityEngine.UI;
using System.Collections;

public class PlayerHealth : MonoBehaviour {
    float maxHealth = 100;
    float currentHealth;
    Slider myHealth;

    void Start() {
        myHealth = GameObject.Find("MyHealthSlider").GetComponent<Slider>();
    }

    void Update() {
        if ((int)myHealth.value < 10) {
            myHealth.image.color = Color.Lerp(Color.red, Color.white, Mathf.PingPong(Time.time, 1f));
        }
        else {
            myHealth.image.color = Color.Lerp(Color.red, Color.green, currentHealth / maxHealth);
        }
    }

Hopefully this will save someone else time in the future 🙂
Cheers. J