Chapter 12-4. 기타 : 물 구현하기

Date:     Updated:

카테고리:

태그:

인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click

🚀 유니티에서 물 넣는 방법

  1. 우클 - Import Package - Environment
    • 유니티 자체에서 제공하는 패키지를 임포트하면 됨. Water도 같이 제공함.
  2. 유니티 에셋 스토어에서 물과 관련된거 구입해서 임포트
  3. ✨ 직접 만들기. 아래 3개가 필요함.
    • 1️⃣ 물 표면 텍스처
    • 2️⃣ 물 쉐이더
    • 3️⃣ 쉐이더를 입힐 물 머테리얼


🚀 물 구현하기

물 머테리얼

image

image

쉐이더 파일을 드래그해서 머테리얼에다 드롭하면 이렇게 머테리얼에 쉐이더를 간단하게 입힐 수 있다. (핫핑크 상태는 아직 머테리얼에 쉐이더가 입혀지지 않은 상태를 의미한다.)

image


물 오브젝트

image

물 표면으로 쓸 Plane 오브젝트에 물 머테리얼을 입힌다. Plane에 기본적으로 붙어있는 Mesh Collider 는 제거해준다. 물 표면 위를 플레이어가 걸을 수 있으면 안되니까! 물 표면을 밟으면 물에 관통되어 들어갈 수 있어야 하므로 Collider를 제거해주는 것이다. 사실상 물 표면을 시각적으로 보여줄 표면 오브젝트만 있고 물 속은 텅텅 비어있는 것이다!

image

이렇게 물 표면 Plane 오브젝트를 여러개 만들어 물 웅덩이로 만들 공간을 덮어준다. 그리고 이들을 Water라는 자식들로 하나로 묶어준다.

image

물 속에 들어가면 물 속에 들어간지를 알아야 하므로 트리거가 체크된 큰 콜라이더를 Water에 붙이고 물 속에 넣어준다. 사실상 이 곳은 빈 공간이지만 콜라이더에 관통되면 진짜 물 속에 있는 것처럼 화면을 파랗게 해주고 저항력을 높여주는 등등 갖가지 효과를 줄것이다.


🚀 물 관련 사운드

image

SoundManager에 물과 관련된 사운드 3 개를 추가해주었다. 사운드 매니저로 재생시킬거라서..


🚀 물에 들어갔을 때

📜GameManager

    public static bool isNight = false;
    public static bool isWater = false;
  • 밤인지, 물속인지도 📜GameManager로 관리되게
    • 밤이면 True
    • 물 속이면 True


📜DayAndNight

기존의 멤버 isNight 지우고 전부 GameManager.isNight로 대체함!


📜Water

Water에 붙인다.

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

public class Water : MonoBehaviour
{
    [SerializeField] private float waterDrag; // 물 속 저항력
    private float originDrag; // 물 밖 세상의 원래 저항력

    private Color originColor; // 물 밖 세상의 낮의 원래 Fog 색깔
    [SerializeField] private Color originNightColor;  // 물 밖 세상의 밤의 원래 Fog 색깔

    [SerializeField] private Color waterColor; // 낮의 물 속 Fog 색깔
    [SerializeField] private Color waterNightColor; // 밤의 물 속 Fog 색깔

    [SerializeField] private float waterFogDensity; // 낮의 물 속 탁한 정도
    [SerializeField] private float waterNightFogDensity; // 낮의 물 속 탁한 정도

    private float originFogDensity; // 물 밖 세상의 낮의 탁한 정도
    [SerializeField] private float originNightFogDensity; // 물 밖 세상의 밤의 탁한 정도

    [SerializeField] private float breatheTime; 
    private float currentBreatheTime;

    [SerializeField] private GameObject thePlayer;

    [SerializeField] private string sound_WaterIn;
    [SerializeField] private string sound_WaterOut;
    [SerializeField] private string sound_WaterBreathe;

물 속일 때는 Fog 색깔을 파랗게 하고, Fog 밀도를 더 높여주어야 한다.

낮과 밤일 때의 각각 물 속의 Fog 색깔과 밀도가 다르다.

    void Start()
    {
        originColor = RenderSettings.fogColor;
        originFogDensity = RenderSettings.fogDensity;

        originDrag = thePlayer.GetComponent<Rigidbody>().drag; 
    }

    void Update()
    {
        if (GameManager.isWater)
        {
            currentBreatheTime += Time.deltaTime;
            if (currentBreatheTime >= breatheTime)
            {
                SoundManager.instance.PlaySE(sound_WaterBreathe);
                currentBreatheTime = 0;
            }
        }
    }

    private void OnTriggerEnter(Collider other)
    {
        if (other.transform.tag == "Player")
            GetInWater(other);  // 물에 들어감
    }

    private void OnTriggerExit(Collider other)
    {
        if (other.transform.tag == "Player")
            GetOutWater(other);  // 물에서 나옴
    }


    private void OnTriggerStay(Collider other)
    {
        if (other.transform.tag == "Player")
            SmoothColorChange();
    }

    private void SmoothColorChange()
    {
        if (!GameManager.isNight && RenderSettings.fogColor != waterColor)
            RenderSettings.fogColor = Color.Lerp(RenderSettings.fogColor, waterColor, 0.1f);

        if (GameManager.isNight && RenderSettings.fogColor != waterNightColor)
            RenderSettings.fogColor = Color.Lerp(RenderSettings.fogColor, waterNightColor, 0.1f);
    }

    private void GetInWater(Collider _player)
    {
        SoundManager.instance.PlaySE(sound_WaterIn);

        GameManager.isWater = true;
        _player.transform.GetComponent<Rigidbody>().drag = waterDrag;

        if (!GameManager.isNight) // 낮일때
        {
            RenderSettings.fogColor = waterColor;
            RenderSettings.fogDensity = waterFogDensity;
        }
        else // 밤일때
        {
            RenderSettings.fogColor = waterNightColor;
            RenderSettings.fogDensity = waterNightFogDensity;
        }
    }

    private void GetOutWater(Collider _player)
    {
        SoundManager.instance.PlaySE(sound_WaterOut);

        if (GameManager.isWater)
        {
            GameManager.isWater = false;
            _player.transform.GetComponent<Rigidbody>().drag = originDrag;

            if (!GameManager.isNight) // 낮일때
            {
                RenderSettings.fogColor = originColor;
                RenderSettings.fogDensity = originFogDensity;
            }
            else // 밤일때
            {
                RenderSettings.fogColor = originNightColor;
                RenderSettings.fogDensity = originNightFogDensity;
            }
        }
    }
}

  • Start
    • 게임이 시작되면 낮일테기 때문에 각각 originColor, originFogDensity에는 낮 상태일때의 안개 색깔, 안개 밀도 값이 들어갈 것이다.
    • 물 밖과 물 속의 플레이어의 물리적 저항력이 다르기 때문에 originDrag에 플레이어의 저항력을 가져와 저장한다.
  • Update
    • anf thrdp dlTsms ehddksdpsms breatheTime 시간 간격마다 물 속에서 숨쉬는 효과음을 재생한다.
  • OnTriggerEnter 👉 물 속을 자리하는 그 콜라이더
    • 플레이어가 물 속에 들어오면 GetInWater 호출
  • GetInWater
    • 입수하는 효과음
    • 저항력을 물에 있을 떄의 저항력으로 세팅
    • 안개 색깔과 안개 밀도를 낮인지 밤인지에 따라 각각 낮일때의 물의 안개색, 안개밀도, 밤일때의 물의 안개색, 안개밀도로 세팅한다.
  • OnTriggerExit 👉 물 속을 자리하는 그 콜라이더
    • 플레이어가 물 밖에 나가면 GetOutWater 호출
  • GetOutWater
    • GetInWater와 반대로. 물 밖 세상의 여러 변수들을 낮과 밤에 따라 설정
  • OnTriggerStay 👉 물 속을 자리하는 그 콜라이더
    • 플레이어가 물 속에 있는 동안 SmoothColorChange 호출
  • SmoothColorChange
    • 낮인데 아직 현재 안개 색깔이 낮일때의 안개 색깔로 변하지 않았다면 천천히 Lerp 로 부드럽게 바꾸게 하기. 밤일 땐 그 반대.
    • 강의엔 없었는데 추가함.

image

안개 색깔의 경우 알파값을 높여줘야 보이게 된다. 밤엔 물 속에 있으면 보라색으로 보이게끔 하였다.

image

낮에 물 속에서 보는 세상.

image

밤에 물 속에서 보는 세상.



🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

Unity Lesson 3 카테고리 내 다른 글 보러가기

댓글 남기기