Random Class, Singletons, and the “Big Debate”™ (does this sound familiar?)

A few weeks ago I wrote a VERY similar post about my Logger class and the debate over the use of Singletons.

I’ve done the same with my new randomization class, LRandom().  LRandom does several things under the hood, and is a singleton for a very specific reason.  First, I wanted to use it to replace the random class that Dungeon Architect uses during initialization of a dungeon or map.  In part because I wanted more control over randomization, and in part because I wanted all aspects to produce the same values with the same seed.  Previously, at least in earlier versions, DA would produce the same dungeon layout, but things like decorations and extras would not always be the same.

Additionally, I wanted the same random class to be able to control other randomizations during play: loot, die rolls, et cetera.  The current implementation uses a single System.Random instance, though I may extend this to have several – one for dungeon building, one for loot, one for mob AI, and so forth.

Also, the state of the System.Random is stored in a serialized file on exit.  This should, in theory and after a lot more work, allow one to pick up where they left off with the state of the randomizer where it was before.  The main goal here is to prevent “known randoms” with the given seed.  The first chest you run across won’t always have the same stuff.

The class also contains the original DA methods for NextGaussianFloat() and GetNextUniformFloat() to integrate without changing a lot of the DA code.  And lastly, it contains methods that allow the instance to be reseeded if need be, which is mostly good for debugging, but may have benefits during runtime as well.

So, currently, LRandom() and LLogger() are two singletons that I’m using that have proven very beneficial.  If you missed my last post, or want to hear more about Singletons (the good, the bad, and the ugly, so to speak), check out this great podcast from The Debug Log- Episode 73: Design Patterns: Singleton.

How To See Your Player… Making Walls Transparent

Over the past several months working on the Dungeon theme for Labyrintheer, I’ve changed my camera angle several times.  I keep moving it higher to prevent walls and such from occluding the player, but I’m never happy with such an oblique view.  So, over the past few days I’ve been looking at options to make walls transparent when they are between the player and the camera.

Some solutions simply disable the geometry.  This isn’t acceptable for my game, and I suspect for many.  You could accidentally walk backwards out of the playable area, or an errant AI could take a bad turn during it’s pathing and fall off the world.  Plus, disabling geometry just doesn’t seem like an elegant solution.  My primary goal (and I’m still working on it) is to use a shader for this directly, though that seems like it has some major pitfalls (how do you tell a shader about an object other than the one that it’s drawing?).

So, for now I’m cheating with a very small amount of code and an extra material for objects that I want to hide.

Basically, I’ve duplicated the four wall materials I have, and the duplicate materials use transparency with an alpha value of 100.

My player controller script now calculates it’s distance from the camera every frame (though I think this might be able to be done once in Awake() since the distance should be fairly static), like this:

     void Update ()
         distanceSquared = (transform.position - Camera.main.transform.position).sqrMagnitude;
     public float Dist()
         return distanceSquared

Then created a script to go on the walls (or any object that needs to be transparent to prevent occlusion), as such:


 using UnityEngine;
 public class TransMaterialSwap : MonoBehaviour {
     public Material _original;
     public Material _transparent;
     private GameObject player;
     private playerController pC;
     private Renderer rend;
     void Start()
         player = GameObject.FindWithTag("Player");
         pC = player.GetComponent<playerController>();
         rend = this.GetComponent<Renderer>();
     void Update()
         if ((transform.position - Camera.main.transform.position).sqrMagnitude < pC.Dist())
             rend.material = _transparent;
             rend.material = _original;

In the inspector I set both the original material and the transparent material.  If the object is between the camera and the player, it switches the object’s material to the transparent material.  It looks like this:

There are a few issues here.  First, I still need to profile this to see if the solution gives my runtime performance a hit.  I don’t suspect it’ll be TOO bad, but it doesn’t hurt to check, especially with larger maps.  I may look into options to only run the check if the object is visible to the camera rather than always checking on Update(), every frame for every wall.  The other issue is that by making it transparent, light comes through.  I’m not sure how big an issue this will be – it’ll require some play testing.  But it may be an issue in some situations.

Lastly, as I said, I really do want to attempt this in a shader.  I figure it’s a good method to learn shader programming, even if exactly what I want isn’t possible.