ºÇ½ª¹¹¿·¡§
orika_ex_miyako 2026ǯ01·î18Æü(Æü) 19:17:28ÍúÎò
¡¡Bake ¥¨¥ê¥¢Æâ¤«¤Ä¡¢Å¨¤¬°Üư²Äǽ¤ÊÃÏÅÀ¤Ë¤ª¤¤¤Æ¡¢Ëè²ó¤ÎÀ¸À®°ÌÃÖ¤¬°Û¤Ê¤ë¾õÂÖ¤ÇÀ¸À®¤µ¤ì¤Þ¤¹¡£
ư²è¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥ó¥¯
https://gyazo.com/a91fc3c9f1982448a0b01c2d6367e948
¡¡NavMeshAgent ¤òÍøÍѤ·¤ÆÅ¨¤Ê¤É¤òư¤«¤¹¾ì¹ç¡¢¥²¡¼¥à¼Â¹Ô¸å¤ËưŪ¤ËÀ¸À®¤·¤ÆÆ°¤«¤¹¤Ë¤Ï Bake ¤µ¤»¤Æ¤¤¤ë¥¨¥ê¥¢Æâ¤ËŨ¤òÀ¸À®¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡£
¸ÇÄê°ÌÃ֤ξì¹ç¤Ç¤¢¤ì¤ÐÌäÂꤢ¤ê¤Þ¤»¤ó¤¬¡¢Bake ¥¨¥ê¥¢¤¬Æ°Åª¤ËÊѲ½¤¹¤ë¾ì¹ç¤ä¡¢À¸À®°ÌÃÖ¤½¤Î¤â¤Î¤ò¥é¥ó¥À¥à¤ËÀßÄꤷ¤¿¤¤¤è¤¦¤Ê¥±¡¼¥¹¤â¤¢¤ê¤Þ¤¹¡£
¡¡º£²ó¤Ï ¥¿¥¤¥ë¥Þ¥Ã¥×¤Î¾å¤ò Bake ¤·¤¿¾õÂ֤ǡ¢NavMesh.SamplePosition ¥á¥½¥Ã¥É¤òÍøÍѤ·¤¿Å¨¤ÎÀ¸À®µ¡Ç½¤Î¼ÂÁõÎã¤Ë¤Ê¤ê¤Þ¤¹¡£
¤³¤Á¤é¤òÍøÍѤ¹¤ë¤³¤È¤Ç¡¢Bake ¤µ¤ì¤Æ¤¤¤ë¥¨¥ê¥¢Á´°è¤òÂоݤˤ·¤Ä¤Ä¡¢°ÜưÉԲĤΥ¨¥ê¥¢¤Ë¤ÏÀ¸À®¤ò¹Ô¤ï¤Ê¤¤½èÍý¤¬²Äǽ¤Ç¤¹¡£
Unity ¸ø¼°¥¹¥¯¥ê¥×¥È¡¦¥ê¥Õ¥¡¥ì¥ó¥¹
NavMesh.SamplePosition
¡¡¤Ê¤ª¡¢£²£Ä ¤Î NavMesh ¼«ÂΤˤĤ¤¤Æ²¼µ¤Î¶µºà¤ò»²¹Í¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
¡¡¡Ú£²£Ä¡ÛNavMeshAgent ¤Ë¤è¤ë¥Ù¡¼¥·¥Ã¥¯¤ÊÄÉÀ×µ¡Ç½¤Î¼ÂÁõÎã
¡¡²¼µ¤Î¥³¡¼¥É¤Ï¡¢SamplePosition ¥á¥½¥Ã¥É¤òÍøÍѤ·¤¿¡¢°ìÄê»þ´Ö¤´¤È¤ËŨ¤ÎÀ¸À®¤ò¹Ô¤¦µ¡Ç½¤Ç¤¹¡£
»ØÄꤵ¤ì¤¿Å¨¤òÀ¸À®¤¹¤ë¤È¡¢À¸À®½èÍý¤¬Ää»ß¤·¤Þ¤¹¡£
¡¡¥Ò¥¨¥é¥ë¥¡¼¾å¤Ë Create Empty ¤ÇºîÀ®¤·¤¿¶õ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò£²¤ÄÍѰդ·¤Þ¤¹¡£
¤³¤Î¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤Ï Bake ¤µ¤ì¤Æ¤¤¤ë¥¿¥¤¥ë¥Þ¥Ã¥×¤Îº¸²¼¤È±¦¾å¤Ë¤½¤ì¤¾¤ìÇÛÃÖ¡¢Bake ¤·¤¿¥¿¥¤¥ë¥Þ¥Ã¥×Á´ÂΤò¥«¥Ð¡¼¤Ç¤¤ë¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
̾¾Î¤Ï¤ï¤«¤ê¤ä¤¹¤¤¤è¤¦¤Ë SpawnTran_LeftBottom¡¢SpawmTran_RightTop ¤Î¤è¤¦¤Ë¡¢ÇÛÃÖ¤·¤¿°ÌÃÖ¤Î̾¾Î¤Ë¤·¤Æ¤ª¤¯¤È¤è¤¤¤Ç¤·¤ç¤¦¡£
SpawnTran_LeftBottom ¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È


SpawmTran_RightTop ¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È


¡¡NavMesh.SamplePosition ¥á¥½¥Ã¥É¤òÍøÍѤ·¤¿¡¢Bake ¤µ¤ì¤Æ¤¤¤ë¥¨¥ê¥¢¤«¤Ä¡¢°Üư¤¬²Äǽ¤Ê°ÌÃ֤ؤÎŨ¤ÎÀ¸À®½èÍý¤Ë¤Ê¤ê¤Þ¤¹¡£
EnemySpawner.cs
using System.Collections;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Tilemaps;
public class EnemySpawner : MonoBehaviour {
[SerializeField]
private Chaser enemyPrefab; // Ũ¤Î¥×¥ì¥Ï¥Ö¤Ç¤¹¡£Chaser ¥¯¥é¥¹¤¬¥¢¥¿¥Ã¥Á¤µ¤ì¤Æ¤¤¤Ê¤¤¤Ê¤é¤Ð¡¢Ê̤Υǡ¼¥¿·¿¤ËÊѹ¹¤·¤Æ¤¯¤À¤µ¤¤¡£
[SerializeField]
private float spawnInterval = 3.0f; // Ũ¤òÀ¸À®¤¹¤ë¤Þ¤Ç¤ÎÂÔµ¡»þ´Ö¤ÎÀßÄêÃÍÍѤÎÊÑ¿ô
[SerializeField]
private Transform[] spawnTrans;¡¡¡¡ // ¥é¥ó¥À¥à¤ËÀ¸À®¤¹¤ë¤È¤¤ËÍøÍѤ¹¤ëÈϰϤòÀßÄꤹ¤ë¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È·²¤Î Transform
public bool isSpawnEnemy; // À¸À®½èÍý¤ò¹Ô¤¦¤«¤É¤¦¤«¤ÎȽÄêÃÍ¡£true ¤Ê¤éÀ¸À®¤¹¤ë
[SerializeField]
private Transform target; // À¸À®¤·¤¿Å¨¤ÎÄÉÀ×ÂоݤǤ¹
[SerializeField]
private Tilemap tilemap; // Bake ¤µ¤ì¤Æ¤¤¤ë¥¿¥¤¥ë¥Þ¥Ã¥×
[SerializeField]
private int maxEnemyCount; // Ũ¤ÎºÇÂçÀ¸À®¿ô¤ÎÀßÄêÍѤÎÊÑ¿ô
private int currentEnemyCount; // ¸½ºß¤ÎÀ¸À®¿ô¤òÇİ®¤¹¤ë¤¿¤á¤ÎÊÑ¿ô
void Start() {
// »ØÄꤷ¤¿ÈÏ°ÏÆâ¤Î¥é¥ó¥À¥à¤Ê°ÌÃÖ¤ËŨ¤òÀ¸À®(¥Ç¥Ð¥Ã¥°ÍѤǤ¹)
//RandomSpawnEnemy();
// »þ´Ö¤Î·×¬´Æ»ë
StartCoroutine(ObserveTimer());
}
/// <summary>
/// »þ´Ö¤Î·×¬´Æ»ë
/// </summary>
/// <returns></returns>
private IEnumerator ObserveTimer() {
// isSpawnEnemy ¤¬ true ¤Î´Ö¡¢Å¨¤ÎÀ¸À®¤ò·«¤êÊÖ¤¹
while (isSpawnEnemy && maxEnemyCount >= currentEnemyCount) {
// »ØÄꤷ¤¿Éÿô¤À¤±½èÍý¤òÃæÃÇ(ÂÔµ¡)
yield return new WaitForSeconds(spawnInterval);
// »ØÄꤷ¤¿ÈÏ°ÏÆâ¤Î¥é¥ó¥À¥à¤Ê°ÌÃÖ¤ËŨ¤òÀ¸À®
RandomSpawnEnemy();
currentEnemyCount++;
}
}
/// <summary>
/// »ØÄꤷ¤¿ÈÏ°ÏÆâ¤Î¥é¥ó¥À¥à¤Ê°ÌÃÖ¤ËŨ¤òÀ¸À®
/// </summary>
private void RandomSpawnEnemy() {
// À¸À®°ÌÃÖ¤ò¥é¥ó¥À¥à¤Ë·èÄê
Vector3 spawnPos = new(Random.Range(spawnTrans[0].position.x, spawnTrans[1].position.x),
Random.Range(spawnTrans[0].position.y, spawnTrans[1].position.y),
0);
// À¸À®
Chaser chaser = SpawnEnemy(spawnPos);
// ¥×¥ì¥¤¥ä¡¼¤Î°ÜưÈϰϳ°¤ËŨ¤òÀ¸À®¤·¤Æ¤¤¤Ê¤¤¤«È½Äꤷ¡¢À¸À®¤·¤Æ¤·¤Þ¤Ã¤Æ¤¤¤ë¾ì¹ç¤Ë¤ÏºÇ¤â¶á¤¤°ÜưÈÏ°ÏÆâ¤Ë°Üư¤µ¤»¤ë
// SamplePosition ¤Ï¡¢sourcePosition¡ÊÂè1°ú¿ô¡Ë¤ò´ð½à¤Ë¡¢maxDistance¡ÊÂè3°ú¿ô¡Ë°ÊÆâ¤Ç¡¢
// areaMask¡ÊÂè4°ú¿ô¡Ë¤Ë´Þ¤Þ¤ì¤ë¡¢NavMesh ¾å¤Î¡ÖºÇ¤â¶á¤¤ÅÀ¡×¤ò¸¡º÷¤¹¤ë¡£
// ¸«¤Ä¤«¤Ã¤¿¾ì¹ç¤Ï true ¤òÊÖ¤·¡¢¤½¤Î°ÌÃÖ¾ðÊó¤¬ hit ¤Ë³ÊǼ¤µ¤ì¤ë¡£
// maxDistance °ÊÆâ¤Ë NavMesh ¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Î¤ß false ¤Ë¤Ê¤ë¡£
if (NavMesh.SamplePosition(chaser.transform.position, out NavMeshHit hit, 1.0f, NavMesh.AllAreas)) {
// hit.position ¤Ë¤Ïɬ¤º NavMesh ¾å¤ÎºÂɸ¤¬Æþ¤ë¡£
// sourcePosition ¤¬¤¹¤Ç¤Ë NavMesh ¾å¤Ë¤¢¤ë¾ì¹ç¤Ï¡¢¤Û¤ÜƱ¤¸ºÂɸ¤Ë¤Ê¤ë¤¬¡¢NavMesh ³°¤Î¾ì¹ç¤Ï¡¢ºÇ¤â¶á¤¤ NavMesh ¾å¤ÎºÂɸ¤ËÊäÀµ¤µ¤ì¤ë¡£
chaser.transform.position = hit.position;
chaser.transform.rotation = Quaternion.identity;
// ZºÂɸ¤ò0¤Ë¸ÇÄê
chaser.transform.position = new Vector3(chaser.transform.position.x, chaser.transform.position.y, 0);
// Ũ¤Î¥¿¡¼¥²¥Ã¥È¤È¥¿¥¤¥ë¥Þ¥Ã¥×¤ÎÀßÄê
chaser.Setup(target, tilemap);
Debug.Log("Ũ¤Î°ÌÃÖÄ´À°¤·¤ÆÇÛÃÖ");
} else {
Debug.Log("Ũ¤ÎÇÛÃÖÉÔ²Ä");
}
}
/// <summary>
/// Ũ¤ÎÀ¸À®
/// </summary>
/// <param name="spawnPos">¥é¥ó¥À¥à¤Ë¼èÆÀ¤·¤¿À¸À®ÍѺÂɸ</param>
/// <returns></returns>
public Chaser SpawnEnemy(Vector3 spawnPos) {
// À¸À®
Chaser chaser = Instantiate(enemyPrefab, spawnPos, enemyPrefab.transform.rotation);
Debug.Log("ŨÀ¸À®");
return chaser;
}
}
¡¡¤Ê¤ª£³£Ä¤Ç¤Î SamplePosition ¥á¥½¥Ã¥É¤ÎÂбþ¤Ë¤Ä¤¤¤Æ¤Ï¡¢²¼µ¤Î¶µºà¤ò»²¹Í¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡£
¡¡¡¡¢ª¡¡£³£ÄÊõÀн¸¤á¥¢¥¯¥·¥ç¥ó¥²¡¼¥à¡¡¼ê½ç£±£¹
¡¡¥¹¥¯¥ê¥×¥È¤òºîÀ®¤·¤¿¤é¡¢¶õ¤Î¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤òºîÀ®¤·¤Æ¡¢EnemySpawner ¤Ë̾Á°¤òÊѹ¹¤·¤Þ¤¹¡£
¤½¤Î¸å¡¢EnemySpawner ¥¹¥¯¥ê¥×¥È¤ò¥¢¥¿¥Ã¥Á¤·¡¢É¬ÍפʾðÊó¤ò¥¢¥µ¥¤¥ó¤·¤Æ¤¯¤À¤µ¤¤¡£
¡¡Å¨¤Î¥×¥ì¥Ï¥Ö¤Ë¤Ï Chaser ¥¯¥é¥¹¤¬¥¢¥¿¥Ã¥Á¤µ¤ì¤Æ¤¤¤ë¤³¤È¡¢¥¿¥¤¥ë¥Þ¥Ã¥×¤ÎÇÛÃ֤䡢¥¿¥¤¥ë¥Þ¥Ã¥×¾å¤Î NavMesh ¤Î Bake ¤Ï½ªÎ»¤·¤Æ¤¤¤ëÁ°Äó¤Ç¤¹¡£
¡¡º£²óºîÀ®¤·¤¿¥¹¥¯¥ê¥×¥È¤Î spawnTrans ÇÛÎó¤Ë¡¢Àè¤Û¤ÉºîÀ®¤·¤Æ¤ª¤¤¤¿ SpawnTran_LeftBottom ¤È SpawmTran_RightTop ¤Î£²¤Ä¤Î¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤ò¥¢¥µ¥¤¥ó¤·¤Þ¤¹¡£
¡¡½èÍý¤Î½çÈÖŪ¤Ë Element 0 ¤Ë¤Ï SpawnTran_LeftBottom ¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¡¢Element 1 ¤Ë¤Ï SpawmTran_RightTop ¥²¡¼¥à¥ª¥Ö¥¸¥§¥¯¥È¤ò¥¢¥µ¥¤¥ó¤·¤Æ¤¯¤À¤µ¤¤¡£
¤Ê¤¼¤³¤Î½çÈ֤ˤʤé¤Ê¤¤¤È¥À¥á¤Ê¤Î¤«¤Ï¡¢¥×¥í¥°¥é¥à¤òÆÉ¤ß²ò¤¤¤Æ¤ß¤Æ¤¯¤À¤µ¤¤¡£
¡¡¤Þ¤¿ spawnInterval ÊÑ¿ô¤Ï 0 ¤Ë¤ÏÀßÄꤷ¤Ê¤¤¤Ç¤¯¤À¤µ¤¤¡£
¸Ä¤ÎÊÑ¿ô¤Ï while ʸÆâ¤Î¥³¥ë¡¼¥Á¥ó¤ÎÂÔµ¡»þ´Ö¤È¤·¤ÆÍøÍѤ·¤Æ¤¤¤ë¤Î¤Ç¡¢Ëü¤¬°ì 0 ¤Î¤Þ¤Þ¤Ç¥²¡¼¥à¤òµ¯Æ°¤·¤Æ¤·¤Þ¤¦¤È̵¸Â¥ë¡¼¥×¤Ë¤Ê¤Ã¤Æ Unity ¤¬Ää»ß¤·¤Æ¤·¤Þ¤¤¤Þ¤¹¡£
while ʸ¤¬¤¢¤ë½èÍý¤ÏÆÃ¤Ëµ¤¤òÉÕ¤±¤Æ¤¯¤À¤µ¤¤¡£
¡¡Æ±ÍÍ¤Ë isSpawnEnemy ÊÑ¿ô¤ò true ¤ËÀßÄꤷ¤Æ¤ª¤«¤Ê¤¤¤È¡¢while ¤Ç¤ÎÀ¸À®¤Ï¹Ô¤ï¤ì¤Þ¤»¤ó¡£
¥µ¥ó¥×¥ë²èÁü

¡¡À¸À®¤Þ¤Ç¤Î spawnInterval ¤Ï 1.5f¡¢Å¨¤ÎºÇÂç¿ô¤Ï maxEnemyCount 4 ¤ÇÀßÄꤷ¤¿¾ì¹ç¤Îư²è¤Ç¤¹¡£
Bake ¥¨¥ê¥¢Æâ¤«¤Ä¡¢Å¨¤¬°Üư²Äǽ¤ÊÃÏÅÀ¤Ë¤ª¤¤¤Æ¡¢Ëè²ó¤ÎÀ¸À®°ÌÃÖ¤¬°Û¤Ê¤ë¾õÂÖ¤ÇÀ¸À®¤µ¤ì¤Þ¤¹¡£
ư²è¥Õ¥¡¥¤¥ë¤Ø¤Î¥ê¥ó¥¯
https://gyazo.com/a91fc3c9f1982448a0b01c2d6367e948
- ¥«¥Æ¥´¥ê¡§
- ¿Ê³Ø/¥¹¥¯¡¼¥ë
- ¥×¥í¥°¥é¥ß¥ó¥°




¥³¥á¥ó¥È¤ò¤«¤¯