301 Days (redux)

Another metric leap year of gamedev experiments and such

Sep 9, 2015 - OldDays ste-reez-muvi

Day 11 - Keeping an Eye on the NPCs

Finding something interesting to look at, part 1…


“Ok, we’re watching”

Witness me!

I keep going completely off the rails with this camera controller, unable to navigate back to seeing any of the map, let alone something interesting. Let’s do something about that:

Managers/GUIManager.cs GitLab
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
void Update () {
    if (Input.GetKeyDown (KeyCode.Z)) {
        map_manager.CycleZ(false);
    }
    if (Input.GetKeyDown (KeyCode.A)) {
        map_manager.CycleZ(true);
    }
    if (Input.GetKeyDown (KeyCode.Space)) {
        mainCamera.ReturnToHome();
    }
    if (Input.GetKeyDown (KeyCode.N)) {
        Vector3 randomNpcCoords = map_manager.locateRandomNpc();
        mainCamera.lookAtNpc(randomNpcCoords);
    }
}

So now Space will return the camera to its original position, and N will make us look at a random NPC? To do that, we’ll need to save (and be able to restore) the initial camera settings:

CameraControlScript.cs GitLab
14
15
16
17
18
19
20
21
22
23
24
Vector3 originalPosition; Quaternion originalRotation;

void Start() {
    originalPosition = transform.position;
    originalRotation = transform.rotation;
}
 
public void ReturnToHome() {
    transform.position = originalPosition;
    transform.rotation = originalRotation;
}
And have a way to look at a particular map cell:
CameraControlScript.cs GitLab
95
96
97
98
public void lookAtNpc(Vector3 npcCoords) {
    transform.position = new Vector3((-1f) * npcCoords.x, (-1f) * npcCoords.y, (0.1f * npcCoords.z) + 15f);
    transform.LookAt(new Vector3((-1f) * npcCoords.x, (-1f) * npcCoords.y, npcCoords.z));
}
So now we can move the camera to 15 units above a cell, looking down. How do we grab a random NPC at which to look?
Managers/MapManager.cs GitLab
310
311
312
313
314
315
316
System.Random myRandom = new System.Random();

public Vector3 locateRandomNpc() {
    if (cellsContainingNpcs.Count == 0) return Vector3.zero;
    List<Vector3> cells = new List<Vector3>(cellsContainingNpcs.Keys);
    return cells[myRandom.Next(cells.Count)];
}
We need a System.Random because we want integers, and UnityEngine.Random will only give us floats.

Demonstration

Hitting Space:

Space takes us back Space takes us back

Hitting N:

Next, next, next.. but where is that one? Next, next, next.. but where is that one?

Yes, I added in a few more of the common surface NPC types. But sometimes we’re not seeing the NPC that we’re centered on; what’s up with that?

Oops

If we switch to an NPC that’s underground, we don’t see it unless we’ve manually disappeared the map layers above it. That won’t do. We need to be more dynamic in updating the Z-layer filter. We’ll split it out into a method we can call with an arbitrary Z, and keep track of that as well:

Managers/MapManager.cs GitLab
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
public void UpdateZ(float z) {
    Renderer currBlockRend;
    foreach (Vector3 v in cell_transforms.Keys) {
        currBlockRend = cell_transforms[v].GetComponent<Renderer>();
        if (v.z > z) {
            currBlockRend.enabled = false;
        } else {
            currBlockRend.enabled = true;
        }
    }
    zTop = z;
}

public void CycleZ(bool up) {
    currentZTopIdx += (up ? 1 : -1);
    if (currentZTopIdx < 0) currentZTopIdx = 0;
    if (currentZTopIdx >= zPlanes.Length) currentZTopIdx = zPlanes.Length - 1;
    UpdateZ(zPlanes[currentZTopIdx]);
}
We’ll call that method directly when we look at a new NPC, and display the actual top Z variable:
Managers/GUIManager.cs GitLab
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    if (Input.GetKeyDown (KeyCode.N)) {
        Vector3 randomNpcCoords = map_manager.locateRandomNpc();
        mainCamera.lookAtNpc(randomNpcCoords);
        map_manager.UpdateZ(randomNpcCoords.z + 1f);
    }
}
        
void OnGUI(){
    GUI.Box (new Rect (0,0,100,50), "# of cells\n" + map_manager.num_cells);
    GUI.Box (new Rect (Screen.width - 100,0,100,50), "# of blocks\n" + map_manager.num_blocks);
    GUI.Box (new Rect (0,Screen.height - 50,100,50), "Z top\n" + map_manager.zTop);
    StringBuilder builder = new StringBuilder();
    foreach (int gameRound in map_manager.activeGameRounds)
        builder.Append(gameRound).Append(" ");
    GUI.Box (new Rect (Screen.width - 100,Screen.height - 50,100,50), "Game Round\n" + builder.ToString());
}

Better?

Now we see them all. Now we see them all.

Yep. And yet:

What are those guys doing there? What are those guys doing there?

Something to fix tomorrow.


Day 11 code - client