2023-12-29 05:59:04 +00:00
|
|
|
using System.Collections;
|
2023-12-28 07:29:52 +00:00
|
|
|
using Sirenix.OdinInspector;
|
|
|
|
using UnityEngine;
|
|
|
|
using Random = UnityEngine.Random;
|
|
|
|
|
|
|
|
// ReSharper disable once CheckNamespace
|
|
|
|
namespace BlueWaterProject
|
|
|
|
{
|
|
|
|
public class Boids : MonoBehaviour
|
|
|
|
{
|
|
|
|
[Title("군집(떼) 설정")]
|
|
|
|
[Tooltip("Boid 프리팹")]
|
|
|
|
[SerializeField] private Boid boidPrefab;
|
|
|
|
|
|
|
|
[Range(1, 1000)]
|
|
|
|
[Tooltip("생성할 개체 수")]
|
|
|
|
[SerializeField] private int boidCount = 5;
|
|
|
|
|
|
|
|
[Range(5, 100)]
|
|
|
|
[Tooltip("개체 생성 범위")]
|
|
|
|
[SerializeField] private float spawnRange = 10;
|
|
|
|
|
|
|
|
[field: Tooltip("개체의 랜덤 속도 값\nx == Min\ny == Max")]
|
|
|
|
[field: SerializeField] public Vector2 RandomSpeedRange { get; private set; } = new(5, 10);
|
|
|
|
|
|
|
|
[field: Range(0, 10)]
|
2023-12-29 05:59:04 +00:00
|
|
|
[field: Tooltip("응집력(뭉치기) 가중치")]
|
2023-12-28 07:29:52 +00:00
|
|
|
[field: SerializeField] public float CohesionWeight { get; private set; } = 1;
|
|
|
|
|
|
|
|
[field: Range(0, 10)]
|
2023-12-29 05:59:04 +00:00
|
|
|
[field: Tooltip("정렬(같은 방향) 가중치")]
|
2023-12-28 07:29:52 +00:00
|
|
|
[field: SerializeField] public float AlignmentWeight { get; private set; } = 1;
|
|
|
|
|
|
|
|
[field: Range(0, 10)]
|
2023-12-29 05:59:04 +00:00
|
|
|
[field: Tooltip("분리(서로 회피) 가중치")]
|
2023-12-28 07:29:52 +00:00
|
|
|
[field: SerializeField] public float SeparationWeight { get; private set; } = 1;
|
|
|
|
|
|
|
|
[field: Range(0, 100)]
|
2023-12-29 05:59:04 +00:00
|
|
|
[field: Tooltip("경계 범위 내 행동 가중치")]
|
2023-12-28 07:29:52 +00:00
|
|
|
[field: SerializeField] public float BoundsWeight { get; private set; } = 1;
|
|
|
|
|
|
|
|
[field: Range(0, 100)]
|
2023-12-29 05:59:04 +00:00
|
|
|
[field: Tooltip("장애물 회피 가중치")]
|
2023-12-28 07:29:52 +00:00
|
|
|
[field: SerializeField] public float ObstacleWeight { get; private set; } = 10;
|
|
|
|
|
|
|
|
[field: Range(0, 10)]
|
2023-12-29 05:59:04 +00:00
|
|
|
[field: Tooltip("자아(독립행동) 가중치")]
|
2023-12-28 07:29:52 +00:00
|
|
|
[field: SerializeField] public float EgoWeight { get; private set; } = 1;
|
|
|
|
|
|
|
|
[Title("옵션")]
|
|
|
|
[Tooltip("경계 범위 On/Off")]
|
|
|
|
[SerializeField] private bool showBounds;
|
|
|
|
|
|
|
|
public MeshRenderer BoundMeshRenderer { get; private set; }
|
|
|
|
|
|
|
|
private void OnValidate()
|
|
|
|
{
|
|
|
|
if (BoundMeshRenderer)
|
|
|
|
{
|
|
|
|
BoundMeshRenderer.enabled = showBounds;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void Start()
|
|
|
|
{
|
|
|
|
CreateBoids();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void CreateBoids()
|
|
|
|
{
|
|
|
|
BoundMeshRenderer = GetComponentInChildren<MeshRenderer>();
|
|
|
|
BoundMeshRenderer.enabled = showBounds;
|
|
|
|
var myTransform = transform;
|
|
|
|
for (var i = 0; i < boidCount; i++)
|
|
|
|
{
|
|
|
|
var randomPos = Random.insideUnitSphere * spawnRange;
|
|
|
|
var randomRotation = Quaternion.Euler(0, Random.Range(0, 360f), 0);
|
|
|
|
var boid = Instantiate(boidPrefab, myTransform.position + randomPos, randomRotation, myTransform);
|
|
|
|
boid.Init(this, Random.Range(RandomSpeedRange.x, RandomSpeedRange.y));
|
|
|
|
}
|
|
|
|
}
|
2023-12-29 05:59:04 +00:00
|
|
|
|
|
|
|
public void SetBoundPos(Vector3 value) => BoundMeshRenderer.transform.position = value;
|
|
|
|
public void SetBoundPosLerp(Vector3 value, float time) => StartCoroutine(BoundPosLerpCoroutine(value, 1/time));
|
|
|
|
|
|
|
|
private IEnumerator BoundPosLerpCoroutine(Vector3 value, float time)
|
|
|
|
{
|
|
|
|
while (Vector3.Distance(transform.position, value) > 0.1f)
|
|
|
|
{
|
|
|
|
transform.position = Vector3.Lerp(transform.position, value, time * Time.deltaTime);
|
|
|
|
yield return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
transform.position = value;
|
|
|
|
}
|
2023-12-28 07:29:52 +00:00
|
|
|
}
|
|
|
|
}
|