CITIZEN – introduction

For the past 7 months I had been working on prototype of an isometric ARPG video game. It’s called CITIZEN, which used to be referred to as 3400AD in this blog. Of course, the game’s concept has evolved drastically since then.

I had completed the prototype about 3 weeks ago, and released an early video sampler of some of the gameplay. I feel that it’s yet to evolve further still, in style and in the narrative.

The prototype was completed in Construct 2, an HTML5 framework. I had originally intended to complete the game in Construct, but for many reasons, I decided to use Unity instead. After all my experimentation, I might as well take advantage of my acquaintance with it.

I had thought of writing my development notes on this blog, but I figured it would be hard to re-factor it for purposes of technical history and documentation, which is the primary role of my development notes. So I created a new Unity-specific development blog specifically for this project.

Unity: ScannerClass

ScannerClass in action. Robot is targeting the player; green line is where the robot is facing; the red line is the centre of the scan direction, and the blue line is an indicator that robot has a positive LOS on its target. Note that when player beyond maximum scan angle (ie red line is limited to a certain angle), LOS is still positive until it goes beyond the field-of-view of the scan direction.

This class was a functionality that I deferred when I was creating the robot’s ‘game’ class. Originally, I had simply used a Raycast to determine LOS; I knew a scanning behaviour was needed, so I coded the robot generically in that respect.

The ScannerClass is attached to a scanning object that is parented under the the robot’s root transform. The behaviour is that it scans around (oscillating pattern or full revolution) using the parent transform as its base direction. The class itself rotates the scanner game object for (my) convenience.

When the RobotGameClass asks ScannerClass for LOS to a specified target (usually the target that attacked it), the scanner will determine at that time if the target had been found; if so, it locks on to it. The RobotGameClass, meanwhile, instructs the RobotMovementClass to face and move towards target, making the the scanner face the target naturally. If the target gets lost out of sight, the lock is broken by the ScannerClass itself and it goes back to scanning, and based on the RobotGameClass AI, it will either reacquire or not.

What I learned from the coding the ScannerClass was more awareness of how rotations — expressed in Quaternions — and vectors are translated to and from each other. Because the scanner is controlled by a ‘scan angle’, which is a float, I needed to make a procedure to translate target vectors to Quaternion rotations to get to the Euler angles. It sounds a bit convoluted, but I think to keep the simplicity of the driving values, which is where the source of the confusion often is, the messy bit had be sorted out that way.