using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/* This class moves the camera part of the security camera model
* so that it stays pointed at the little car as it races around.
* Note that it will only follow the car when the car is visible,
* i.e. not behind a block.
*
* There is some complicated rotation code, but all you need to
* understand is the raycasting that is happening in FixedUpdate.
*/
public class SecurityCamera : MonoBehaviour
{
[SerializeField]
GameObject car;
[SerializeField]
float watchDistance;
//note that I don't need a layer mask here
//because the camera doesn't have a collider
Transform swivel;
Vector3 directionToTarget;
void Start()
{
swivel = transform.Find("Camera/Swivel");
//The camera model has two parts: the boxy camera
//itself, and the structure that attaches it to
//the wall.
//I want the camera part to look back and forth
//and the wall mount to stay in place.
}
void FixedUpdate()
{
directionToTarget = car.transform.position - transform.position;
Debug.DrawRay(
transform.position,
directionToTarget.normalized * watchDistance,
Color.red
);
RaycastHit rHit;
//3D raycasts are weird because they use an "out"
//parameter instead of just returning a value like
//a normal method. This is both uncommon and frowned-upon.
//You're unlikely to see it anywhere else in Unity.
Physics.Raycast(
transform.position,
directionToTarget,
out rHit,
watchDistance
);
if (rHit.collider != null)
{
Debug.Log("Ray hit " + rHit.collider.name);
//transform.root means "look all the way up the
//hierarchy from this object until you find the
//one that has no parent". In this case, traveling
//up from the individual collider, like FrontRightWheel,
//to SciFiCar_Prefab, to Car
if (rHit.collider.transform.root.tag == "Car")
{
swivel.LookAt(car.transform.position);
//This line tells the camera model to line up its
//personal "forward" to point at the car. But it
//doesn't quite work. Its parent GO SecurityCamera
//is rotated by 90 degrees, so all of its children are
//also rotated by 90 degrees. LookAt doesn't account
//for this.
swivel.rotation *= Quaternion.Inverse(transform.rotation);
//So this line "undoes" (offsets) the SecurityCamera
//GameObject's rotation. Comment out the line to
//see what it's doing.
//Also, be aware that this is pretty advanced! It took
//me a few tries to find a solution. But it's a useful
//technique, as well as an illustration of how rotation
//gets complicated quickly.
//Credit to
//https://answers.unity.com/questions/950010/offset-lookat-rotation.html
}
}
}
}