유니티 물고기 이동 - yuniti mulgogi idong

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);
	}
 }

Shark Feeding Game(상어먹방게임) - 안드로이드 폰 화면을 터치하면 물고기(Prefabs)가 떨어지고(Touch & Spawn) 좌우반전 이동(Object Flip Move)하는 상어 입속에 들어가면 효과음(Collision Sfx)이 발생하면서 물고기가 사라지게 됩니다(OnTriggerEnter2D - Destroy).

#터치스폰  #상어먹이주기게임  #충돌효과음

[SharkMove.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SharkMove : MonoBehaviour
{
    Rigidbody2D rb;
    Vector3 localScale;
    [SerializeField] float speed = 5, dist = 7;


    bool dirRight = true;

    void Start()
    {
        rb = GetComponent<Rigidbody2D>();
        localScale = transform.localScale;
    }

    void FixedUpdate()
    {
        if (transform.position.x > dist)
            dirRight = false;
        else if (transform.position.x < -dist)
            dirRight = true;

        if (dirRight)
            GoRight();
        else
            GoLeft();
    }

    void GoRight()
    {
        localScale.x = -1;
        transform.transform.localScale = localScale;
        rb.velocity = new Vector2(speed, 0);
    }

    void GoLeft()
    {
        localScale.x = 1;
        transform.transform.localScale = localScale;
        rb.velocity = new Vector2(-speed, 0);
    }
}

[DestroyEat.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyEat : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D collision)
    {
        FishSpawn.SoundPlay();
        Destroy(collision.gameObject);
    }
}

[DestroyArea.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class DestroyArea : MonoBehaviour
{
    void OnTriggerEnter2D(Collider2D collision)
    {
        Destroy(collision.gameObject);
    }
}

[FishSpawn.cs]

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FishSpawn : MonoBehaviour
{
    [SerializeField] GameObject fish;
    static AudioSource audioSource;
    public static AudioClip audioClip;

    void Start()
    {
        audioSource = GetComponent<AudioSource>(); audioClip = Resources.Load<AudioClip>("Eat");
    }

    void Update()
    {
        if(Input.touchCount > 0)
        {
            Touch touch = Input.GetTouch(0);
            Vector2 touchPos = Camera.main.ScreenToWorldPoint(touch.position);

            if (touch.phase == TouchPhase.Began)
                Instantiate(fish, touchPos, Quaternion.identity);
        }
    }
    public static void SoundPlay()
    {
        audioSource.PlayOneShot(audioClip);
    }
}