반응형
1. 소개
- 원터치 2D 캐쥬얼
- 스테이지 클리어 방식
- SQL, PHP
- Unity 2017.3.0f
- 메인 프로그래머
- 모바일
- 제작기간: 1개월
2. 핵심 컨텐츠
![]() 물고기 잡기 |
![]() 원하는 물고기 선택 |
![]() 랭킹등록 |
3. 구현
3.1 물고기 세팅(메모리 풀링)
![]() 메모리 풀링 시 로딩전환 |
![]() SQL에 저장된 물고기 정보들 가져오기 (Cafe24) 음수 값들의 물고기들은 잘못된 것이 아니다. 내 기획이다 ^^;; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <?php $code = $_POST['code']; $con = mysql_connect("localhost","hki234","안알랴쥼"); if(!$con) die('Could not Connect:' .mysql_error()); mysql_select_db("hki234", $con) or die("could not load the database" .mysql_error()); $check = mysql_query("SELECT NAME_KOR, NAME_ENG, HEALTH, ARMOR, PLASTIC, PRICE FROM LOF_FISHES WHERE CODE = '".$code."'"); $numrows = mysql_num_rows($check); if($numrows == 0) { die("".$code." does not exist. \n"); } else { //fetch_assoc - 가져온 변수 배열저장 while($row = mysql_fetch_assoc($check)) { if($code == $row['CODE']) { echo("". $row['NAME_KOR']." \n"); die("Log in - Success!!"); } else { die("Name does not Match. \nConnect Success!!"); } } } ?> | cs |
Cafe24쪽에 올라간 PHP
연동되어있는 FileZila로 불러왔던 걸로 기억한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 | using UnityEngine; using System.Collections.Generic; using System.Collections; public class DataManager : MonoBehaviour { private string fishUrl = "https://hki234.cafe24.com/LoadFish.php"; //프레임당 한 번만 불러오도록 하는 변수 private bool loadData = false; public bool Load_Data { get { return loadData; } } //데이터 불러오면 참으로 변환 private bool dataOn = false; public bool Data_On { get { return dataOn; } } //지정된 해안의 모든 물고기 저장 [SerializeField] private List<Fish> fishDataList; public List<Fish> Fish_Data_List { get { return fishDataList; } } private LoadFishManager loadFishManager; private GameObject fish; public void Load_FIsh(OCEAN_TYPE ocean, LoadFishManager _l, GameObject _f) { loadData = true; //물고기 전체 수가 맞아 떨어지는 지 체크 //맞아 떨어지면 Load에서 다음으로 전환 loadFishManager = _l; fish = _f; StartCoroutine(WWW_FISH(ocean)); } private IEnumerator WWW_FISH(OCEAN_TYPE ocean) { WWWForm form = new WWWForm(); string oceanText; switch(ocean) { case OCEAN_TYPE.PACIFIC: oceanText = "PACIFIC"; break; case OCEAN_TYPE.INDIA: oceanText = "INDIA"; break; case OCEAN_TYPE.ANTARCTIC: oceanText = "ANTARCTIC"; break; case OCEAN_TYPE.ATLANTIC: oceanText = "ATLANTIC"; break; case OCEAN_TYPE.ARCTIC: oceanText = "ARCTIC"; break; default: oceanText = "PACIFIC"; break; } form.AddField("ocean", "PACIFIC"); WWW webRequest = new WWW(fishUrl, form); //데이터 받아오기 do { yield return null; } while (!webRequest.isDone); if (webRequest.error != null) { yield break; } //데이터 저장 - 컨테이너로 옮기기 //크게 *로 자른뒤 뒤에서 |로 개별데이터를 자른다. string fishData = webRequest.text; var dataContainer = fishData.Split("*"[0]); //가상 물고기 생산 //좌표는 아예 안보이게 셋엑티브 끔 for (int i = 0; i < dataContainer.Length - 1; i++) { GameObject clone = Instantiate(fish); clone.transform.parent = this.transform; clone.SetActive(false); /******************나름의 직렬화*******************/ var fishContainer = dataContainer[i].Split("|"[0]); OCEAN_TYPE _ocean; if (fishContainer[1].Contains("PACIFIC")) { _ocean = OCEAN_TYPE.PACIFIC; } else if (fishContainer[1].Contains("ANTARCTIC")) { _ocean = OCEAN_TYPE.ANTARCTIC; } else if (fishContainer[1].Contains("ARCTIC")) { _ocean = OCEAN_TYPE.ARCTIC; } else if (fishContainer[1].Contains("INDIA")) { _ocean = OCEAN_TYPE.INDIA; } else if (fishContainer[1].Contains("ATLANTIC")) { _ocean = OCEAN_TYPE.ATLANTIC; } else { _ocean = OCEAN_TYPE.PACIFIC; } clone.GetComponent<Fish>().InitInfo( int.Parse(fishContainer[0]), _ocean, fishContainer[2], fishContainer[3], int.Parse(fishContainer[4]), int.Parse(fishContainer[5]), int.Parse(fishContainer[6]), int.Parse(fishContainer[7])); fishDataList.Add(clone.GetComponent<Fish>()); } //여기까지 왔다면 데이터가 모두 준비되었을 경우다. dataOn = true; } } | cs |
Unity에선 DataManager 단에서 전체 물고기의 데이터를 관리한다.
원래 기획은 5대양 별 물고기로 기획되었으나, 기간이 줄어 그냥 대양 구분 없이 물고기가 생성된다.
3.2 게임 구현
단순 터치 방식이며, Raycast를 수직으로 쏴 가리키는 물고기의 체력을 깎는다.
물고기 체력이 다 닳게 되면 잡는 것이다.
시간 제한은 위 창에 존재하며, 좌측 상단에는 잡은 물고기 수다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | using System.Collections; using System.Collections.Generic; using UnityEngine; //참고 블로그 //http://ateliersera.blog.me/220439790504 //터치해서 적에게 데미지를 가함 public class PlayerManager : MonoBehaviour { public void Init() { } public void Updated() { UpdatedInputs(); } public void UpdatedInputs() { //위는 3D코드 아래는 2D코드 //ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Input.GetMouseButtonDown(0)) { RaycastHit2D hit = Physics2D.Raycast( Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1.0f)), Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 100.0f))); if (hit.collider != null) { hit.transform.gameObject.GetComponent<Fish>().Hit(); } } Debug.DrawLine( Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 1.0f)), Camera.main.ScreenToWorldPoint(new Vector3(Input.mousePosition.x, Input.mousePosition.y, 100.0f)), Color.red); } } | cs |
여타 캐릭터가 없어 걍 PlayerManager 단에서 모든 구현이 끝난다.
RPG 만들다 캐릭터 수에 기겁해서 그냥 다 때려쳤다는 것이 정설...
3.3 랭킹등록
![]() |
![]() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | <?php $id = $_POST['id']; $price = $_POST['price']; $con = mysql_connect("localhost","hki234","안알랴쥰다용"); if(!$con) die('Could not Connect:' .mysql_error()); mysql_select_db("hki234", $con) or die("could not load the database" .mysql_error()); //이름이 있는 경우엔 넣지 못함 $check = mysql_query("SELECT * FROM LOF_RANKING WHERE ID = '$id'"); $numrows = mysql_num_rows($check); if($numrows != 0) { echo("ID is Already Existence!!"); while($row = mysql_fetch_assoc($check)) { if($price == $row['PRICE']) { die("PRICE is Already Existence!! Shut Down!!"); } } } //여기까지 왔다는 것은 1차 검열을 통과했다는 뜻 mysql_query("INSERT INTO LOF_RANKING (ID, PRICE) VALUES ('$id', '$price')"); echo "Insert Success"; //아래 정렬로 다시 랭킹을 산출한다. $rankingCheck = mysql_query("SELECT * FROM LOF_RANKING ORDER BY PRICE DESC"); $minRank = 0; while($rankingRow = mysql_fetch_assoc($rankingCheck)) { //이 순위 아래는 데이터를 삭제한다. //8 - 남아있는 데이터 수 if($minRank >= 8) { echo ("$minRank"); mysql_query("DELETE FROM LOF_RANKING WHERE ID = '".$rankingRow['ID']."' AND PRICE = '".$rankingRow['PRICE']."'"); } $minRank++; } ?> | cs |
PHP 소스다.
랭킹을 올릴 때에 필터링을 구현해 보았다.
여기서는 랭킹 밖에 있을 경우 데이터가 삭제된다!
4. 정리하기
Server 개념을 게임에 처음 접목시켜보았다. 물론, 지금 만들라면 로컬 서버를 띄워 만들어보겠지만, 자격증(정처기)으로만 남아있던 서버지식을 활용해보는 시간이었다.
게임 구현보다는 시스템 이해에 더 시간을 쏟았었다.
반응형
'UNITY' 카테고리의 다른 글
Guising [팀 제작게임, Mobile 2D, 턴제 RPG] (0) | 2024.05.15 |
---|---|
메르헨엘리스 [팀 자체제작, 3D, 착시효과] (0) | 2024.05.03 |
PACMAN [개인 모작] (0) | 2021.09.05 |
ASTROBOX [팀 자체제작, 3D, 퍼즐] (0) | 2021.09.05 |