❌ Data.contents.cs에서 이미 Stat 클래스명을 사용하고 있기 때문에 중복된다는 오류 메시지가 뜬다.
-> Data.contents.cs의 Stat 클래스를 Data라는 별도의 네임스페이스 안에 넣어 중복을 피한다.
-> 기존에 Stat클래스를 참조하던 다른 코드들도 수정
public class Stat : MonoBehaviour
{
[SerializeField] protected int _level;
[SerializeField] protected int _hp;
[SerializeField] protected int _maxHp;
[SerializeField] protected int _attack;
[SerializeField] protected int _defense;
[SerializeField] protected float _moveSpeed;
public int Level { get { return _level; } set { _level = value; } }
public int Hp{ get { return _hp; } set { _hp = value; } }
public int MaxHp { get { return _maxHp; } set { _maxHp = value; } }
public int Attack { get { return _attack; } set { _attack = value; } }
public int Defense { get { return _defense; } set { _defense = value; } }
public float MoveSpeed { get { return _moveSpeed; } set { _moveSpeed = value; } }
private void Start()
{
_level = 1;
_hp = 100;
_maxHp = 100;
_attack = 10;
_defense = 5;
_moveSpeed = 5.0f;
}
}
ㄴ 프로퍼티를 사용할건데 굳이 필드 변수를 만들어준 이유?
-> 인스펙터창에서 변수와 값을 확인하려고.
public class PlayerStat : Stat
{
protected int _exp;
protected int _gold;
public int Exp { get { return _exp; } set { _exp = value; } }
public int Gold { get { return _gold; } set { _gold = value; } }
private void Start()
{
_level = 1;
_hp = 100;
_maxHp = 100;
_attack = 10;
_defense = 5;
_moveSpeed = 5.0f;
_exp = 0;
_gold = 0;
}
}
- 컴포넌트 연결
PlayerStat.cs -> UnityChan
Stat.cs -> Knight
❌ 기존에 PlayerController.cs에서 사용하던 _speed 변수는 이제 필요없다. Stat.cs에서 _moveSpeed로 스피드값을 줄 것이기 때문.
커서 에셋 다운 및 설정
커서 에셋을 받은 후, Texture Type을 Cursor로 지정한다.
PlayerController.cs에 UpdateMouseCursor() 추가
커서가 땅을 가리킬 때와 적을 가리킬 때의 이미지를 변경한다.
💡SetCursor(Texture2D texture, Vector2 hotspot, CursorMode cursorMode);
- 땅을 클릭한 상태로 커서를 움직이면 Player가 커서를 따라서 이동
- 적을 클릭한 상태로 커서를 움직이면 Player가 마우스 커서가 아닌 적을 향해 이동
(ex.리니지1, 디아블로 3)
Define.cs MouseEvent 수정
-> PointerUp과 Click을 마우스를 누르고 있는 시간(_pressedTime)으로 구분
InputManager.cs
PlayerController.cs
int _mask = (1 << (int)Define.Layer.Ground) | (1 << (int)Define.Layer.Monster);
GameObject _lockTarget;
void OnMouseEvent(Define.MouseEvent evt)
{
if (_state == PlayerState.Die)
return;
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
bool raycastHit = Physics.Raycast(ray, out hit, 100.0f, _mask);
//Debug.DrawRay(Camera.main.transform.position, ray.direction * 100.0f, Color.red, 1.0f);
switch(evt)
{
case Define.MouseEvent.PointerDown:
{
if (raycastHit)
{
_destinationPos = hit.point;
_state = PlayerState.Moving;
if (hit.collider.gameObject.layer == (int)Define.Layer.Monster)
{
_lockTarget = hit.collider.gameObject;
}
else
{
_lockTarget = null;
}
}
}
break;
case Define.MouseEvent.Press:
{
if(_lockTarget != null)
{
_destinationPos = _lockTarget.transform.position;
}
else if(raycastHit)
{
_destinationPos = hit.point;
}
}
break;
}
}
현재 마우스 클릭 상태에 따른 Cursor의 상태 변화에 관한 코드까지 PlayerController.cs에서 관리하고 있다. 이를 CursorController.cs에서 관리하도록 수정하자.
public class CursorController : MonoBehaviour
{
int _mask = (1 << (int)Define.Layer.Ground) | (1 << (int)Define.Layer.Monster);
Texture2D _attackIcon;
Texture2D _handIcon;
enum CursorType
{
None,
Attack,
Hand,
}
CursorType _cursorType = CursorType.None;
void Start()
{
_attackIcon = Managers.Resource.Load<Texture2D>("Textures/Cursor/Attack");
_handIcon = Managers.Resource.Load<Texture2D>("Textures/Cursor/Hand");
}
void Update()
{
//마우스를 누르고 있는 상태면 커서 상태 변화 X
if (Input.GetMouseButton(0))
return;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100.0f, _mask))
{
if (hit.collider.gameObject.layer == (int)Define.Layer.Monster)
{
if (_cursorType != CursorType.Attack)
{
Cursor.SetCursor(_attackIcon, new Vector2(_attackIcon.width / 5, 0), CursorMode.Auto);
_cursorType = CursorType.Attack;
}
}
else
{
if (_cursorType != CursorType.Hand)
{
Cursor.SetCursor(_handIcon, new Vector2(_handIcon.width / 3, 0), CursorMode.Auto);
_cursorType = CursorType.Hand;
}
}
}
}
}
📄참고자료
[인프런] c#과 유니티로 만드는 MMORPG 게임 개발 시리즈_3. 유니티 엔진
Unity Documentation_Cursor.SetCursor