An application to assist firefighters in specific car collision cases by streamlining their communication and visual cues between each team member developed for Drenthe Fire Department.
A second block project, an application made for Drenthe Fire Department to help them reduce the time needed for succesfull evacuation of people from a car crash.
Application
Touch Screen Tablet/Phone
Unity
As an only programmer I was responsible for 100% of the game's code. I used C# to code main game systems: 3DViewController, DrawingViewController, NetworkManagerController.
/// <summary>
/// Coroutine DrawLine is used to facilitate drawing of the line.
/// </summary>
IEnumerator DrawLine()
{
newLine = Instantiate(linePrefab, drawOffset, viewCamPivot.rotation);
lineRenderComp = newLine.GetComponent<LineRenderer>();
lineRenderComp.positionCount = 0;
// Do not kill me this is needed cause the drawing is controlled by stopping the coroutine
while (true)
{
Vector3 position = viewCam.ScreenToWorldPoint(currentTouch.position);
lineRenderComp.positionCount++;
position -= drawOffset * 0.1f;
lineRenderComp.SetPosition(lineRenderComp.positionCount-1, position);
yield return null;
}
}
/// <summary>
/// Method FinalizeLineHit is used to finalize the drawing by casting a ray forward from the position of renderer.
/// </summary>
void FinalizeLineHit()
{
RaycastHit hit;
if (Physics.Raycast(lineRenderComp.bounds.center, newLine.transform.forward, out hit, Mathf.Infinity))
{
Debug.DrawRay(lineRenderComp.bounds.center, newLine.transform.forward * 1000, Color.yellow, duration:500);
if (hit.transform.gameObject.tag == "CarPart")
{
_networkManagerController.allSigns.Add(hit.collider.gameObject.GetComponentInParent<CarSignManager>()
.PlaceSignAtLocation(hit.point, stateController.ActiveCarId, _signId));
}
}
Destroy(newLine);
}
The Drawing Controller uses a coroutine to create a temporary drawing plane in front of the camera to draw any shape in front of it.
After the drawing is finished it casts a ray from the middle point of the drawing to apply a sign at that location on the car model.
The whole app is coded in a state based design, one of the states is 3D view controller that creates the ability for the person to span around the car.
Player can also snap to the specific side of the car using buttons at the bottom right of the screen.
/// <summary>
/// Method DetectInput registers if only one finger is touching the screen and records the begin, stationary and moved positions.
/// </summary>
private void DetectInput()
{
if (inputManager.IsTouchApplied())
{
Touch currentTouch = inputManager.GetTouch();
TouchPhase currentTouchPhase = currentTouch.phase;
if (currentTouchPhase == TouchPhase.Began || currentTouchPhase == TouchPhase.Stationary) {
_touchBeginPosition = currentTouch.position;
_touchMovedPosition = currentTouch.position;
}
if (currentTouchPhase == TouchPhase.Moved) {
_touchMovedPosition = currentTouch.position;
}
if (currentTouchPhase == TouchPhase.Ended)
{
_touchBeginPosition = Vector2.zero;
_touchMovedPosition = Vector2.zero;
}
_inputDrivenRotation = true;
}
_inputDrivenRotation = false;
}
/// <summary>
/// Method RotateCamera rotates camera pivot point around the target. Deadzones are implemented to safeguard from excessive rotation.
/// </summary>
private void RotateCamera()
{
Vector2 touchMoveDir = _touchBeginPosition - _touchMovedPosition;
var rotCheckVal = _pivotRotationY + touchMoveDir.y * cameraSpeedMultiplier;
if (rotCheckVal is >= -20 and <= 20)
{
_pivotRotationY += touchMoveDir.y * cameraSpeedMultiplier;
}
if (touchMoveDir.x is <= -1 or >= 1)
{
_pivotRotationX += touchMoveDir.x * cameraSpeedMultiplier;
}
if (_inputDrivenRotation)
{
cameraPivot.transform.rotation = Quaternion.Euler(-_pivotRotationY, -_pivotRotationX, 0);
}
else
{
cameraPivot.transform.rotation = Quaternion.Lerp(cameraPivot.transform.rotation, Quaternion.Euler(_pivotRotationY, _pivotRotationX, 0), lerpValue);
lerpValue += Time.deltaTime;
}
}
Created the shader for the frame of the car.