2024-06-04

LifeTime 을 관리하고, 상태에 따라 함수를 호출한다.
private void Update()
{
if (lifeTime > 0)
lifeTime -= Time.deltaTime;
else
curState = State.Crashing;
switch (curState)
{
case State.Idle:
GoStraight(); break;
case State.Random:
HandleTurn(); break;
case State.Chasing:
GoToPlayer(); break;
case State.Crashing:
BeforeCrashing(); break;
}
}
자동차 오브젝트가 생성되고, 직진 방향으로 달린다.
private void GoStraight() // 그냥 직진 방향으로 달려
{
// 오브젝트의 진행 방향으로 힘 더해주기
rb.AddForce(transform.forward * IdleSpeed, ForceMode.Acceleration);
}
플레이어를 감지하여, 확률에 따라 Random 이나 Chasing 상태로 변환
private void OnTriggerEnter(Collider other)
{
if (curState != State.Idle)
return;
if (other.gameObject.layer == LayerMask.NameToLayer("Player"))
{
if (Random.Range(0f, 1f) < percent)
{
// y축 기준, -fov' ~ fov' 회전
float randomAngle = Random.Range(-fov, fov);
// 쿼터니언으로 변환 후, 목표 진행 방향을 계산
targetV = Quaternion.Euler(0f, randomAngle, 0f) * transform.forward;
targetV = targetV.normalized;
// 목표 회전 방향을 계산
targetRot = Quaternion.LookRotation(targetV, transform.up);
curState = State.Random;
}
else
curState = State.Chasing;
}
}
OnTriggerEnter 에서 설정한 랜덤 방향을 향해 달린다.
private void HandleTurn() // 캐릭터를 찾으면, 핸들 꺾어서 달려~
{
if (curState != State.Random)
return;
curV = transform.forward;
curRot = transform.rotation;
if (curV != targetV)
curV = Vector3.Lerp(curV, targetV, acc1 * Time.deltaTime);
if (curRot != targetRot)
curRot = Quaternion.Lerp(curRot, targetRot, acc1 * Time.deltaTime);
curV.y = 0.0f;
transform.rotation = curRot;
rb.AddForce(curV * walkSpeed, ForceMode.Acceleration);
}
플레이어 방향을 계속 추적하여, 해당 방향으로 자동차가 움직인다.
private void GoToPlayer() // 플레이어 방향으로 달려
{
if (curState != State.Chasing)
return;
Vector3 playerPos = Player.transform.position;
Vector3 carPos = transform.position;
// 자동차 -> 플레이어 방향 벡터 계산
targetV = (playerPos - carPos).normalized;
dirV = targetV - curV;
// 목표 회전 방향 계산
targetRot = Quaternion.LookRotation(targetV, transform.up);
// 현재 자동차의 방향과 회전
curV = transform.forward;
curRot = transform.rotation;
if (curV != targetV)
curV = Vector3.Lerp(curV, dirV, acc2 * Time.deltaTime);
if (curRot != targetRot)
curRot = Quaternion.Lerp(curRot, targetRot, acc2 * Time.deltaTime);
curV.y = 0.0f;
transform.rotation = curRot;
rb.AddForce(curV * runSpeed, ForceMode.Acceleration);
}
Random 상태 - 차량이 무작위 방향으로 돌진
Chasing 상태 - 플레이어를 따라가는 상태
플레이어가 차량과 충돌했을 때, 플레이어가 날아가는 충돌 작용이 일어나지 않는다.
해당 부분을 수정하고, 새로 알게된 레그돌 이라는 시스템을 도입하면
플레이어가 충돌했을 때 더 자연스러운 연출이 될 것 같다.