링크 : https://elderly-badge-d56.notion.site/e282e3cc3b334603a84382823a21ca33?pvs=4
UnityShader-젠레스 존 제로 일부 기능 재현 - https://wgstudylog.tistory.com/m/178
<aside> <img src="/icons/snippet_red.svg" alt="/icons/snippet_red.svg" width="40px" /> Github에는 최종적으로 올릴 예정입니다.
</aside>
public class Actor : MonoBehaviour
{
[SerializeField] private Camera actorCamera;
[SerializeField] private float fsmoothTime = 0.05f;
protected CharacterController characterController;
protected Animator animator;
[SerializeField] protected float fmoveSpeed = 3.0f;
protected float frotSpeed = 50.0f;
protected AState.State estate = AState.State.Idle;
protected AState currentState;
protected bool bstateFance = false;
public Animator anim { get => animator; }
public Vector3 inputDirection { get => vmoveDiretion; }
public CharacterController charController { get => characterController; }
public float moveSpeed { get => fmoveSpeed; }
protected Vector3 vmoveDiretion = Vector3.zero;
protected float fcurrentVelocity = 0f;
[SerializeField] private Renderer[] playerRenderers;
public void SwitchState<T>() where T : AState, new()
{
if (bstateFance) return;
currentState.EndState(this);
currentState = new T();
currentState.StartState(this);
}
protected virtual void Initialized()
{
Cursor.lockState = CursorLockMode.Locked;
characterController = GetComponent<CharacterController>();
transform.rotation = Quaternion.identity;
animator = GetComponentInChildren<Animator>();
currentState = new IdleState();
currentState.StartState(this);
}
public void UpdateMove(Vector3 _moveDir, float _speed)
{
Vector3 dir = actorCamera.transform.TransformDirection(_moveDir);
dir.y = 0f;
characterController.SimpleMove(dir * fmoveSpeed);
}
public void UpdateRotate(Vector3 _moveDir)
{
Vector3 dir = actorCamera.transform.TransformDirection(_moveDir);
float targetAngle = Mathf.Atan2(dir.x, dir.z) * Mathf.Rad2Deg;
float angle = Mathf.SmoothDampAngle(transform.eulerAngles.y, targetAngle, ref fcurrentVelocity, fsmoothTime);
transform.rotation = Quaternion.Euler(0f, angle, 0f);
}
protected virtual void Tick()
{
//입력이 없을경우 Idle 상태로 변경
if (bstateFance) return;
Vector3 inputDirection = GameUtility.GetInputDirection();
if (inputDirection == Vector3.zero)
{
//Idle
if(currentState.state != AState.State.Idle)
SwitchState<IdleState>();
return;
}
else
{
if(Input.GetKeyDown(KeyCode.LeftShift))
{
//Dash
SwitchState<DashState>();
}
else if(Input.GetKey(KeyCode.LeftShift))
{
//Run
SwitchState<RunState>();
}
else
{
//Walk
SwitchState<WalkState>();
}
}
}
public virtual void Damaged(int _dmg)
{
if(currentState.state == AState.State.Dash)
{
//저스트 회피
Debug.Log($"Not Damaged!");
}
else
{
//TODO > Damaged
}
}
/// <summary>
/// State 변경을 가능하게 하거나 잠그거나
/// </summary>
/// <param name="_active"></param>
public void SetStateLock(bool _active)
{
bstateFance = _active;
}
void Start()
{
Initialized();
}
void Update()
{
Tick();
currentState.UpdateState(this);
if(Input.GetKeyDown(KeyCode.Alpha1))
{
foreach(var renderer in playerRenderers)
{
renderer.material.SetFloat("_RimPower", 10f);
}
}
else if(Input.GetKeyDown(KeyCode.Alpha2))
{
foreach (var renderer in playerRenderers)
{
renderer.material.SetFloat("_RimPower", 0f);
}
}
}
}
Actor
클래스는 Unity의 MonoBehaviour
를 상속받아 캐릭터의 이동, 회전, 상태 관리 등을 처리하는 기초 클래스입니다. 다양한 상태 전환을 지원하며, 이를 기반으로 여러 종류의 캐릭터를 만들 수 있습니다.
actorCamera
: 캐릭터를 따르는 카메라.fsmoothTime
: 회전 시 부드러운 전환을 위한 시간.characterController
: 캐릭터의 이동을 제어하는 CharacterController
컴포넌트.animator
: 캐릭터의 애니메이션을 제어하는 Animator
컴포넌트.fmoveSpeed
: 캐릭터의 이동 속도.