(1) 총구가 Player를 향하도록 조준하는 부분
*Enemy1가 실시간으로 Player를 향해 LookAt을 하는 방식으로 구현
TestEnemy1Main.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestEnemy1Main : MonoBehaviour
{
[SerializeField]
private Enemy1 enemy1;
[SerializeField]
private Transform Player;
void Update()
{
this.enemy1.AimPlayer(this.Player);
}
}
Enemy1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Enemy1 : MonoBehaviour
{
public void AimPlayer(Transform player)
{
this.transform.LookAt(player);
}
}

조준은 되지만 움직임과 동시에 조준이 되고 있는 상황. Player의 움직임보다 늦게 조준이 되도록 수정한다.
응,,,무리,,,,,,,,,
처음 시도 : coroutine을 돌려 Player보다 느리게 움직이도록 하기 => Enemy1이 안움직이는 상황 발생(coroutine이 돌아가지고 않음)
두번째 시도 : Invoke를 사용하여 Enemy1이 좀 더 늦게 조준하도록 하기 => 늦게 돌리나 조준이 매끄럽게 이루어지지 않음.
결국 시도해봐야 되는 부분 => player의 위치값을 받고 slerp을 사용하여 직접 enemy1을 rotation하기.
우선 디테일한 부분은 좀 때려치우고(?) 빨리 다음 구현으로 넘어가쟈ㄱㄱ
(2) 총알 발사


1) 4초마다 3번씩 발사
- Main.cs에서 coolTime을 관리하도록 하여 4초가 경과될 때마다 enemy1에게 player를 공격하도록 지시한다.
- Coroutine을 사용하여 enemy1이 약간의 시간 간격을 두고 총알을 발사하도록 한다.
- coolTime은 enemy1이 총알을 다 발사하고 난 뒤에 돌아야 하므로 대리자를 사용하여 enemy1이 Main에게 공격이 끝났음을 알려주도록 한다.
TestEnemy1Main.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestEnemy1Main : MonoBehaviour
{
[SerializeField]
private Enemy1 enemy1;
[SerializeField]
private Transform player;
private float coolTime = 4f;
private float elapsedTime;
private bool isAttack;
void Start()
{
//enemy1이 공격이 끝났음을 알림.
this.enemy1.onCompleteAttack = () =>
{
Debug.Log("Attack Complete");
this.isAttack = false; //공격상태 아님을 나타냄.
};
}
// Update is called once per frame
void Update()
{
this.enemy1.AimTarget(this.player);
//공격중이 아닐 경우 elapsedTime 추가
if (!this.isAttack)
this.elapsedTime += Time.deltaTime;
//쿨타임이 다 찼을 경우 공격.
if(this.elapsedTime >= this.coolTime)
{
this.enemy1.AttackPlayer();
this.isAttack = true;
this.elapsedTime = 0;
}
}
}
Enemy1.cs
using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;
public class Enemy1 : MonoBehaviour
{
[SerializeField]
private Transform muzzleTrans;
private int attackCount = 3; //최대 공격 횟수
private float dealLossTime = 0.4f; //공격 빈도
public System.Action onCompleteAttack;
public void AimTarget(Transform target)
{
this.transform.LookAt(target);
}
//player 공격 method
public void AttackPlayer()
{
StartCoroutine(this.CoAttackPlayer());
}
//dealLossTime에 맞춰 player를 공격하는 method
private IEnumerator CoAttackPlayer()
{
for(int i = 0; i < this.attackCount; i++)
{
BulletGenerator.Instance.GenerateBullet(this.muzzleTrans);
yield return new WaitForSeconds(this.dealLossTime);
}
this.onCompleteAttack(); //공격이 완료되면 대리자를 사용하여 TestEnemy1Main.cs에게 공격 완료를 알림.
}
}
BulletGenerator.cs

Hierarchy

결과

2) BulletGenerator에서 실제 총알을 생성하여 발사
- 총알이 player를 향해 가속을 받으며 날아옴
- player보다 position.z값이 더 낮아지거나 player와 충돌할시 총알은 사라짐(player와 충돌시는 아직 구현하지 못함)
BulletGenerator.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SJY
{
public class BulletGenerator : MonoBehaviour
{
public static BulletGenerator Instance;
[SerializeField]
private GameObject bulletPrefab;
private void Awake()
{
Instance = this;
}
public void GenerateBullet(Transform parent)
{
GameObject bulletGo = Instantiate(bulletPrefab, parent);
bulletGo.transform.SetParent(null);
}
}
}


총구 위치로 총알을 생성
Bullet.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace SJY
{
public class Bullet : MonoBehaviour
{
private Transform target;
private Rigidbody rBody;
public float maxSpeed = 10f;
public float moveForce = 2.0f;
// Start is called before the first frame update
void Start()
{
this.target = GameObject.Find("CenterEyeAnchor").transform;
this.rBody = this.GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update()
{
//player 방향으로 총알에 AddForce
this.transform.LookAt(this.target);
this.rBody.AddForce(this.transform.forward * this.moveForce, ForceMode.Acceleration);
//총알 속도 조절
if(this.rBody.velocity.magnitude > this.maxSpeed)
{
this.rBody.velocity = this.rBody.velocity.normalized * this.maxSpeed;
}
//총알이 player보다 뒤로 갈 시 destroy
if(this.transform.position.z<=this.target.position.z)
{
Destroy(this.gameObject);
}
}
}
}
'K-digital traning > Final Project' 카테고리의 다른 글
Gazzlers 개발일지 - Map생성(3) (0) | 2023.11.22 |
---|---|
Gazzlers 개발일지 - Map 생성(2) (1) | 2023.11.21 |
Gazzlers 개발일지 - Map 생성 (0) | 2023.11.09 |
Gazzlers 개발일지 - Enemy1 GetHit 구현(1) (0) | 2023.11.07 |
Gazzlers 개발일지 - R&D 목록 (2) | 2023.11.03 |