✍ 따라다니는 보조무기 만들기
- power를 최대치 이상 획득하면 활성화시키도록 구현
알아두어야 할 것
- 유니티에서 Queue에 데이터를 입력할 땐 Enqueue()를, 데이터를 뺄 때는 Dequeue()를 사용
- 큐의 개수는 Count
- Contains() -> ()안의 내용이 큐에 들어있으면 true 반환
팔로우 로직
- 첫번째 팔로우는 player를 따라가고 n번째 팔로우는 n-1번째 팔로우를 따라감.
- 나머지 로직은 플레이어와 같다.
수정된 코드
1. Follower.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Follower : MonoBehaviour
{
public float curShotDelay;
public float maxShotDelay;
public ObjectManager objectManager;
public Vector3 followPos;
public int followDelay;
public Transform parent;
public Queue<Vector3> parentPos;
private void Awake()
{
parentPos = new Queue<Vector3>();
}
void Update()
{
Watch();
Follow();
Fire();
Reload();
}
void Reload()
{
curShotDelay += Time.deltaTime;
}
void Fire()
{
if (!Input.GetButton("Fire1"))
return;
if (curShotDelay < maxShotDelay)
return;
GameObject bullet = objectManager.MakeObj("followerBullet");
bullet.transform.position = transform.position;
Rigidbody2D rigid = bullet.GetComponent<Rigidbody2D>();
rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
curShotDelay = 0;
}
void Watch()
{
//#. Input Pos
if (parentPos.Contains(parent.position))
return;
parentPos.Enqueue(parent.position);
//#. Output Pos
if (parentPos.Count > followDelay)
followPos = parentPos.Dequeue();
else if (parentPos.Count < followDelay)
followPos = parent.position;
}
void Follow()
{
transform.position = followPos;
}
}
2. Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour
{
public bool isTouchTop;
public bool isTouchBottom;
public bool isTouchLeft;
public bool isTouchRight;
public int score;
public int health;
public float speed;
public int boom;
public int maxBoom;
public int power;
public int maxPower;
public float curShotDelay;
public float maxShotDelay;
public bool isHit;
public bool isBoom;
public GameObject[] followers;
public ObjectManager objectManager;
public GameObject boomEffect;
public GameManager gameManager;
/* public GameObject BulletA;
public GameObject BulletB;
*/
Animator anim;
private void Awake()
{
anim = GetComponent<Animator>();
}
// Update is called once per frame
void Update()
{
Move();
Fire();
Reload();
Boom();
}
void Boom()
{
if (!Input.GetButton("Fire2"))
return;
if (isBoom)
return;
if (boom == 0)
return;
boom--;
isBoom = true;
gameManager.UpdateBoom(boom);
//#1. Effect visible
boomEffect.SetActive(true);
Invoke("OffBoomEffect", 3f);
//#2. Remove Enemy
GameObject[] enemiesL = objectManager.GetPool("EnemyL");
GameObject[] enemiesM = objectManager.GetPool("EnemyM");
GameObject[] enemiesS = objectManager.GetPool("EnemyS");
for (int i = 0; i < enemiesL.Length; i++)
{
if (enemiesL[i].activeSelf)
{
Enemy enemyLogic = enemiesL[i].GetComponent<Enemy>();
enemyLogic.onDamaged(1000);
}
}
for (int i = 0; i < enemiesM.Length; i++)
{
if (enemiesM[i].activeSelf)
{
Enemy enemyLogic = enemiesM[i].GetComponent<Enemy>();
enemyLogic.onDamaged(1000);
}
}
for (int i = 0; i < enemiesS.Length; i++)
{
if (enemiesS[i].activeSelf)
{
Enemy enemyLogic = enemiesS[i].GetComponent<Enemy>();
enemyLogic.onDamaged(1000);
}
}
//#3. Remove Enemy Bullet
GameObject[] bulletsA = objectManager.GetPool("EnemyBulletA");
GameObject[] bulletsB = objectManager.GetPool("EnemyBulletB");
for (int i = 0; i < bulletsA.Length; i++)
if(bulletsA[i].activeSelf)
bulletsA[i].SetActive(false);
for (int i = 0; i < bulletsB.Length; i++)
if (bulletsB[i].activeSelf)
bulletsB[i].SetActive(false);
}
void Reload()
{
curShotDelay += Time.deltaTime;
}
void Fire()
{
if (!Input.GetButton("Fire1")) // Fire1은 마우스좌클릭
return;
if (curShotDelay < maxShotDelay)
return;
switch(power)
{
case 1:
// Power 1
GameObject Bullet = objectManager.MakeObj("PlayerBulletA");
Bullet.transform.position = transform.position;
Rigidbody2D rigid = Bullet.GetComponent<Rigidbody2D>();
rigid.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
case 2:
// Power 2
GameObject BulletR = objectManager.MakeObj("PlayerBulletA");
GameObject BulletL = objectManager.MakeObj("PlayerBulletA");
BulletR.transform.position = transform.position + Vector3.right * 0.1f;
BulletL.transform.position = transform.position + Vector3.left * 0.1f;
Rigidbody2D rigidR = BulletR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidL = BulletL.GetComponent<Rigidbody2D>();
rigidR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
default:
// Power 3
GameObject BulletRR = objectManager.MakeObj("PlayerBulletA");
GameObject BulletCC = objectManager.MakeObj("PlayerBulletB");
GameObject BulletLL = objectManager.MakeObj("PlayerBulletA");
BulletRR.transform.position = transform.position + Vector3.right * 0.35f;
BulletCC.transform.position = transform.position;
BulletLL.transform.position = transform.position + Vector3.left * 0.35f;
Rigidbody2D rigidRR = BulletRR.GetComponent<Rigidbody2D>();
Rigidbody2D rigidCC = BulletCC.GetComponent<Rigidbody2D>();
Rigidbody2D rigidLL = BulletLL.GetComponent<Rigidbody2D>();
rigidRR.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidCC.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
rigidLL.AddForce(Vector2.up * 10, ForceMode2D.Impulse);
break;
}
curShotDelay = 0;
}
void Move()
{
float h = Input.GetAxisRaw("Horizontal");
if ((isTouchRight && h == 1) || (isTouchLeft && h == -1))
h = 0;
float v = Input.GetAxisRaw("Vertical");
if ((isTouchTop && v == 1) || (isTouchBottom && v == -1))
v = 0;
Vector3 curPos = transform.position;
Vector3 nextPos = new Vector3(h, v, 0) * speed * Time.deltaTime;
transform.position = curPos + nextPos;
// Animation
if (Input.GetButtonUp("Horizontal") || Input.GetButtonDown("Horizontal"))
{
anim.SetInteger("Input", (int)h);
}
}
public void OnTriggerEnter2D(Collider2D collision)
{
if(collision.gameObject.tag == "Border")
{
switch(collision.gameObject.name)
{
case "Top":
isTouchTop = true;
break;
case "Bottom":
isTouchBottom = true;
break;
case "Left":
isTouchLeft = true;
break;
case "Right":
isTouchRight = true;
break;
}
}
else if(collision.gameObject.tag == "Enemy" || (collision.gameObject.tag == "EnemyBullet"))
{
if (isHit)
return;
isHit = true;
health--;
gameManager.UpdateLife(health);
if (health == 0)
gameManager.GameOver();
else
gameManager.RespawnPlayer();
gameObject.SetActive(false);
collision.gameObject.SetActive(false);
}
else if(collision.gameObject.tag == "Item")
{
Item item = collision.gameObject.GetComponent<Item>();
string itemtype = item.type;
switch(itemtype)
{
case "Coin":
score += 1000;
break;
case "Power":
if (power == maxPower)
score += 500;
else
{
power++;
AddFollower();
}
break;
case "Boom":
if (boom == maxBoom)
score += 500;
else
{
boom++;
gameManager.UpdateBoom(boom);
}
break;
}
collision.gameObject.SetActive(false);
}
}
void AddFollower()
{
if (power == 4)
followers[0].SetActive(true);
else if (power == 5)
followers[1].SetActive(true);
}
void OffBoomEffect()
{
boomEffect.SetActive(false);
isBoom = false;
}
private void OnTriggerExit2D(Collider2D collision)
{
if (collision.gameObject.tag == "Border")
{
switch (collision.gameObject.name)
{
case "Top":
isTouchTop = false;
break;
case "Bottom":
isTouchBottom = false;
break;
case "Left":
isTouchLeft = false;
break;
case "Right":
isTouchRight = false;
break;
}
}
}
}
- 팔로워가 따라다니는 모습
출처 - https://www.youtube.com/c/GoldMetal