Chapter 12-4. 기타 : 물 구현하기
카테고리: Unity Lesson 3
태그: Unity Game Engine
인프런에 있는 케이디님의 [유니티 3D] 실전! 생존게임 만들기 - Advanced 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
🚀 유니티에서 물 넣는 방법
- 우클 - Import Package - Environment
- 유니티 자체에서 제공하는 패키지를 임포트하면 됨. Water도 같이 제공함.
- 유니티 에셋 스토어에서 물과 관련된거 구입해서 임포트
- ✨ 직접 만들기. 아래 3개가 필요함.
- 1️⃣ 물 표면 텍스처
- 2️⃣ 물 쉐이더
- 3️⃣ 쉐이더를 입힐 물 머테리얼
🚀 물 구현하기
물 머테리얼
쉐이더 파일을 드래그해서 머테리얼에다 드롭하면 이렇게 머테리얼에 쉐이더를 간단하게 입힐 수 있다. (핫핑크 상태는 아직 머테리얼에 쉐이더가 입혀지지 않은 상태를 의미한다.)
물 오브젝트
물 표면으로 쓸 Plane
오브젝트에 물 머테리얼을 입힌다. Plane
에 기본적으로 붙어있는 Mesh Collider 는 제거해준다. 물 표면 위를 플레이어가 걸을 수 있으면 안되니까! 물 표면을 밟으면 물에 관통되어 들어갈 수 있어야 하므로 Collider를 제거해주는 것이다. 사실상 물 표면을 시각적으로 보여줄 표면 오브젝트만 있고 물 속은 텅텅 비어있는 것이다!
이렇게 물 표면 Plane
오브젝트를 여러개 만들어 물 웅덩이로 만들 공간을 덮어준다. 그리고 이들을 Water
라는 자식들로 하나로 묶어준다.
물 속에 들어가면 물 속에 들어간지를 알아야 하므로 트리거가 체크된 큰 콜라이더를 Water
에 붙이고 물 속에 넣어준다. 사실상 이 곳은 빈 공간이지만 콜라이더에 관통되면 진짜 물 속에 있는 것처럼 화면을 파랗게 해주고 저항력을 높여주는 등등 갖가지 효과를 줄것이다.
🚀 물 관련 사운드
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
시간 간격마다 물 속에서 숨쉬는 효과음을 재생한다.
- anf thrdp dlTsms ehddksdpsms
- OnTriggerEnter 👉 물 속을 자리하는 그 콜라이더
- 플레이어가 물 속에 들어오면 GetInWater 호출
- GetInWater
- 입수하는 효과음
- 저항력을 물에 있을 떄의 저항력으로 세팅
- 안개 색깔과 안개 밀도를 낮인지 밤인지에 따라 각각 낮일때의 물의 안개색, 안개밀도, 밤일때의 물의 안개색, 안개밀도로 세팅한다.
- OnTriggerExit 👉 물 속을 자리하는 그 콜라이더
- 플레이어가 물 밖에 나가면 GetOutWater 호출
- GetOutWater
- GetInWater와 반대로. 물 밖 세상의 여러 변수들을 낮과 밤에 따라 설정
- OnTriggerStay 👉 물 속을 자리하는 그 콜라이더
- 플레이어가 물 속에 있는 동안 SmoothColorChange 호출
- SmoothColorChange
- 낮인데 아직 현재 안개 색깔이 낮일때의 안개 색깔로 변하지 않았다면 천천히 Lerp 로 부드럽게 바꾸게 하기. 밤일 땐 그 반대.
- 강의엔 없었는데 추가함.
안개 색깔의 경우 알파값을 높여줘야 보이게 된다. 밤엔 물 속에 있으면 보라색으로 보이게끔 하였다.
낮에 물 속에서 보는 세상.
밤에 물 속에서 보는 세상.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글 남기기