Unity
[유니티] RPG 게임 만들기2
Skull Crusher
2021. 5. 28. 10:37
728x90
1. Trail Renderer
Width -> Color -> Element 설정
2.
Player -> Window -> Animation -> Attack1 -> Add event 추가
3.
4. 추적 카메라 추가
5. 슬라임 프리펩 추가
쉐이더 변경
애니메이터 추가
6. 애니스테이트 활용
7. 공격 피격 콜라이더 추가
8. foreach in 사용
Add Layer -> Monster = Attack Layer Name
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterAttackController : MonoBehaviour
{
[SerializeField] private Animator animator;
public bool isAttack; // 공격 여부
[SerializeField] private CharacterAttack characterAttack;
[SerializeField] private string attackLayerName;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (isAttack) return;
if (Input.GetKeyDown(KeyCode.Z))
{
animator.SetTrigger("Attack1");
}
else if (Input.GetKeyDown(KeyCode.X))
{
animator.SetTrigger("Attack2");
}
}
public void OnNormalAttackAnimationEvent()
{
characterAttack.Attack(attackLayerName);
}
public void OnSkillAttackAnimationEvent()
{
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterAttack : MonoBehaviour
{
public Transform attackHitPoint; //피격 위치 포인트 참조
public float attackRange; // 공격 범위
public int damage; // 데미지
//이펙트 표현이 필요한 공격에 수행할 이펙트 참조
public GameObject attackShowEffectPrefab;
//현재 공격이 피결될때 표현될 이펙트 참조
public GameObject attackHitEffectPrefab;
private void AttackShowEffect()
{
if (attackShowEffectPrefab = null) return;
Instantiate(attackShowEffectPrefab, attackHitPoint.position, Quaternion.identity);
}
// 디폴트 매개변수 : 호출시 생략이 가능한 매개변수 (생략시 디폴트값으로 적용)
// * 디폴트 매개변수는 오른쪽부터 적용 가능
// isKnockBack 매개변수는 디폴트 값으로 false를 설정함
// 호출방식1 -> Attack(레이어이름, true/false)
// 호출방식2 -> Attack(레이어이름) <==== 매개변수값 생략 가능 (생략시 디폴트 값으로 적용)
// 호출방식3 -> Attack();
public void Attack(string layerName, bool isKnockBack = false)
{
AttackShowEffect(); // 공격시 이펙트 재생
// Physics.OverlapSphere(충돌체크위치, 검출위치, 1 << LayerMask.NameToLayer(충돌레이어);
Collider[] hitMonsters = Physics.OverlapSphere(attackHitPoint.position,
attackRange, 1 << LayerMask.NameToLayer(layerName));
// foreach : 순차적으로 목록화된 배열에서 순차적으로 하나의 요소를 접근할 때 사용하는 for 개량형 문법
// foreach (요소변수 in 배열(컬렉션)변수)
//{...}
// for (int i=0; i<hitMonsters.Length; i++)
foreach (Collider hitMonster in hitMonsters)
{
Debug.Log(hitMonster.name + ", " + hitMonster.transform.position);
}
}
}
9. 이펙트 prefabs 파일에 옮기기
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
// 몬스터 체력/피격
public class MonsterHealth : MonoBehaviour
{
// 피격 이펙트 생성 위치
[SerializeField] private Transform hitEffectTrans;
[SerializeField] private float knockBackSize; // 뒤로 밀리는 크기
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
public void Damage(GameObject hitEffectPrefab, int damage, bool isKnockBack = false)
{
//넉백이 데미지일 경우
if (isKnockBack)
{
// 몬스터를 뒤로 밈
transform.Translate(-Vector3.forward * knockBackSize);
}
// 체력 감소
Instantiate(hitEffectPrefab, hitEffectTrans.position, Quaternion.identity);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterAttack : MonoBehaviour
{
public Transform attackHitPoint; //피격 위치 포인트 참조
public float attackRange; // 공격 범위
public int damage; // 데미지
//이펙트 표현이 필요한 공격에 수행할 이펙트 참조
public GameObject attackShowEffectPrefab;
//현재 공격이 피결될때 표현될 이펙트 참조
public GameObject attackHitEffectPrefab;
private void AttackShowEffect()
{
if (attackShowEffectPrefab = null) return;
Instantiate(attackShowEffectPrefab, attackHitPoint.position, Quaternion.identity);
}
// 디폴트 매개변수 : 호출시 생략이 가능한 매개변수 (생략시 디폴트값으로 적용)
// * 디폴트 매개변수는 오른쪽부터 적용 가능
// isKnockBack 매개변수는 디폴트 값으로 false를 설정함
// 호출방식1 -> Attack(레이어이름, true/false)
// 호출방식2 -> Attack(레이어이름) <==== 매개변수값 생략 가능 (생략시 디폴트 값으로 적용)
// 호출방식3 -> Attack();
public void Attack(string layerName, bool isKnockBack = false)
{
AttackShowEffect(); // 공격시 이펙트 재생
// Physics.OverlapSphere(충돌체크위치, 검출위치, 1 << LayerMask.NameToLayer(충돌레이어);
Collider[] hitMonsters = Physics.OverlapSphere(attackHitPoint.position,
attackRange, 1 << LayerMask.NameToLayer(layerName));
// foreach : 순차적으로 목록화된 배열에서 순차적으로 하나의 요소를 접근할 때 사용하는 for 개량형 문법
// foreach (요소변수 in 배열(컬렉션)변수)
//{...}
// for (int i=0; i<hitMonsters.Length; i++)
foreach (Collider hitMonster in hitMonsters)
{
hitMonster.GetComponent<MonsterHealth>().Damage(attackHitEffectPrefab, damage, true);
Debug.Log(hitMonster.name + ", " + hitMonster.transform.position);
}
}
}
10. 몬스터에 체력바 만들기
UI -> Canvas
그림판 -> box.png
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
// 몬스터 체력/피격
public class MonsterHealth : MonoBehaviour
{
// 피격 이펙트 생성 위치
[SerializeField] private Transform hitEffectTrans;
[SerializeField] private float knockBackSize; // 뒤로 밀리는 크기
[SerializeField] private int hp; // 총 체력
private int currentHp; // 현재 체력
[SerializeField] private Image hpPregressImage;
// Start is called before the first frame update
void Start()
{
currentHp = hp; // 체력 설정
}
public void HpDown(int downValue)
{
if (currentHp < 0) return;
currentHp = -downValue; // 체력 감소
float resultHp = currentHp / hp; // 현재 체력의 비율을 계산
hpPregressImage.fillAmount = resultHp; // 비율값을 체력 게이지에 적용
}
public void Damage(GameObject hitEffectPrefab, int damage, bool isKnockBack = false)
{
//넉백이 데미지일 경우
if (isKnockBack)
{
// 몬스터를 뒤로 밈
transform.Translate(-Vector3.forward * knockBackSize);
}
// 체력 감소
HpDown(damage);
// 피격 처리에 사용될 이펙트를 생성함
Instantiate(hitEffectPrefab, hitEffectTrans.position, Quaternion.identity);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class UIBillboard : MonoBehaviour
{
// Update is called once per frame
void LateUpdate()
{
//메인 카메라의 시선과 일치하게 UI 게임오브젝트의 시선을 회전함
transform.rotation = Quaternion.LookRotation(Camera.main.transform.forward);
}
}