I had a similar thought as efge did, thinking on a way to create the heatmap in Unity. Here's what I came up with:
First I set up a script to store position data:
var positionTrackingFrequency : int = 2; // How often to store player position
private var timer : float = 0; // The timer
static var posArray : Vector2[]; // Local array storing player position
// debug vars
private var arrayIterator : int = -1;
function Update()
{
timer += 1 * Time.deltaTime;
if(timer >= positionTrackingFrequency)
{
storePos();
}
}
function storePos()
{
timer = 0;
var localArray : Array = new Array();
if(posArray != null)
localArray = new Array(posArray);
localArray.Push(Vector2(transform.position.x, transform.position.z) );
posArray = localArray.ToBuiltin(Vector2);
arrayIterator++;
Debug.Log(" " + posArray[arrayIterator] + " Iteration = " + arrayIterator);
}
Next on the agenda was to translate the data into a heatmap, so I duplicated the level, set up an orthographic camera and loaded all the positions using cubes as 'marks' for player position.
var heightToOverlay : int = 10;
var theHeat : GameObject;
static var finished : boolean = false;
function Start()
{
var pass : Vector2[] = storeHeatMapData.posArray;
// Debug.Log("" + pass.length);
readData(pass);
}
function readData(curArray : Vector2[])
{
for(iterator = 0; iterator < curArray.length; iterator++)
{
Instantiate(theHeat, Vector3(curArray[iterator].x, heightToOverlay, curArray[iterator].y), transform.rotation);
}
finished = true;
}
From here, my next step would be to write a script to cycle through the 'marks' of previous player locations and adjust their Red & Blue material values depending on how many neighbors are within a given radius (Creating the 'heat' for the map). After that, Application.CaptureScreenShot and a heatmap is (hopefully) saved. I didn't have time to write the actual code, but I figure this method could be scaled to allow for multiple playthroughs to be loaded into the heatmap creation level.
Edit : Wrote the code to color the cubes from cool (blue) to hot (red). Attach this to the prefab you're instantiating as the marks.
// The distance allowed to affect 'heat'
var allowableDistance : float = 5;
// How much to adjust the 'heat' by.
var colorAdjuster : float = .2;
// Creates a material from shader&texture references
var texture : Texture;
var color : Color;
// This stops the material from continuously altering color
private var thisCubeDone : boolean = false;
function Start ()
{
renderer.material = new Material (Shader.Find("Self-Illumin/Diffuse"));
renderer.material.mainTexture = texture;
renderer.material.color = color;
renderer.material.color = Color.blue;
}
function Update()
{
// Wait till map is finished loading to check nearby marks
if(readHeatMapData.finished && !thisCubeDone)
setColor();
}
function setColor()
{
var heatBoxes : GameObject[] = GameObject.FindGameObjectsWithTag("heatBox");
for(item in heatBoxes)
{
var distCheck = Vector2(item.transform.position.x, item.transform.position.z) -
Vector2(this.transform.position.x, this.transform.position.z);
dist = distCheck.sqrMagnitude;
Debug.Log("Distances " + dist);
if( dist <= allowableDistance )
{
// Here's where the color is actually adjusted.
// It starts blue (cool) by default and moves towards red (hot)
renderer.material.color.r += colorAdjuster;
renderer.material.color.b -= colorAdjuster;
}
}
thisCubeDone = true;
}
One last edit: If you were to add a blur effect to the marks (I think that camera effects are a Unity Pro feature only?) it would look much more like a traditional heat map. Here is what I was able to get after a few minutes of adjusting settings:
![screenshot][1]