이번 시간에는 전투로 인한 캐릭터 파라미터를 만들고 변경되는 부분을 처리 하겠습니다
새로운 스크립트를 생성하고 이름을 CharacterParams 합니다
CharacterParams 스크립트 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//CharacterParams는 플레이어의 파라미터 클래스와 몬스터 파라미터 클래스의 부모 클래스 역할을 하게됨
public class CharacterParams : MonoBehaviour
{
//퍼블릭 변수가 아니라 약식프로퍼티,속성으로 지정
//퍼블릭 변수와 똑같이 사용할수 있지만 유니티 인스펙터에 노출되는 것을 막고 보안을 위해정식 프로퍼티로 전환이 쉬워짐
public int level { get; set; }
public int maxHp { get; set; }
public int curHp { get; set; }
public int attackMin { get; set; }
public int attackMax { get; set; }
public int defense { get; set; }
public bool isDead { get; set; }
void Start()
{
InitParams();
}
//나중에 CharacterParams 클래스를 상속한 자식클래스 에서
//InitParams 함수 에 자신만의 명령어를 추가하기만 하면 자동으로 필요한 명령어드이 실행
public virtual void InitParams()
{
}
public int GetRandomAttack()
{
int randAttack = Random.Range(attackMin, attackMax + 1);
return randAttack;
}
public void SetEnemyAttack(int enemyAttackPower)
{
curHp -= enemyAttackPower;
UpdateAfterReceiveAttack();
}
//캐릭터가 적으로 부터 공격을 받은 뒤에 자동으로 실행될 함수를 가상함수로 만듬
protected virtual void UpdateAfterReceiveAttack()
{
print(name + "'s HP: " + curHp);
}
}
그리고 새로운 스크립트를 생성하고 이름을 EnemyParams라 합니다
EnemyParams 스크립트 작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemyParams : CharacterParams
{
public string name;
public int exp { get; set; }
public int rewardMoney { get; set; }
public override void InitParams()
{
name = "Monster";
level = 1;
maxHp = 50;
curHp = maxHp;
attackMin = 2;
attackMax = 5;
defense = 1;
exp = 10;
rewardMoney = Random.Range(10, 31);
isDead = false;
}
protected override void UpdateAfterReceiveAttack()
{
base.UpdateAfterReceiveAttack();
}
}
그리고 새로운 스크립트를 만들고 이름을 PlayerParams 라 합니다
PlayerParams 스크립트작성
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerParams : CharacterParams
{
public string name { get; set; }
public int curExp { get; set; }
public int expToNextLevel { get; set; }
public int money { get; set; }
public override void InitParams()
{
name = "hong";
level = 1;
maxHp = 100;
curHp = maxHp;
attackMin = 5;
attackMax = 8;
defense = 1;
curExp = 0;
expToNextLevel = 100 * level;
money = 0;
isDead = false;
}
protected override void UpdateAfterReceiveAttack()
{
base.UpdateAfterReceiveAttack();
}
}
Player 오브젝트를 선택하고 PlayerParams 스크립트를 Player 에 붙힘니다
Enemy 오브젝트를 선택하고 EnemyParams 스크립트를 Enemy에 붙힘니다
그리고 PlayerFSM 스크립트를 선택하고 수정하겠습니다
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerFSM : MonoBehaviour
{
public enum State
{
Idle,
Move,
Attack,
AttackWait,
Dead
}
//idle 상태를 기본 상태로 지정
public State currentState = State.Idle;
//마우수 클릭 지점,플레이어가 이동할 목적지의 좌표를 저장할 예정
Vector3 curTargetPos;
GameObject curEnemy;
public float rotAnglePerSecond = 360f; //1초에 플레이어의 방향을 360도 회전한다
public float moveSpeed = 2f; //초당 2미터의 속도로 이동
float attackDelay = 2f; // 공격을 한번하고 다시 공격할때 까지의 지연시간
float attackTimer = 0f; //공격을 하고 난 뒤에 경과되는 시간을 계산하기 위한 변수
float attackDistance = 1.5f; // 공격 거리 (적과의 거리)
float chaseDistance = 2.5f; // 전투 중 적이 도망가면 다시 추적을 시작 하기 위한 거리
PlayerAni myAni;
PlayerParams myParams;
EnemyParams curEnemyParams;
void Start()
{
myAni = GetComponent<PlayerAni>();
// myAni.ChangeAni(PlayerAni.ANI_WALK);
myParams = GetComponent<PlayerParams>();
myParams.InitParams();
ChangeState(State.Idle, PlayerAni.ANI_IDLE);
}
public void AttackCalculate()
{
if (curEnemy == null)
{
return;
}
curEnemy.GetComponent<EnemyFSM>().ShowHitEffect();
int attackPower = myParams.GetRandomAttack();
curEnemyParams.SetEnemyAttack(attackPower);
}
// 적을 공격하기 위한 함수
public void AttackEnemy(GameObject enemy)
{
if (curEnemy != null && curEnemy == enemy)
{
return;
}
//적(몬스터)의 파라미터를 변수에 저장
curEnemyParams = enemy.GetComponent<EnemyParams>();
if (curEnemyParams.isDead == false)
{
curEnemy = enemy;
curTargetPos = curEnemy.transform.position;
ChangeState(State.Move, PlayerAni.ANI_WALK);
}
else
{
curEnemyParams = null;
}
}
void ChangeState(State newState, int aniNumber)
{
if (currentState == newState)
{
return;
}
myAni.ChangeAni(aniNumber);
currentState = newState;
}
//캐릭터의 상태가 바뀌면 어떤 일이 일어날지 를 미리 정의
void UpdateState()
{
switch (currentState)
{
case State.Idle:
IdleState();
break;
case State.Move:
MoveState();
break;
case State.Attack:
AttackState();
break;
case State.AttackWait:
AttackWaitState();
break;
case State.Dead:
DeadState();
break;
default:
break;
}
}
void IdleState()
{
}
void MoveState()
{
TurnToDestination();
MoveToDestination();
}
void AttackState()
{
attackTimer = 0f;
//transform.LookAt(목표지점 위치) 목표지점을 향해 오브젝트를 회전 시키는 함수
transform.LookAt(curTargetPos);
ChangeState(State.AttackWait, PlayerAni.ANI_ATKIDLE);
}
void AttackWaitState()
{
if (attackTimer > attackDelay)
{
ChangeState(State.Attack, PlayerAni.ANI_ATTACK);
}
attackTimer += Time.deltaTime;
}
void DeadState()
{
}
//MoveTo(캐릭터가 이동할 목표 지점의 좌표)
public void MoveTo(Vector3 tPos)
{
curEnemy = null;
curTargetPos = tPos;
ChangeState(State.Move, PlayerAni.ANI_WALK);
}
void TurnToDestination()
{
// Quaternion lookRotation(회전할 목표 방향) : 목표 방향은 목적지 위치에서 자신의 위치를 빼면 구함
Quaternion lookRotation = Quaternion.LookRotation(curTargetPos - transform.position);
//Quaternion.RotateTowards(현재의 rotation값, 최종목표rotation 값, 최대 회전각)
transform.rotation = Quaternion.RotateTowards(transform.rotation, lookRotation, Time.deltaTime * rotAnglePerSecond);
}
void MoveToDestination()
{
//Vector3.MoveTowards(시작지점, 목표지점,최대이동거리)
transform.position = Vector3.MoveTowards(transform.position, curTargetPos,moveSpeed * Time.deltaTime);
if (curEnemy == null)
{
//플레이어의 위치와 목표지점의 위치가 같으면, 상태를 Idle 상태로 바꾸라는 명령
if (transform.position == curTargetPos)
{
ChangeState(State.Idle, PlayerAni.ANI_IDLE);
}
}
else if (Vector3.Distance(transform.position,curTargetPos) < attackDistance)//Vector3.Distance(A,B):A와B사이의 거리
{
ChangeState(State.Attack, PlayerAni.ANI_ATTACK);
}
}
void Update()
{
UpdateState();
}
}
게임을 실행하고 플레이어가 적을 공격하였을때 콘솔창에 적의 HP 가 깍이는 것을 확인합니다
'게임 만들기 강좌 > 유니티 3D RPG 게임만들기' 카테고리의 다른 글
unity 유니티 게임 만들기 RPG 게임만들기 14 공격 애니메이션 타이밍 맞추기 및 플레이어 데미지 처리 (1) | 2019.07.06 |
---|---|
unity 유니티 게임 만들기 RPG 게임만들기 13 Unity Event 및 Send Message() (0) | 2019.07.05 |
unity 유니티 게임 만들기 RPG 게임만들기 11 hit Effect 만들기 (0) | 2019.07.03 |
unity 유니티 게임 만들기 RPG 게임만들기 10 EnemyFSM 및 Player 추적하기 (1) | 2019.07.02 |
unity 유니티 게임 만들기 RPG 게임만들기 9 적 공격 함수 만들기 (0) | 2019.07.01 |