오늘은 어제에 이어서 캐릭터 구현을 해보려고 한다.
일단은 조이스틱 과 키보드 둘다 되게하고싶은데 키보드 먼저 구현을 해보려고한다.
나는 캐릭터가 조작키를 땠는데 미끄러지는 느낌을 좋아하지않아서
GetAxisRaw 를 사용하는것을 좋아한다
GetAxis 와 Raw 의 차이점은 Axis 는 약간 자동차 운전과같다고 보면되고 Raw는 테트리스같은 느낌이라고 생각하면된다.
Character 스크립트 추가후
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterManger : MonoBehaviour
{
public float moveSpeed = 10f;
Rigidbody body;
Animator myanim;
Vector3 movement;
void Awake()
{
myanim = GetComponent<Animator>();
body = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
move();
}
void move()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
movement.Set(h, 0, v);
if(h ==0 && v == 0)
{
myanim.SetBool("IsMoving", false);
}
else
{
myanim.SetBool("IsMoving", true);
}
movement=movement.normalized*moveSpeed*Time.deltaTime;
body.MovePosition(transform.position + movement);
}
}
학원에서 알려준대로 만들려니까 너무 복잡해져서 인터넷에 쳐보니 좋은 자료들이 많아서 많이 읽어보고 그 중에 내가원하는 조작감이 뭘까 생각해서 코드를 짜면서 진행했고 이렇게 코드를 짜면 캐릭터가 이동된다.
코드는 골드메탈님 영상을 참고했다.
이제 캐릭터 회전을 구현해보려고한다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterManger : MonoBehaviour
{
public float moveSpeed = 10f;
public float rotationSpeed = 5f;
Rigidbody body;
Animator myanim;
Vector3 movement;
void Awake()
{
myanim = GetComponent<Animator>();
body = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
move(h,v);
turn(h, v);
}
void move(float h, float v)
{
movement.Set(h, 0, v);
if(h ==0 && v == 0)
{
myanim.SetBool("IsMoving", false);
}
else
{
myanim.SetBool("IsMoving", true);
}
movement=movement.normalized*moveSpeed*Time.deltaTime;
body.MovePosition(transform.position + movement);
}
void turn(float h, float v)
{
if (h == 0 && v == 0)
return;
Quaternion Rotation = Quaternion.LookRotation(movement);
body.rotation = Quaternion.Slerp(body.rotation, Rotation,rotationSpeed*Time.deltaTime);
}
}
회전까지 구현하고보니 raw를 하면 입력값이 적어도 일정거리를 이동하기때문에 불편한게있는거같아서 raw를빼려한다 .
카메라회전을 위해서 스크립트 작성후 아래 스크립트를 썼다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CarmeraManger : MonoBehaviour
{
GameObject player;
public float x = 0f;
public float y = 4f;
public float z = -5f;
Vector3 cameraPosition;
private void Awake()
{
player = GameObject.FindWithTag("Player");
}
private void LateUpdate()
{
cameraPosition.x = player.transform.position.x + x;
cameraPosition.y = player.transform.position.y + y;
cameraPosition.z = player.transform.position.z + z;
transform.position = cameraPosition;
}
}
player 는 지금은 Archer 하나지만 나중에 추가로 구현하게될수있기때문에 tag 로 구분하여 받기로했다 왜냐면 하나만 생성되기때문에
카메라에위치는 캐릭터포지션 + flot 값을 줬고 lateupdate를 쓴이유는 제일 마지막에 업데이트가 되기위해서이다.
-------D+7 여기까지 작성했는데 글쓰는걸 까먹고 너무졸려서 컴퓨터를 바로꺼버렸다.
이렇게보니 움직임이 너무어색하다
캐릭터에 학원에서배운 STATE 상태로 구분짖는거를 하려고한다 .
public enum State
{
CREATE, IDLE, BATTLE,DIE
}
캐릭터 스크립트 부분에 캐릭터 스테이트를 enum 으로 추가해준다
그리고 state 는 항상 세트로 같이다니는 코드가있다 강사님이 말씀해주신건데
void ChangeState(State s)
{
if (myState == s) return;
myState = s;
switch (myState)
{
case State.CREATE:
break;
case State.IDLE:
break;
case State.BATTLE:
break;
case State.DIE:
break;
}
}
protected void StateProcess()
{
switch (myState)
{
case State.CREATE:
break;
case State.IDLE:
break;
case State.BATTLE:
break;
case State.DIE:
break;
}
}
뼈대는 이렇게 구성되고
일단은 배틀상태일때 활을 꺼내는 애니메이션이 끝나는 동시에 손에 활이생기게 끔 하고
일반상태로 돌아갈때는 꽂는 애니메이션이 없어서 그냥 false 로 해주었고
그리고 활을 꺼낼동안에 움직이길레 움직임을 막기위해 애니메이션 파라메터 를 하나 추가해줘서
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EqipBow : StateMachineBehaviour
{
// OnStateEnter is called when a transition starts and the state machine starts to evaluate this state
override public void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.SetBool("EqipBow", true);
}
// OnStateUpdate is called on each Update frame between OnStateEnter and OnStateExit callbacks
//override public void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
//
//}
// OnStateExit is called when a transition ends and the state machine finishes evaluating this state
override public void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
{
animator.SetBool("EqipBow", false);
}
// OnStateMove is called right after Animator.OnAnimatorMove()
//override public void OnStateMove(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
// // Implement code that processes and affects root motion
//}
// OnStateIK is called right after Animator.OnAnimatorIK()
//override public void OnStateIK(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
//{
// // Implement code that sets up animation IK (inverse kinematics)
//}
}
이런식으로 들어갈때 true 나올때 false 로 바뀌게끔하여 저 true false 를 이용하여 애니메이션 끝나는 타이밍에 다시 이동 할수있게끔 해주었다 코드를보면
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterManger : MonoBehaviour
{
public enum State
{
CREATE, IDLE, BATTLE,DIE
}
public State myState = State.CREATE;
public GameObject Backbow;
public GameObject Handbow;
float moveSpeed = 6f;
float rotationSpeed = 5f;
Rigidbody body;
Animator myanim;
Vector3 movement;
void Awake()
{
myanim = GetComponent<Animator>();
body = GetComponent<Rigidbody>();
}
void FixedUpdate()
{
float h = Input.GetAxis("Horizontal");
float v = Input.GetAxis("Vertical");
move(h,v);
turn(h, v);
if(Input.GetMouseButtonUp(0))
{
ChangeState(State.BATTLE);
}
if (Input.GetMouseButton(1))
{
ChangeState(State.IDLE);
}
}
void move(float h, float v)
{
movement.Set(h, 0, v);
if(h ==0 && v == 0 )
{
myanim.SetBool("IsMoving", false);
}
else if( myanim.GetBool("EqipBow") != true)
{
myanim.SetBool("IsMoving", true);
}
if (myanim.GetBool("EqipBow") != true)
{
movement = movement.normalized * moveSpeed * Time.deltaTime;
body.MovePosition(transform.position + movement);
}
}
void turn(float h, float v)
{
if (h == 0 && v == 0 )
return;
else if(myanim.GetBool("EqipBow") != true)
{
Quaternion Rotation = Quaternion.LookRotation(movement);
body.rotation = Quaternion.Slerp(body.rotation, Rotation, rotationSpeed * Time.deltaTime);
}
}
void ChangeState(State s)
{
if (myState == s) return;
myState = s;
switch (myState)
{
case State.CREATE:
Backbow.SetActive(true);
Handbow.SetActive(false);
break;
case State.IDLE:
myanim.SetTrigger("Idle");
if(Backbow.activeSelf==false)
Backbow.SetActive(true);
if (Handbow.activeSelf== true)
Handbow.SetActive(false);
break;
case State.BATTLE:
moveSpeed = 3f;
myanim.SetTrigger("Battle");
Backbow.SetActive(false);
Handbow.SetActive(true);
break;
case State.DIE:
break;
}
}
protected void StateProcess()
{
switch (myState)
{
case State.CREATE:
break;
case State.IDLE:
break;
case State.BATTLE:
break;
case State.DIE:
break;
}
}
이런식으로 변경되었고
지금은 확인을 위해
마우스 왼쪽 버튼 클릭시 배틀모드 오른쪽 클릭시 아이들 모드로 들어가게끔 설정해주었다.
이거는 나중에 주위에 타겟팅 된 적이있다면 배틀모드로 들어가게끔 해주면 될거같다.
카메라 이동을 하려는데 축이동을 하려고 빈게임 오브젝트를 만들고 거기안에 카메라를 넣고 오브젝트 각도를 조절하면 원래내가 생각했던거는 그걸 축이라생각해서 캐릭터 를 중심으로 넣고 카메라 를 회전하는데 지금 뭐때문인지 모르겠는데
카메라각도그대로가 회전되서 그거에 애먹고있다.
'개인프로젝트 3D RPG 개발일지' 카테고리의 다른 글
10(유니티포폴) 캐릭터구현 (0) | 2022.06.26 |
---|---|
9. (유니티포폴) 메인신구현 (0) | 2022.06.25 |
7. (유니티포폴) 메인신 구현 (0) | 2022.06.21 |
6.(유니티포폴) 메인신 구현 (2) | 2022.06.20 |
5. (유니티포폴) 뒤끝서버 사용해보기 (0) | 2022.06.16 |