[오늘 한 일]
보스1 패턴 로직 구현 완료
보스2 움직임까지 구현 완료
public class LookBoss : MonoBehaviour
{
[Header("look")]
public Transform target; //플레이어
public float LookSpeed = 5f;
public void LookTarget()
{
//바라보는 방향만 가져오기
Vector3 targetDirection = (target.position - transform.position).normalized;
//바라볼 방향을 쿼터니온 변수에 저장 (Lerp을 사용하기 위해서 쿼터니온 변수 쓰는것도 있음)
Quaternion SetRotation = Quaternion.LookRotation(targetDirection);
transform.rotation = Quaternion.Lerp(transform.rotation, SetRotation, LookSpeed * Time.deltaTime);
}
}
보스1, 보스2 둘다 플레이어를 따라 바라보기 때문에 위의 로직은 상속을 줄 예정이다.
Lerp를 이용해 플레이어를 바라보는 딜레이를 줌
로직 - 지정된 타겟포지션으로 이동후 타겟 포지션에 도착하면 n갈래로 일정한 각도를 가지고 공격하는 로직
타겟 포스로 이동하는 로직은 딜레이를 주며 타겟포지션을 지정해야하기 때문에 코루틴을 반복문을 사용하여 구현
IEnumerator Move()
{
while(true)
{
yield return new WaitForFixedUpdate();
Vector3 targetPosition = targetPos[_index].transform.position;
targetPosition.y = transform.position.y;
Vector3 direction = (targetPosition - transform.position).normalized;
//Vector3.Distance는 두점사이의 거리를 나타내는 메소드
float distance = Vector3.Distance(transform.position, targetPos[_index].transform.position);
if (distance < 0.5f)
{
transform.position = new Vector3(targetPos[_index].position.x, transform.position.y, targetPos[_index].position.z);
_index++;
ProjectileManager.instance.AttackProjectiles(data,gameObject);
if (_index >= targetPos.Length)
{
_index = 0;
}
yield return new WaitForSeconds(1.3f);
}
else
{
transform.Translate(direction * speed * Time.deltaTime, Space.World);
}
}
}
이후에 시간이 남으면 오브젝트 pool의 가능성을 염두해두고 ProjectileManager에서 공격 생성을 관리한다.
public void AttackProjectiles(AttackSO attackData, GameObject cur)
{
Vector3 directionTarget = (attackData.targetTransform.position - cur.transform.position).normalized;
int numProjectiles = Random.Range(attackData.minProjectiles, attackData.maxProjectiles + 1);
for (int i = 0; i < numProjectiles; i++)
{
// 현재 공격의 각도 계산
float projectileAngle = attackData.angleBetweenProjectiles * (i - (numProjectiles - 1) / 2f);
//Quaternion.AngleAxis는 주어진 백터만큼 회전하는 메소드
//Vector3.up은 y축을 기준으로 회전하라는 뜻
Quaternion rotation = Quaternion.AngleAxis(projectileAngle, Vector3.up);
//쿼터니언 회전값과 타겟을바라보는 방향을 곱하기
Vector3 projectileDirection = rotation * directionTarget;
GameObject projectile = Instantiate(attackData.AttackPrefab, cur.transform.position, Quaternion.identity);
projectile.transform.position = new Vector3(cur.transform.position.x, attackData.targetTransform.position.y,
cur.transform.position.z);
projectile.transform.parent = attackPrefebParent.transform;
projectile.transform.rotation = Quaternion.LookRotation(projectileDirection);
}
}
그리고 생성한 오브젝트 내 스크립트에서 바라보는 방향으로 이동시킨다.
void Update()
{
_currentDuration -= Time.deltaTime;
if(_currentDuration<=0)
{
_currentDuration = 0;
//시간남으면 오브젝트 pool할 예정
Destroy(gameObject);
}
_rigidbody.velocity = transform.forward * data.speed;
}
보스2 또한 LookBoss 클래스를 상속받는다.
보스가 바라보는 반대방향으로 뛰되, x,z 값에 약간의 변수값을 +해줘 동적인 움직임을 방지하였다.
또한 일정이상 거리가 멀어지면 보스가 바라보는 방향으로 뛰게끔 구현하였다.
void Jump()
{
Vector3 minusForward = SetForward();
_rigidbody.AddForce(minusForward, ForceMode.Impulse);
_rigidbody.AddForce(Vector3.up * moveForce, ForceMode.Impulse);
}
Vector3 SetForward()
{
//약간의 랜덤값 주기위한 처리
float randomX = Random.Range(-1f, 1f);
float randomZ = Random.Range(-1f, 1f);
Vector3 randomSet = new Vector3(randomX, 0f, randomZ);
float distance = Vector3.Distance(transform.position, target.transform.position);
if (distance > targetDistanse)
{
return (transform.forward + randomSet).normalized * moveForce;
}
else
{
return (-transform.forward + randomSet).normalized * moveForce;
}
}
문제: 보스를 움직일때 이동하는 거리에서 차이가 생김.
랜덤값을 준것이 원인이라고 판단하여
Vector3 randomSet = new Vector3(randomX, 0f, randomZ).normalized; 하였으나, 해결되지 않았다.
원인:
forward
방향을 나타내는 것인데, 이것을 정확하게 이해 못한 문제이다.
(transform.forward + randomSet) * moveForce;
방향에서 랜덤으로 +1에 가깝게 나올때 이동하는 거리가 커지는 것이었다. transform.forward + randomSet까지가 방향 세팅이었는데, 랜덤값만 nomalized해봤자 의미가 없었다.
해결:
return (transform.forward + randomSet).normalized * moveForce;
따라서 위와같이 문제 해결