-
07/05 수업 서바이벌 슈터카테고리 없음 2021. 7. 5. 14:17
리소스 다운
https://github.com/IJEMIN/Unity-Programming-Essence
IJEMIN/Unity-Programming-Essence
레트로의 유니티 게임 프로그래밍 에센스. Contribute to IJEMIN/Unity-Programming-Essence development by creating an account on GitHub.
github.com
조이스틱 다운로드
https://assetstore.unity.com/packages/tools/input-management/joystick-pack-107631
Joystick Pack | 입출력 관리 | Unity Asset Store
Get the Joystick Pack package from Fenerax Studios and speed up your game development process. Find this & other 입출력 관리 options on the Unity Asset Store.
assetstore.unity.com
Zombie 유니티 프로젝트 생성
[기본구현]
1. 조이스틱으로 케릭터를 컨트롤 할수 있다
2. 플레이어가 바라보는 방향으로 일정 시간마다 총알을 쏜다
3. 네비메시를 활용해서 지형을 설치한다
4. 스폰위치에 좀비가 스폰되어야 한다
5. 좀비는 플레이어를 쫒아간다
6. 플레이가 발사하는 총에 맞으면 좀비는 죽는다
7. 플레이어가 좀비에 닿으면 체력이 감소된다
8. 플레이어의 체력이 0이되면 게임이 종료 된다
9. 게임이 종료되면 처음부터 다시 시작한다.
10. 안드로이드 플랫폼 빌드후 실행결과를 확인할수 있어야 한다
[추가 구현]
1. 씨네머신 카메라를 사용해 플레이어를 따라가게 만든다
2. 플레어의 체력을 UI상에 표시 한다 (UI는 플레이어의 바닥에 붙어서 플레어가 움직일때 함께 움직여야 한다)
[순서]
플랫폼 변경 (Android)
해상도를 설정한다 (1920, 1080 Landscape)
제공된 리소스를 임포트 한다
조이스틱 어셋추가
캔버스 생성
Variable Joystick 넣기
GameMain 빈오브젝트 생성
GameMain.cs 파일 만들고 컴포넌트로 부착
케릭터 씬에 넣기
회전테스트
17/done/Zombie
리소스 취득
- 캐릭터
- 좀비
- 지형
- 총
- HP UI
새 씬 만들어서
캐릭터
좀비
건
하이어라키에 이동 후
좀비에 에너미 스크립트 제거
Woman에 GunPivot을 생성
GunPivot아래에 Gun을 추가
IKTest
https://cafe.naver.com/gameprogramming7
종로 더조은 게임 개발자 과정 3기 : 네이버 카페
종로 더조은 컴퓨터 게임 개발자 양성과정 3기 입니다.
cafe.naver.com
생성한 Zombie프로젝트를 열고
빌트세팅을 안드로이드
해상도 설정
제공된 리소스를 임포트 한다.
zombie_res.unitypackage9.88MB
조이스틱 추가Joystick Pack.unitypackage0.48MBWoman 추가
캔버스를 만들고
Variable Joystic 추가
GameMain 빈오브젝트 추가
GameMain 스크립트 생성하여 GameMain에 추가
GameMain.cs
using UnityEngine; public class GameMain : MonoBehaviour { public VariableJoystick joystic; public GameObject playerGo; private Animator anim; private void Start() { this.anim = this.playerGo.GetComponent<Animator>(); } // Update is called once per frame void Update() { var eulerAngles = new Vector3(0, Mathf.Atan2(joystic.Horizontal, joystic.Vertical) * 180 / Mathf.PI, 0); playerGo.transform.eulerAngles = eulerAngles; if (joystic.Horizontal != 0 && joystic.Vertical != 0) { this.playerGo.transform.Translate(Vector3.forward * 1.0f * Time.deltaTime); this.anim.SetFloat("Move", 1.0f); } else { this.anim.SetFloat("Move", 0f); } } }
Woman 게임 오브젝트 unpack
Gun.cs 파일 만들어서 Gun에 컴포넌트로 부착
스크립트 작성
Gun.cs
using UnityEngine; public class Gun : MonoBehaviour { public Transform firePos; private float span = 1.0f; private float delta = 0f; void Update() { this.delta += Time.deltaTime; if (this.delta > this.span) { this.delta = 0; Debug.Log("발사"); Ray ray = new Ray(this.firePos.position, firePos.forward * 1000f); //Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red, 0.1f); } } }
지형 프리팹을 가져온다
unpack한다
텍스쳐 빠져있는거 삭제
플레이어 리지드바디, 캡슐콜라이더 붙여서 지형을 뚫고 가지 못하게 만든다
Freeze Rotation x, z 체크
네비매시 굽기
Window / AI / Navigation 에서 Bake 탭에서 Bake 버튼 누르기
SpawnPoints 빈 오브젝트 만들기
point1, point2 빈오브젝트 만들어서 배치
빈오브젝트 ZombieSpawner 만들기
ZombieSpawner.cs 파일 만들어서 컴포넌트로 부착
스크립트 수정 (최대 2마리까지 생성되게)
ZombieSpawner.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ZombieSpawner : MonoBehaviour { public int maxCount = 2; public List<GameObject> zombies; public GameObject zombiePrefab; public Transform[] arrSpawnPos; // Start is called before the first frame update void Start() { this.zombies = new List<GameObject>(); this.CreateZombies(); } private void CreateZombies() { int total = this.maxCount - this.zombies.Count; for (int i = 0; i < total; i++) { var zombieGo = Instantiate<GameObject>(this.zombiePrefab); var zombie = zombieGo.GetComponent<Zombie>(); zombie.Init(this.arrSpawnPos[i].position, i); } } }
Zombie스크립트 생성후 작성
Zombie.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class Zombie : MonoBehaviour { public Action onDie; public int Id { get; private set; } public void Init(Vector3 initPos, int id) { this.transform.position = initPos; this.Id = id; } public void Hit() { Debug.Log("Hit"); this.Die(); } public void Die() { Debug.Log("Die"); this.onDie(); } }
좀비가 죽으면 두개의 스판포인트중 랜덤으로 좀비 생성
ZombieSpawner.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; public class ZombieSpawner : MonoBehaviour { public int maxCount = 2; public List<GameObject> zombies; public GameObject zombiePrefab; public Transform[] arrSpawnPos; // Start is called before the first frame update void Start() { this.zombies = new List<GameObject>(); this.CreateZombies(); } private void CreateZombies() { int total = this.maxCount - this.zombies.Count; for (int i = 0; i < total; i++) { var zombieGo = Instantiate<GameObject>(this.zombiePrefab); var zombie = zombieGo.GetComponent<Zombie>(); zombie.Init(this.arrSpawnPos[Random.Range(0, 2)].position); this.zombies.Add(zombie.gameObject); zombie.onDie = () => { this.zombies.Remove(zombie.gameObject); Destroy(zombie.gameObject); this.CreateZombies(); }; } } }
Zombie.cs
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using System; public class Zombie : MonoBehaviour { public Action onDie; private bool isFollow; private NavMeshAgent agent; private float delta; private float span = 1; public void Init(Vector3 initPos) { this.transform.position = initPos; this.isFollow = true; this.agent = this.GetComponent<NavMeshAgent>(); } public void Hit() { Debug.Log("Hit"); this.Die(); } public void Die() { Debug.Log("Die"); this.onDie(); } private void Update() { if (this.isFollow) { var player = GameObject.Find("Woman"); if (player != null) { this.transform.LookAt(player.transform); this.agent.SetDestination(player.transform.position); var dis = Vector3.Distance(player.transform.position, this.transform.position); if (dis < 1f) { this.isFollow = false; this.agent.isStopped = true; } } } else { this.delta += Time.deltaTime; if (this.delta > this.span) { this.delta = 0; this.isFollow = true; this.agent.isStopped = false; } } } }
Gun.cs
using UnityEngine; public class Gun : MonoBehaviour { public Transform firePos; private float span = 1.0f; private float delta = 0f; void Update() { this.delta += Time.deltaTime; if (this.delta > this.span) { this.delta = 0; //Debug.Log("발사"); Ray ray = new Ray(this.firePos.position, firePos.forward * 1000f); RaycastHit hit; if (Physics.Raycast(ray, out hit, 1000)) { if (hit.collider.tag == "zombie") { var zombie = hit.transform.GetComponent<Zombie>(); zombie.Hit(); } } //Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red, 0.1f); } } }
GameMain.cs
using UnityEngine; using System.Linq; using System.Collections.Generic; using System; public class GameMain : MonoBehaviour { public VariableJoystick joystic; public GameObject playerGo; private Animator anim; private void Start() { this.anim = this.playerGo.GetComponent<Animator>(); this.joystic.onPointerUpHandler = () => { var zombies = GameObject.FindObjectsOfType<Zombie>(); Debug.Log("zombies: " + zombies.Count()); List<Tuple<float, Zombie>> list = new List<Tuple<float, Zombie>>(); foreach (var zombie in zombies) { var dis = Vector3.Distance(zombie.transform.position, this.playerGo.transform.position); var tuple = new Tuple<float, Zombie>(dis, zombie); list.Add(tuple); } list.Sort(); foreach (var t in list) { Debug.LogFormat("{0}, {1}", t.Item1, t.Item2); } var first = list.FirstOrDefault(); Debug.Log("first: " + first); if (first != null) { this.playerGo.transform.LookAt(first.Item2.transform); } }; } // Update is called once per frame void Update() { if (joystic.Horizontal != 0 && joystic.Vertical != 0) { var eulerAngles = new Vector3(0, Mathf.Atan2(joystic.Horizontal, joystic.Vertical) * 180 / Mathf.PI, 0); playerGo.transform.eulerAngles = eulerAngles; this.playerGo.transform.Translate(Vector3.forward * 1.0f * Time.deltaTime); this.anim.SetFloat("Move", 1.0f); } else { this.anim.SetFloat("Move", 0f); } } }
Zombie 수정
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.AI; using System; public class Zombie : MonoBehaviour { public Action onDie; private bool isFollow; private NavMeshAgent agent; private float delta; private float span = 1; private Animator anim; public void Init(Vector3 initPos) { this.transform.position = initPos; this.isFollow = true; this.agent = this.GetComponent<NavMeshAgent>(); this.anim = this.GetComponent<Animator>(); } public void Hit() { Debug.Log("Hit"); this.Die(); } public void Die() { Debug.Log("Die"); this.onDie(); } private void Update() { if (this.isFollow) { this.anim.SetBool("HasTarget", true); var player = GameObject.Find("Woman"); if (player != null) { this.transform.LookAt(player.transform); this.agent.SetDestination(player.transform.position); var dis = Vector3.Distance(player.transform.position, this.transform.position); if (dis < 1f) { this.isFollow = false; this.agent.isStopped = true; this.anim.SetBool("HasTarget", false); } } } else { this.delta += Time.deltaTime; if (this.delta > this.span) { this.delta = 0; this.isFollow = true; this.agent.isStopped = false; } } } }
https://cafe.naver.com/gameprogramming7/423
게임플랫폼응용프로그래밍
목표: 모바일 기기 (android 플랫폼)에서 실행되는 좀비 서버이버 슈터 게임을 제작해 빌드 리소스 준비 https://github.com/IJEMIN/Unity-P...
cafe.naver.com