¡¡¾åµ¤Î½èÍý¤òÍøÍѤ·¤¿¡¢¼ÂºÝ¤Ë¥²¡¼¥à¤ª¤±¤ë¥µ¥ó¥×¥ë¥³¡¼¥É¤âÄ󼨤·¤Æ¤ª¤¤Þ¤¹¡£
¡¡¤³¤ì¤Ï£²£Ä¥²¡¼¥à¤Ë¤ª¤¤¤Æ¡¢¥³¥é¥¤¥À¡¼¤ÎÈÏ°ÏÆâ¤Ë¤¤¤ëÂоݤ«¤é¡¢ºÇ¤â¶á¤¤Å¨¤Î¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤òõ¤·¤ÆÃƤòȯ¼Í¤¹¤ëµ¡Ç½¤Ç¤¹¡£
£±¤Ä¤Î¥¯¥é¥¹¤Ë¤·¤Æ¤¤¤Þ¤¹¤¬¡¢Å¬µ¹Ê¬³ä¤·¤Æµ½Ò¤·¤Æ¤â¤è¤¤¤Ç¤·¤ç¤¦¡£
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq;
// Physics2D.OverlapCircleNonAlloc
// https://docs.unity3d.com/ja/current/ScriptReference/Physics2D.OverlapCircleNonAlloc.html
// Physics2D.OverlapCircleAll
// https://docs.unity3d.com/ja/current/ScriptReference/Physics2D.OverlapCircleAll.html
public class BulletGenerator_AutoAim : MonoBehaviour
{
[SerializeField] private Bullet bulletPrefab;
[SerializeField] private int damage;
[SerializeField] private float speed = 1000.0f;
[SerializeField] private float interval = 2.0f;
// => BulletDataSO ¤òºîÀ®¤·¤¿¤é¡¢¤½¤³¤«¤é³Æ¥Ç¡¼¥¿¤ò¤â¤é¤Ã¤Æ»È¤¦
[SerializeField] private LayerMask enemyLayer; // LayerMask ÀßÄê¤ò¥¤¥ó¥¹¥Ú¥¯¥¿¡¼¤Ç¹Ô¤¦
[SerializeField] private float radius = 2.0f;
[SerializeField] private bool isDrawGizmoOn; // ¥Ç¥Ð¥Ã¥°ÍѤε¡Ç½¤Î¥ª¥ó¥ª¥ÕÀÚ¤êÂؤ¨¤ò¼«Ê¬¤Çºî¤ë
private bool isShooting; // ÃƤÎÀ¸À®À©¸æ
void Start()
{
// TODO BulletData ºîÀ®¸å¤Ï¡¢damage, speed, interval ¤ÎÃͤò BulletData ¤ÎÆâÍƤ˹¹¿·¤¹¤ë
}
void Update()
{
// ÃƤÎÏ¢¼ÍËÉ»ß
if (isShooting) {
return;
}
// ¹¶·âÍѤΥܥ¿¥ó¤ò²¡¤·¤¿¤é
if (Input.GetButtonDown("Fire1") || Input.GetKeyDown(KeyCode.Return)) { // Fire1 = Left Ctrl
// ¹¶·âÈÏ°ÏÆâ¤ËŨ¤¬¤¤¤ë¤«È½Äê
DetectEnemiesInRange();
}
}
/// <summary>
/// ¹¶·âÈÏ°ÏÆâ¤ËŨ¤¬¤¤¤ë¤«È½Äꤷ¡¢Â¸ºß¤¹¤ë¾ì¹ç¤Ë¤Ï¥×¥ì¥¤¥ä¡¼¤ËºÇ¤â¶á¤¤Å¨¤òÆÃÄê
/// </summary>
private void DetectEnemiesInRange()
{
¡¡¡¡¡¡¡¡// ÈÏ°ÏÆâ¤ÎÁ´¤Æ¤ÎŨ¤Î¥³¥é¥¤¥À¡¼¤ò¼èÆÀ
// ¡OverlapCircleNonAlloc ¤Î¾ì¹ç(¤¿¤À¤·¡¢¾ÍèŪ¤ËÈó¿ä¾©)
// ÈÏ°ÏÆâ¤ÎÁ´¤Æ¤ÎŨ¤Î¥³¥é¥¤¥À¡¼¤ò¼èÆÀ¤¹¤ë¤¿¤á¤ÎÇÛÎó¤òÍÑ°Õ
//Collider2D[] hitColliders = new Collider2D[10]; // 10¤Ï²¾¤Î¿ôÃͤǤ¹¡£¼ÂºÝ¤Ë¤ÏŬÀڤʿôÃͤòÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
//int numColliders = Physics2D.OverlapCircleNonAlloc(transform.position, radius, hitColliders, enemyLayer);
// ¹¶·âÈÏ°ÏÆâ¤ËŨ¤¬¸«¤Ä¤«¤é¤Ê¤¤¾ì¹ç¡¢½èÍý¤·¤Ê¤¤
// if (numColliders == 0) {
// return;
// }
// ¢OverlapCircleAll ¤Î¾ì¹ç
¡¡¡¡¡¡¡¡// ÈÏ°ÏÆâ¤ÎÁ´¤Æ¤ÎŨ¤Î¥³¥é¥¤¥À¡¼¤ò¼èÆÀ¤·¤ÆÇÛÎó¤Ë³ÊǼ
Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, radius, enemyLayer);
// ¹¶·âÈÏ°ÏÆâ¤ËŨ¤¬¸«¤Ä¤«¤é¤Ê¤¤¾ì¹ç¡¢½èÍý¤·¤Ê¤¤
if (hitColliders.Length == 0) {
Debug.Log("Ũ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó");
return;
}
// ¤³¤³¤«¤é¶¦Ä̽èÍý
Debug.Log("Ũ¤òȯ¸« : " + hitColliders.Length + " ÂÎ");
// ºÇ¤â¶á¤¤Å¨¤È¤½¤Îµ÷Î¥¤ÎÆó¾è¤òÊݸ¤¹¤ëÊÑ¿ô
Collider2D nearestEnemy = null;
float nearestDistanceSqr = float.MaxValue;
// ÇÛÎóÆâ¤Î³ÆŨ¤ËÂФ·¤Æµ÷Î¥¤ÎÆó¾è¤ò·×»»¤·¡¢ºÇ¤â¶á¤¤Å¨¤ò¸«¤Ä¤±¤ë(OverlapCircleNonAlloc ¤Î¾ì¹ç¤Ï numColliders ¤ò»È¤¦)
for (int i = 0; i < hitColliders.Length; i++)
{
// ¥×¥ì¥¤¥ä¡¼¤Î°ÌÃÖ¤ÈÇÛÎó¤ËÆþ¤Ã¤Æ¤¤¤ëŨ¤Î°ÌÃÖ¤ò·×»»¤·¤Æ¡¢Ê¿Êýº¬¤Ë¤¹¤ë
float distanceSqr = (transform.position - hitColliders[i].transform.position).sqrMagnitude;
//distanceSqr = (transform.position - hitColliders[i].transform.position).magnitude;
//distanceSqr = Vector2.Distance(transform.position - hitColliders[i].transform.position);
// º£²ó¤Îµ÷Î¥¤È¡¢¸½ºß¤ÎºÇ¤â¶á¤¤µ÷Î¥¤òÈæ³Ó
if (distanceSqr < nearestDistanceSqr)
{
nearestDistanceSqr = distanceSqr;
nearestEnemy = hitColliders[i];
}
}
// ¾åµ¤Î¶¦Ä̽èÍý¤ò Linq ¤Ë¤·¤¿¾ì¹ç(ÍÑ°Õ¤¹¤ë¥í¡¼¥«¥ëÊÑ¿ô¤Ï¸º¤ê¡¢for ʸ¤â¤Ê¤¯¤Ê¤ë¤¿¤á¡¢²ÄÆÉÀ¤Ï¹â¤¯¤Ê¤ë¤¬¡¢Éé²Ù¤¬¤¢¤¬¤ë²ÄǽÀ¤¬¤¢¤ë)
// Collider2D nearestEnemy =
// hitColliders
// .OrderBy(hit => (transform.position - hit.transform.position).sqrMagnitude)
// .FirstOrDefault(); // hitColliders[0]
//
// if (nearestEnemy == null) {
// Debug.Log("Ũ¤¬¸«¤Ä¤«¤ê¤Þ¤»¤ó");
// return;
// }
Debug.Log("ºÇ¤â¶á¤¤Å¨¤¬¸«¤Ä¤«¤ê¤Þ¤·¤¿ : " + nearestEnemy.gameObject.name);
¡¡¡¡¡¡¡¡// ÃƤòȯ¼Í¤·¤Æ¤¤¤ë¾õÂ֤ˤ¹¤ë => Ï¢¼ÍËÉ»ß
isShooting = true;
¡¡¡¡¡¡¡¡// ¥×¥ì¥¤¥ä¡¼¤«¤é¸«¤¿Å¨¤ÎÊý¸þ¤ò»»½Ð¤·¡¢Àµµ¬²½(µ÷Î¥¤Ë¤è¤ë±ó¶á¤Ç¡¢ÃƤήÅÙ¤¬ÊѤï¤é¤Ê¤¤¤è¤¦¤Ë¤¹¤ë)
Vector2 direction = (nearestEnemy.transform.position - transform.position).normalized;
// ºÇ¤â¶á¤¤Å¨¤Î¤¤¤ëÊý¸þ¤ËÂФ·¤ÆÃƤòȯ¼Í¤¹¤ë
StartCoroutine(GenerateBullet(direction));
// TODO ¥¢¥Ë¥áƱ´ü¤µ¤»¤ë¾ì¹ç¡¢direction ¤ÎÃͤòÍøÍѤ¹¤ì¤Ð¥×¥ì¥¤¥ä¡¼¤«¤é¸«¤¿Å¨¤ÎÊý¸þ¤Ë¤Ê¤ê¤Þ¤¹¡£
}
/// <summary>
/// ÃƤòÀ¸À®¤·¤Æ¡¢È¯¼ÍÌ¿Îá¤ò¤¹¤ë
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
private IEnumerator GenerateBullet(Vector2 direction) {
¡¡¡¡¡¡¡¡// ¥¯¥é¥¹¤ÇÀ¸À®
Bullet bullet = Instantiate(bulletPrefab, transform.position, Quaternion.identity);
¡¡¡¡¡¡¡¡// ȯ¼ÍÌ¿Îá
bullet.Shoot(damage, speed, direction);
¡¡¡¡¡¡¡¡// ÂÔµ¡»þ´Ö
yield return new WaitForSeconds(interval);
¡¡¡¡¡¡¡¡// ºÆÅÙ¡¢ÃƤòȯ¼Í¤Ç¤¤ë¾õÂÖ¤ËÌ᤹
isShooting = false;
}
/// <summary>
/// ¹¶·âÈϰϤβĻ벽(Scene¥Ó¥å¡¼)
/// </summary>
void OnDrawGizmos()
{
if (!isDrawGizmoOn) {
return;
}
Gizmos.color = Color.red;
Gizmos.DrawWireSphere(transform.position, radius);
}
}
¡¡OnDrawGizmos ¥á¥½¥Ã¥É¤Ç¤Ï¡¢¾åµ¤Î¤è¤¦¤Ë
Áá´ü¤Î return ʸ¤Ë¤¹¤ë¤³¤È¤Ç½èÍý¤Î²ÄÆÉÀ¤ò¹â¤á¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡£
¡¡¾ò·ï¼°¤òºîÀ®¤¹¤ë¾ì¹ç¤Ë¤Ï¡¢¡Á¤Ê¤é¤Ð¡¢¤È¹Í¤¨¤ë¤À¤±¤Ç¤Ï¤Ê¤¯¡¢¡Á¤Ç¤Ï¤Ê¤¤¤Ê¤é¡¢¤È¤¤¤¦Ê̤λëÅÀ¤â»ý¤Ä¤³¤È¤¬ÂçÀڤǤ¹¡£
¤½¤¦¤¹¤ë¤³¤È¤Ç½ÀÆð¤Ê½èÍý¤òºîÀ®¤·¤Æ¤¤¤¯¤³¤È¤¬½ÐÍè¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡£
¡¡¤Þ¤¿¡¢Gizmos.DrawWireSphere ¥á¥½¥Ã¥ÉÆâ¤Î°ú¿ô¤Î¾ðÊó¤ò Physics2D.OverlapCircleAll ¥á¥½¥Ã¥É¤Î°ú¿ô¤ÈƱ¤¸ÊÑ¿ô¤Ë¤·¤Æ¤ª¤¯¤³¤È¤Ç¡¢
Physics2D.OverlapCircleAll ¥á¥½¥Ã¥É¤ÎÆâÍƤËϢư¤·¤¿¥®¥º¥â¤ÎÉÁ²è¤ò¹Ô¤¦¤è¤¦¤Ë¤·¤Æ¤¤¤Þ¤¹¡£
// ÈÏ°ÏÆâ¤ÎÁ´¤Æ¤ÎŨ¤Î¥³¥é¥¤¥À¡¼¤ò¼èÆÀ¤·¤ÆÇÛÎó¤Ë³ÊǼ
Collider2D[] hitColliders = Physics2D.OverlapCircleAll(transform.position, radius, enemyLayer);
Gizmos.DrawWireSphere(transform.position, radius);
¡¡¤³¤Î¤è¤¦¤Ê·Á¤ÇÍøÍѤ¹¤ë¤È¡¢ÁÛÄꤷ¤Æ¤¤¤ëÄ̤ê¤Î¥®¥º¥âÉÁ²è¤ÎµóÆ°¤Ë¤Ê¤ê¤Þ¤¹¡£
¡¡
¡¡
¥á¥½¥Ã¥É¤Î°ú¿ô¤òÍý²ò¤·¤¿¾å¤Ç¡¢ÊÑ¿ô¤ò¾å¼ê¤¯³èÍѤ·¤Þ¤·¤ç¤¦¡£
¡¡