프로그램/유니티 스크립트 소스
[유니티 스크립트 소스] Fish Flock
코더 제로
2021. 2. 2. 04:18
728x90
반응형
1. 설정
1.1 게임오브젝트 생성
① Flock.cs가 들어 갈 빈 게임오브젝트 생성(Main Camera을 대신 사용해도 됨).
② 물고기(Fish)들이 들어 갈 부모 게임오브젝트 생성
1.2 프리팹 생성
물고기 프리팹 모델을 프리팹으로 만든 뒤 FishController.cs 소스를 컴포넌트에 넣음.
2. 소스
2.1 Flock.cs
using UnityEngine;
public class Flock : MonoBehaviour
{
public GameObject m_Prfbfish;
public GameObject m_PrntFish;
public int m_Fish = 30;
public static int m_Boundary = 7;
public static GameObject[] m_Fishes;
public static Vector3 m_TargetPosition = Vector3.zero;
void Start()
{
m_Fishes = new GameObject[m_Fish];
for (int i = 0; i < m_Fish; i++)
{
Vector3 position = new Vector3(
Random.Range(-m_Boundary, m_Boundary),
Random.Range(-m_Boundary, m_Boundary),
Random.Range(-m_Boundary, m_Boundary)
);
GameObject fish = (GameObject)Instantiate(m_Prfbfish, position, Quaternion.identity);
fish.transform.parent = m_PrntFish.transform;
m_Fishes[i] = fish;
}
}
void Update()
{
GetTargetPosition();
}
void GetTargetPosition()
{
if (Random.Range(1, 10000) < 50)
{
m_TargetPosition = new Vector3(
Random.Range(-m_Boundary, m_Boundary),
Random.Range(-m_Boundary, m_Boundary),
Random.Range(-m_Boundary, m_Boundary)
);
}
}
}
2.2 FishController.cs
using UnityEngine;
public class FishController : MonoBehaviour
{
public float m_MaxSpeed = 2.0f;
public float m_MaxTurnSpeed = 0.5f;
private float m_Speed;
private float m_NeighborDistance = 3.0f;
private bool m_IsTurning = false;
void Start ()
{
m_Speed = Random.Range (0.5f, m_MaxSpeed);
}
void Update ()
{
GetIsTurning ();
if(m_IsTurning)
{
Vector3 direction = Vector3.zero - transform.position;
transform.rotation = Quaternion.Slerp (transform.rotation,
Quaternion.LookRotation (direction),
TurnSpeed () * Time.deltaTime);
m_Speed = Random.Range (0.5f, m_MaxSpeed);
}
else
{
if (Random.Range (0, 5) < 1)
SetRotation ();
}
transform.Translate (0, 0, Time.deltaTime * m_Speed);
}
void GetIsTurning()
{
if(Vector3.Distance(transform.position, Vector3.zero) >= Flock.m_Boundary)
{
m_IsTurning = true;
}
else
{
m_IsTurning = false;
}
}
void SetRotation()
{
GameObject[] fishes;
fishes = Flock.m_Fishes;
Vector3 center = Vector3.zero;
Vector3 avoid = Vector3.zero;
float speed = 0.1f;
Vector3 targetPosition = Flock.m_TargetPosition;
float distance;
int groupSize = 0;
for (int i = 0; i < fishes.Length; i++)
{
if (fishes[i] != gameObject)
{
distance = Vector3.Distance(fishes[i].transform.position, transform.position);
if (distance <= m_NeighborDistance)
{
center += fishes[i].transform.position;
groupSize++;
if (distance < 0.75f)
{
avoid += (transform.position - fishes[i].transform.position);
}
FishController anotherFish = fishes[i].GetComponent<FishController>();
speed += anotherFish.m_Speed;
}
}
}
if (groupSize > 0)
{
center = center / groupSize + (targetPosition - transform.position);
m_Speed = speed / groupSize;
Vector3 direction = (center + avoid) - transform.position;
if (direction != Vector3.zero) {
transform.rotation = Quaternion.Slerp (transform.rotation,
Quaternion.LookRotation (direction),
TurnSpeed () * Time.deltaTime);
}
}
}
float TurnSpeed()
{
return Random.Range (0.2f, m_MaxTurnSpeed);
}
}
728x90
반응형