using UnityEngine;
using System.Collections;
using UnityEngine.SceneManagement;
public class PlayerController : MonoBehaviour
{
public Joystick joystick;
public float moveSpeed = 2f;
public GameObject bulletPrefab;
public Transform firePoint;
public float bulletForce = 20f;
public float fireRate = 3f;
public float detectionRadius = 3f; // 공격 범위
public string gameOverScene;
public int damage = 1;
public int PlayerHP = 5;
public Transform playerMain;
private SpriteRenderer playerMainSpriteRenderer;
private Color defaultColor = new Color(255f / 255f, 255f / 255f, 255f / 255f);
private Color hitColor = new Color(100f / 255f, 107f / 255f, 109f / 255f);
private float lastMovedTime; // 마지막으로 움직인 시간을 저장할 변수
private void Start()
{
lastMovedTime = -fireRate;
playerMainSpriteRenderer = playerMain.GetComponent<SpriteRenderer>();
StartCoroutine(PlayerMovementCoroutine());
StartCoroutine(ShootCoroutine());
}
private IEnumerator PlayerMovementCoroutine()
{
while (true)
{
Vector2 direction = new Vector2(joystick.Horizontal, joystick.Vertical);
transform.Translate(direction * moveSpeed * Time.deltaTime, Space.World);
Vector3 clampedPosition = transform.position; //화면 밖 이동 제한
clampedPosition.x = Mathf.Clamp(clampedPosition.x, -2.8f, 2.8f);
clampedPosition.y = Mathf.Clamp(clampedPosition.y, -5f, 25f);
transform.position = clampedPosition;
if (direction != Vector2.zero)
{
lastMovedTime = Time.time;
float targetAngle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0f, 0f, targetAngle - 90f);
}
else // 조이스틱을 움직이지 않을 때
{
Collider2D[] Enemies = Physics2D.OverlapCircleAll(transform.position, detectionRadius);
Collider2D nearestEnemy = null;
float nearestDistance = detectionRadius;
foreach (Collider2D Enemy in Enemies)
{
if (Enemy.CompareTag("Enemy"))
{
float distanceToEnemy = Vector2.Distance(transform.position, Enemy.transform.position);
if (distanceToEnemy < nearestDistance)
{
nearestDistance = distanceToEnemy;
nearestEnemy = Enemy;
}
}
else if (Enemy.CompareTag("Boss"))
{
float distanceToEnemy = Vector2.Distance(transform.position, Enemy.transform.position);
if (distanceToEnemy < nearestDistance)
{
nearestDistance = distanceToEnemy;
nearestEnemy = Enemy;
}
}
}
if (nearestEnemy)
{
Vector2 directionToNearestEnemy = nearestEnemy.transform.position - transform.position;
float angle = Mathf.Atan2(directionToNearestEnemy.y, directionToNearestEnemy.x) * Mathf.Rad2Deg;
transform.eulerAngles = new Vector3(0f, 0f, angle - 90f);
}
}
yield return null;
}
}
private IEnumerator ShootCoroutine()
{
while (true)
{
Vector2 direction = new Vector2(joystick.Horizontal, joystick.Vertical);
if (direction == Vector2.zero)
{
float timeSinceLastMoved = Time.time - lastMovedTime;
if (timeSinceLastMoved < fireRate)
{
yield return new WaitForSeconds(fireRate - timeSinceLastMoved); // 움직임 이후의 시간만큼만 대기
}
GameObject bullet = Instantiate(bulletPrefab, firePoint.position, firePoint.rotation);
Rigidbody2D rb = bullet.GetComponent<Rigidbody2D>();
if (rb)
{
rb.AddForce(firePoint.up * bulletForce, ForceMode2D.Impulse);
}
}
yield return new WaitForSeconds(fireRate);
}
}
void OnCollisionEnter2D(Collision2D collision)
{
if (collision.gameObject.CompareTag("Enemy"))
{
PlayerHP -= 1;
if(PlayerHP <= 0)
{
SceneManager.LoadScene(gameOverScene); //게임오버 씬으로 이동
}
// 충돌 방향 계산
Vector2 pushDirection = transform.position - collision.transform.position;
pushDirection = pushDirection.normalized; // 방향 벡터를 정규화
float pushDistance = 1f;// 넉백 거리
transform.position += (Vector3)pushDirection * pushDistance;
// 색상 변경 및 원래대로 돌아오는 코루틴 시작
StartCoroutine(HitChangeColor());
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (collision.gameObject.CompareTag("BossBullet"))
{
PlayerHP -= 1;
if (PlayerHP <= 0)
{
SceneManager.LoadScene(gameOverScene); //게임오버 씬으로 이동
}
Destroy(collision.gameObject);
StartCoroutine(HitChangeColor());
}
}
private IEnumerator HitChangeColor()
{
playerMainSpriteRenderer.color = hitColor;
yield return new WaitForSeconds(0.2f);
playerMainSpriteRenderer.color = defaultColor;
}
void OnDrawGizmos()
{
Gizmos.color = Color.white;
Gizmos.DrawWireSphere(transform.position, detectionRadius);
}
}
using System.Collections;
using UnityEngine;
public class BossController : MonoBehaviour
{
public float detectionRange = 10f; // 탐지 범위
public GameObject bulletPrefab; // 발사할 BossBullet의 프리팹
public float shootForce = 10f; // 발사체에 적용할 힘의 크기
public int hp = 10; // Boss의 체력
private GameObject player;
[SerializeField] private PlayerController playerController;
private bool isPlayerInRange = false;
private SpriteRenderer spriteRenderer;
private Color defaultColor = new Color(255f / 255f, 0f, 0f);
private Color hitColor = new Color(188f / 255f, 81f / 255f, 81f / 255f);
public Transform firePos;
public float shootInterval = 0.5f;
private void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
spriteRenderer.color = defaultColor;
player = GameObject.FindGameObjectWithTag("Player");
StartCoroutine(ShootRoutine());
}
private void Update()
{
float distanceToPlayer = Vector3.Distance(transform.position, player.transform.position);
if (distanceToPlayer <= detectionRange)
{
isPlayerInRange = true;
LookAtPlayer();
}
else
{
isPlayerInRange = false;
}
}
private void LookAtPlayer()
{
Vector2 direction = player.transform.position - transform.position;
float angle = Mathf.Atan2(direction.y, direction.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0, 0, angle);
}
private IEnumerator ShootRoutine()
{
while (true)
{
if (isPlayerInRange)
{
ShootBullet();
}
yield return new WaitForSeconds(shootInterval);
}
}
private void ShootBullet()
{
if (firePos != null) // 발사 위치 오브젝트가 설정되었는지 확인
{
GameObject bullet = Instantiate(bulletPrefab, firePos.position, firePos.rotation);
Rigidbody2D bulletRb = bullet.GetComponent<Rigidbody2D>(); // Rigidbody2D로 수정
if (bulletRb != null)
{
bulletRb.AddForce(firePos.right * shootForce, ForceMode2D.Impulse); // 방향 변경
}
}
}
private void OnTriggerEnter2D(Collider2D other)
{
// bullet 프리팹과 트리거가 발생한 경우
if (other.gameObject.CompareTag("Bullet"))
{
if (player != null)
{
hp -= playerController.damage; // 플레이어의 공격력만큼 체력 감소
// 체력이 0 이하가 되면 적 제거
if (hp <= 0)
{
Destroy(this.gameObject);
}
StartCoroutine(HitChangeColor());
Destroy(other.gameObject);
}
}
}
private IEnumerator HitChangeColor()
{
spriteRenderer.color = hitColor;
yield return new WaitForSeconds(0.2f); // 0.2초 동안 색을 유지
spriteRenderer.color = defaultColor;
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, detectionRange);
}
}
using UnityEngine;
using System.Collections;
public class EnemyController : MonoBehaviour
{
public int hp; // 적의 체력
[SerializeField] private PlayerController player;
private SpriteRenderer spriteRenderer;
private Color defaultColor = new Color(255f / 255f, 0f, 0f);
private Color hitColor = new Color(188f / 255f, 81f / 255f, 81f / 255f);
public float detectionRange = 2f; // 탐지 범위
public float moveSpeed = 3f; // 적의 이동 속도
private Vector2 originalPosition;
private bool isChasing = false;
private void Start()
{
spriteRenderer = GetComponent<SpriteRenderer>();
spriteRenderer.color = defaultColor;
originalPosition = transform.position;
}
private void Update()
{
if (player)
{
float distanceToPlayer = Vector2.Distance(transform.position, player.transform.position);
if (distanceToPlayer <= detectionRange)
{
isChasing = true;
}
else if (distanceToPlayer > detectionRange && isChasing)
{
isChasing = false;
}
if (isChasing)
{
transform.position = Vector2.MoveTowards(transform.position, player.transform.position, moveSpeed * Time.deltaTime);
}
else
{
transform.position = Vector2.MoveTowards(transform.position, originalPosition, moveSpeed * Time.deltaTime);
}
}
}
private void OnTriggerEnter2D(Collider2D collider)
{
if (collider.CompareTag("Bullet"))
{
if (player != null)
{
hp -= player.damage; // 플레이어의 공격력만큼 체력 감소
// 체력이 0 이하가 되면 적 제거
if (hp <= 0)
{
Destroy(this.gameObject);
}
StartCoroutine(HitChangeColor());
Destroy(collider.gameObject);
}
}
}
private IEnumerator HitChangeColor()
{
spriteRenderer.color = hitColor;
yield return new WaitForSeconds(0.2f); // 0.2초 동안 색을 유지
spriteRenderer.color = defaultColor;
}
void OnDrawGizmos()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, detectionRange);
}
}
using UnityEngine;
using System.Collections;
public class WallController : MonoBehaviour
{
private void OnTriggerEnter2D(Collider2D collider)
{
// 트리거에 들어온 오브젝트의 태그가 "Bullet"인지 확인
if (collider.gameObject.CompareTag("Bullet") || (collider.gameObject.CompareTag("BossBullet")))
{
Rigidbody2D rb = collider.gameObject.GetComponent<Rigidbody2D>();
// Rigidbody2D가 있다면 움직임을 멈춤
if (rb)
{
rb.velocity = Vector2.zero;
}
Destroy(collider.gameObject, 2f);
}
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LoadManager : MonoBehaviour
{
public string nextSceneName;
public void SceneLoadManager(string nextSceneName)
{
SceneManager.LoadScene(nextSceneName);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RangeUpController : MonoBehaviour //보스방 입장시 공격범위 상승
{
private void OnTriggerExit2D(Collider2D collider)
{
if (collider.gameObject.CompareTag("Player"))
{
PlayerController player = collider.gameObject.GetComponent<PlayerController>();
player.detectionRadius = 4;
}
}
}
반응형
'KDT > 유니티 심화' 카테고리의 다른 글
[SpaceShooter] 총알이 벽에 닿았을 때 튕기게 만들기 (0) | 2023.08.21 |
---|---|
[SpaceShooter] 벽에 닿았을 때 캐릭터 회전 시키기 (2) (0) | 2023.08.21 |
[SpaceShooter] 벽에 닿았을때 캐릭터 회전시키기 (1) (0) | 2023.08.21 |
[궁수의 전설 따라해보기] 이동과 공격 (1) (0) | 2023.08.20 |
[SpaceShooter] 메인 카메라의 회전과 줌 기능 구현 (0) | 2023.08.17 |