https://store.steampowered.com/app/2114090/Goetita_Turnbased_City/
Goetita: Turn-based City on Steam
Goetita: Turn-based city is a turn-based strategy game controlling the element of luck through rational judgment. Survive even in a desperate situation when all your resources are running out with your strategy in the cold and dark city!
store.steampowered.com
VIDEO
그냥 가서 칼로 때리는 건데 머 이리 사전에 고려어야 하는 게 많은지 모르겠다. 왜 사람들이 중간에 인디 개발을 쉽게 포기하는지 알듯도 싶다. 일단 체력바 시스템을 개선해야 하는데 원형으로 만들고 체력이 시계방향이나 반시계 방향으로 깎기 게 표현해야 할 듯싶다. 유니티 uGUI에서 해당 기능을 지원한다는 게 다행이다. 간격을 표시를 해야 하는데 이경우에 거리가 아닌 각을 나누면 되나 싶긴 하다. 안되면 그냥 숫자로 표현하는 방식도 가능할 듯싶다. 사이버 펑크 느낌이 나도록 허드 비슷하게 만들어야 하나 싶기도 하다.
이런식으로 직접적인 숫자로 체력 표시를 하는 건데 깔끔하고 좋아 보인다.
문제는 체력바가 캐릭터 크기에 비해 너무 컸던 거에서 기인하는 듯싶다. 간격을 표현하려면 어느 정도 최소 크기를 확보해야 하니 말이다. 엑스컴의 경우에는 이쁘게 잘 배치했던데 내겐 그 정도 감각이 없는 듯싶다.
작게 만드니까 또 어색하지는 않다.
잘 안보이는 문제를 해결하려면 색을 바꿀 필요가 있을 듯싶다.
UI가 그래픽에 차지하는 느낌이 지대한거 같다.
이게 한번 확대를 한건데 이 기준에서 이쁘게 떨어지는듯한 느낌이 든다.
클로즈업 상태에서는 3배를 확대를 해야 이쁘게 떨어진다. 축소를 더 하는 건 불가능해 보인다. 줌을 한 단계 했을 때는 그냥 유지를 해야겠다. 이게 1픽셀 단위다 보니 기술상 불가능한 듯싶다.
if (cameraZoomOut == cameraZoomIn )
{
if (hpBarUp ) return ;
var hpBars = hp .GetComponentsInChildren<HPBar >();
foreach (var bar in hpBars )
{
bar .transform .localScale = upScale ;
}
hpBarUp = true ;
}
else
{
if (hpBarUp == false ) return ;
var hpBars = hp .GetComponentsInChildren<HPBar >();
foreach (var bar in hpBars )
{
bar .transform .localScale = downScale ;
}
hpBarUp = false ;
}
Update 구문안에 있는거라 최적화 차원에서 스위치를 통해서 발동되도록 만들어 보았다.
방망이 깍는 노인이 된 듯싶다.
카메라가 움직이면서 길찾기까지 하니까 버벅거리는 감이 좀 있는 듯싶긴 하다. 카메라 움직이는 동안에는 길 찾기를 잠시 멈출 필요가 있는 듯싶다.
존나게 코드를 많이 수정했다. 혹자는 컴퓨터 성능이 좋은데 굳이 불편하게 제약을 두었냐고 할 수도 있을 듯싶다.
인게임에서 테스트를 해보니까 확대될때 체력바가 한 단계씩 더 커져도 이상하지 않은 듯싶다. 1920x1080 기준에서 말이다.
void CameraOut ()
{
cameraZoomOut += change ;
thisCamera .orthographicSize = cameraZoomOut ;
hp .localScale -= Vector3 .one ;
}
void CameraIn ()
{
cameraZoomOut -= change ;
thisCamera .orthographicSize = cameraZoomOut ;
hp .localScale += Vector3 .one ;
}
코드가 한결 간결해진듯 싶다. 근데 이게 테스트해보니 대략 4 정도 돼야 하지 않을까 싶기도 하다. 그렇다면 좀 더 코드가 복잡해 질듯 싶다.
1, 2, 6이 되어야 하는데 이걸 순열로 해결할수 있는 방법이 없나 궁금하다. 제곱을 더하면 되겠구나!
void CameraIn ()
{
cameraZoomOut -= change ;
thisCamera .orthographicSize = cameraZoomOut ;
hp .localScale += Vector3 .one * (hp .localScale .x ) * (hp .localScale .x );
}
일단 확대를 할때는 제곱을 더하면 되는데 빼는 게 문제다.
void CameraOut ()
{
cameraZoomOut += change ;
thisCamera .orthographicSize = cameraZoomOut ;
int newInt = (int ) (((hp .localScale .x ) / 3 ) * 2 );
hp .localScale -= Vector3 .one * newInt;
}
1.3... 이렇게 나오면 int로 강제 형 변환을 하면 1로 된다는 성질을 이용했다. 난 좀 머리가 똑똑한 듯싶다.
쉬바 이제야 모든 준비가 다 끝난듯 싶다. 여기까지 오기에 너무 오랜 시간이 걸렸다. 알고리즘은 대략적으로 굳이 스킬 버튼을 누르지 않아도 공격을 할 수가 있는 것이 있다. 물론 스킬 버튼을 누르고 타일을 클릭을 하면 마찬가지로 공격이 가능하다. 앞선 방식은 엑스컴 방식인데 문제는 근접 공격 스킬이 하나가 아니라는 거다. 엑스컴의 경우에는 검 공격은 하나고 원거리 공격이 여러 개 기 때문에 이런 편의 기능이 가능할 듯싶다. 그래서 그냥 스킬 버튼을 누른 경우 원하는 타일을 클릭하도록 해야겠다. 문제는 역시나 중첩이 되는 경우이다. 물론 인공지능을 만들 때 무조건 2칸 이상은 띠우도록 할 생각이다. 이게 엑스컴의 경우에 인공지능이 바짝 붙어 있는 경우를 못 봐서 어떻게 해결했는지 모르겠다. 그냥 주변에 적을 다 쓸어버리는 게 좋을 듯싶긴 한데 이건 엑스컴에서 일종에 패시브 스킬로 제공되는 거라서 말이다. 아니다 주변 적을 다 쓸어버리자. 근접이면 말이다. 이걸 기본 패시브로 주자. 검을 상향시키는 의미에서 말이다. 그러면 적을 일부러 모는 방식도 활용할 수 있을 듯싶다. 아 거참 편하구먼.
스킬 버튼을 누르면 그 스킬이 먼지 상태를 저장하는 걸 만들어야 할 듯싶다. 근접 공격 스킬이 1개가 아니니 말이다. 스키고 스킬을 쓰는 순간은 클로즈업 상태가 되어야 한다. 이를 해결하려면 애니 미 네이터에서 메시지를 보내 주어야 하는데 이런 기능이 있는지 모르겠다. 왠지 있을 거 같기도 하고 말이다.
print (animator .GetCurrentAnimatorStateInfo(0 ).IsName("Idle" ));
이걸로 원하는 상태에 있는지 아닌지를 체크를 해볼 수가 있다. 거의 웬만한 게임 만드는데 필요한 함수는 다 가지고 있는 듯싶다. 왜 상용엔진을 쓰는지 알겠다.
가서 써는 것까지 만들면 다시 코딩보다는 애니메이션이나 이펙트 쪽을 공부하게 될 듯싶다. 이펙트의 경우에는 새로 공부하는 거라서 그동안 루즈해 졌던거 다시 빡 조이게 될듯 싶다. 이게 학습을 할 때가 일을 할때 보다 더 눈이 반짝반짝하는 경향이 좀 있다. 마찬가지로 주로 에셋을 쓰되 에셋을 편집을 할 수 있을 정도의 실력을 쌓는 것을 목적으로 해야겠다. 내 게임의 전반적인 뉘앙스에 맞처서 말이다. 이펙트의 경우에는 에셋을 써도 그렇게까지 에셋을 썼다는 게 티가 나지는 않을 듯싶다. 이것까지만 만들고 고향집에 내려가서 전번에 사놓은 이펙트 쉐이더 책이랑 가져와야 할 듯싶다.
피격 후 상태를 어떻게 할지 고민이다. 장기자랑을 하는 시체를 만들지 아니면 그냥 모델링을 유지한 채 피만 흥건히 만들지 말이다. 일단 모델링을 유지하는 게 만들기는 편한 감이 있다.
어제 머리가 아픈 뒤로 계속 오늘까지 코피가 나서 이것까지만 하고 쉬러 내려가야겠다.
움직인 다음에 공격을 해야 하는데 이 함수를 재활용할 일이 많기 때문에 이벤트라든지 고급 기능을 좀 쓸 필요가 있을 듯싶다.
using System ;
반환 값이 없으니 액션을 쓰면 될 듯싶다. 문득 정부 비판하는 콘텐츠를 노려서 노이즈 마케팅을 하는 게 홍보에 도움이 되지 않을까 이런 생각이 든다. 우선 심의 시스템같이 내게 직접적으로 피해를 주는 정책은 까야할 듯싶다. 별다른 수입이 없는 니트다 보니 꽤나 부담이 된다.
주전자 닷컴이 당했다고 한다. 이러다 알만 툴 커뮤니티들도 당하는 게 아닌가 모르겠다. 약간 화가 나서 현 정부를 비판하는 콘텐츠를 좀 많이 집어넣어야 할 듯싶다.
한 일주일 정도 피를 흘리다 지금은 좀 나아졌다. 다시 작업을 지속해야 할 듯싶다. 누어 있는 동안 생각해 봤는데 지금 살짝 버벅거리기 때문에 쉐이더쪽을 최적화할 필요가 있을듯 싶다. 아 그리고 라이트를 두개를 쓰고 있는데 느낌을 그대로 유지 한채 라이트를 한개로 만드는 걸 연구를 좀 해야 할듯 싶다. 일단 당면한 이 문제부터 해결하고 넘어가자.
채도가 좀 낮아진 듯싶다...
일단 아우트라인 안으니까 그거 정도 비활성화해야겠다.
그냥 그대로 둬야겠다. 너무 칙칙하다.
전투 시스템까지 만들어 놓고 갔구나... 치면 리액션을 하는 거랑 피범벅 되는 거 만들어야 할 듯싶다. 일단 클로즈업 시스템부터 만들어야겠다.
그전에 이동하고 나서 적을 바라보도록 해야겠다.
public void BaseCloseAttack ()
{
foreach (var direction in GameUtility .eightDirections )
{
RaycastHit hit;
if (Physics .Raycast (transform .position , direction , out hit , GameUtility .interval , LayerMask .GetMask("Enemy" )))
{
transform .LookAt (hit .transform );
}
}
animator .SetTrigger ("BaseAttack" );
에너미 턴에서 동작이 끝날 때까지 대기를 시킬 필요가 있다. 다른 캐릭터 클릭도 막아야 할 듯싶다.
void OnMouseEnter ()
{
if (gameManager .somthingOn ) return ;
if (gameManager .currentPlayer == null ) return ;
if (gameManager .currentPlayer .playerActiveState == PlayerActiveState .NotAnything &&
gameManager .currentPlayer .playerTurnState == PlayerTurnState .Active )
{
MakeShield();
ShowPathIn();
ShowPathOut();
}
}
잠깐 버그가 있어서 해결했다. 애니메이션 상태를 추출하는 게 필요하다. 그전에 에너미도 플레이어를 쳐다보게 해야겠다.
이거랑 몇 가지 플레이어 턴 넘어가는 메커니즘도 손봤다. 순식간에 처다 보니까 좀 어색하긴 하다... 모션을 따로 만들려고 하면 복잡하니까 모든 전투는 클로으즈업을 하는 걸로 대체해야겠다.
이걸 칼 콜라이더를 만들어서 캐릭터에 맞는 경우에 파티클이 방출하게 해야 할지 아니면 막일로 모션마다 방출 시간을 정해야 할지 고민이다. 일단은 노가다로 설정을 하도록 해야겠다. 그럴라면 일단 클로즈업을 만들어야 할듯 싶다.
public void BaseCloseAttack ()
{
print (gameManager .currentPlayer .playerActiveState );
foreach (var direction in GameUtility .eightDirections )
{
RaycastHit hit;
if (Physics .Raycast (transform .position + Vector3 .up , direction , out hit , GameUtility .interval * alpha , LayerMask .GetMask("Enemy" )))
{
hit .transform .LookAt (this .transform );
transform .LookAt (hit .transform );
}
}
animator .SetTrigger ("BaseAttack" );
StartCoroutine (WaitSkillUsed());
}
그전에 시스템 전반을 손을 보고 클로즈업을 해야 겠다. 클로즈업 상태에서는 전반적인걸 확인하기 어려우니 말이다. 아 그리고 애니메이션 스테이트 상태를 체크하는 시스템도 만들어야 할 듯싶다. 아 그리고 액션 시에 UI 표시가 없어지는 것도 만들어야겠다.
아 그리고 복수로 있을 때 바라보는 건 상관이 없는데 문제는 플레이어는 맨 마지막에 본 사람을 바라보게 되니까. 공격을 한 사람을 정해서 그놈을 바라보게 해야겠다. 커런트 어택 에너미라는 개념을 만들어야 할 듯싶다. 체력이 다는 것도 표기를 하려면 말이다.
public void CloseCamera (Transform objectTrasform, bool isClosed = false , bool close = true )
{
if (! isClosed ) return ;
if (close )
{
thisCamera .orthographicSize = cameraZoomIn ;
}
else if (! close )
{
thisCamera .orthographicSize = cameraZoomOut ;
}
transform .position = objectTrasform .position ;
}
public void FollowCamera (Transform objectTrasform, bool isFollow = false )
{
if (! isFollow ) return ;
transform .position = objectTrasform .position ;
}
public void FollowCameraKey (bool isFollow = false , bool state = false )
{
if (! isFollow ) return ;
useMove = state ;
useScreenEdgeInput = state ;
}
public void CloseCameraKey (bool isClosed = false , bool state = false )
{
if (! isClosed ) return ;
useKeyboardInput = state ;
useScreenEdgeInput = state ;
}
카메라 줌인 아웃은 반복적으로 쓰게 될 거니 카메라 컨트롤러에 함수로 만들어야겠다.
IEnumerator WaitSkillUsed ()
{
cameraController .CameraKey (isClosed , false );
cameraController .CloseCamera(this .transform , isClosed , true );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsName ("Idle" ))
{
yield return null ;
}
cameraController .CameraKey (isClosed , true );
cameraController .CloseCamera(this .transform , isClosed , false );
gameManager .CheckPlayerTurn();
}
카메라 줌아웃은 이런 식으로 만들면 구동한다. 이제 애니메이션에서 어색한 부분을 수정하고 적이 타격을 입었을 때 맞았다는 모션을 만들어야겠다. 그다음 이펙트 같은걸 넣어주면 충분할 듯싶다. 아 그리고 엑스컴을 보니까 때릴 때 카메라 각도가 적의 뒤를 보고 캐릭터의 앞을 보도록 연출을 하는 듯싶다.
애니메이션의 경우에는 한 칸의 간격이 너무 좁아서 생기는 문제인듯 싶다. 오브젝트 크기를 대충 0.8로 줄이면 되긴 하다. 그런데 플레이어 크기를 줄이면 거기에 맞춰놯던걸 다 수정해야 하는 번거로움이 있다. 한칸의 크기를 3으로 늘리면 배치를 할 때 또 했갈리는 문제가 있고 말이다. 2로 맞추면 짝수인지만 확인하면 되기 때문이다.
곰곰이 생각해 보니 그냥 클로우즈 전에 조금 뒤로 이동시키면 될 듯싶다.
IEnumerator WaitSkillUsed (Vector3 direction)
{
model .position = this .transform .position - direction / 2 ;
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsName ("Idle" ))
{
yield return null ;
}
print ("End" );
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position + direction / 2 ;
}
이런 식으로 말이다.
IEnumerator WaitSkillUsed (Vector3 direction, float farFrom = 0 )
{
model .position = this .transform .position - direction / farFrom ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsName ("Idle" ))
{
yield return null ;
}
print ("End" );
activeOn .Invoke();
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position ;
board .ResetBoard();
}
이제 적이 맞고 반응하는 거랑 카메라를 움직여 놓았다가 다시 돌아오는 게 필요할듯싶다. 이펙트랑 이런거 까지 추가하고 체력이 다는것까지 구현하면 유튜브에 결과를 올려야 겠다.
공격자가 왼쪽 상단에 있고 피격자가 오른쪽 하단에 있어야 각이 멋지게 나오는 듯 싶다.
이 버그는 왜 생기는 걸까.
void FindStardNode ()
{
startNode = NodeList .Find (i => i .Coordinate == GameUtility .Coordinate (gameManager .currentPlayer .transform .position ));
}
이걸 만들어 주면 되는 듯싶다.
IEnumerator WaitSkillUsed (Vector3 direction, float farFrom = 0 )
{
model .position = this .transform .position - direction / farFrom + pos ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsName ("Idle" ))
{
yield return null ;
}
print ("End" );
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position + pos ;
currentVigor = 0 ;
gameManager .EndSkill();
board .ResetBoard();
}
공격이 끝나면 턴을 넘기도록 해준다. 아 근데 알고 보니 칼이 다른 게임에 나오는 거더라. AyanamiAzurlane이라고 되어 있어서 찾아보니 그렇게 뜨더라. 게임 내 아이템 이름을 아야나미이라고 쓰면 될 듯싶다.
웨폰을 트랜스폼으로 등록을 했는데 문제는 캐릭터가 생성될 때다. 내가 수동으로 달아줄 수가 없기 때문에 가급적 자동적으로 해결해야 한다. 주인의 경우 트렌스폼으로 찾아 가는 게 아니라 레이 캐스트 같은 걸로 찾아가야 할 듯싶다.
실수로 옆에 사람을 담지 않도록 이런 식으로 만들어야 될 듯싶다.
Transform player;
void Start ()
{
RaycastHit hit;
Physics .Raycast (this .transform .position , Vector3 .right , out hit , playerDistance , LayerMask .GetMask ("Player" ));
player = hit .transform ;
print (player );
}
약간 딜레이 같은 게 있는 듯싶다.
아 그게 아니라 데네브는 담는데 갈라테이아가 담지 못하는 거였다.
void Start ()
{
RaycastHit hit;
Physics .Raycast (this .transform .position + pos , Vector3 .left , out hit , playerDistance , LayerMask .GetMask ("Player" ));
player = hit .transform ;
print (player );
}
void Update ()
{
Debug .DrawRay(this .transform .position + pos , Vector3 .left , Color .red , playerDistance );
}
오른쪽이 아니라 윈 쪽이었다. 디버그 드로우 레이 함수는 애용해야 할 듯싶다.
void Start ()
{
RaycastHit hit;
Physics .Raycast (this .transform .position + pos , Vector3 .left , out hit , playerDistance , LayerMask .GetMask ("Player" ));
player = hit .transform .GetComponent<Player >();
player .weapon = this .transform ;
}
이런 식으로 해주면 연결된다. 이걸 만들 이유는 콜라이더 끼리 부딪칠 때 쓰러지는 모션이 재생되도록 만들기 위함이다.
public void BaseCloseAttack ()
{
print (gameManager .currentPlayer .playerActiveState );
currentEnemyList = null ;
var enemyDirection = new Vector3 ();
var currentEnemy = new Enemy ();
currentEnemyList = new List <Enemy >();
foreach (var direction in GameUtility .eightDirections )
{
RaycastHit hit;
if (Physics .Raycast (transform .position + Vector3 .up , direction , out hit , GameUtility .interval * alpha , LayerMask .GetMask ("Enemy" )))
{
if (hit .transform == null ) continue ;
var enemy = new Enemy ();
enemyDirection = direction ;
hit .transform .LookAt (this .transform );
transform .LookAt (hit .transform );
enemy = hit .transform .GetComponent<Enemy >();
enemy .direction = direction ;
currentEnemyList .Add (enemy );
}
}
if (currentEnemyList == null ) return ;
StartCoroutine (AllEnemy (2f));
}
IEnumerator AllEnemy (float farFrom = 0 )
{
foreach (var enemy in currentEnemyList )
{
ending = false ;
enemy .animator .SetTrigger ("Die" );
animator .SetTrigger ("BaseAttack" );
StartCoroutine (WaitSkillUsed (enemy .direction , farFrom ));
while (! ending )
{
yield return null ;
}
}
}
IEnumerator WaitSkillUsed (Vector3 direction, float farFrom)
{
model .position = this .transform .position - direction / farFrom + pos ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsName ("Idle" ))
{
yield return null ;
}
print ("End" );
ending = true ;
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position + pos ;
currentVigor = 0 ;
gameManager .EndSkill();
board .ResetBoard();
}
기본적으로 주변에 있는 애는 다 때린다.
IEnumerator WaitSkillUsed (Enemy enemy, float farFrom)
{
model .position = this .transform .position - enemy .direction / farFrom + pos ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsName ("Idle" ))
{
yield return null ;
}
while (! enemy .animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Dead" ))
{
yield return null ;
}
while (enemy .animator .GetCurrentAnimatorStateInfo(0 ).normalizedTime < endTime )
{
yield return null ;
}
print ("End" );
ending = true ;
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position + pos ;
currentVigor = 0 ;
gameManager .EndSkill();
board .ResetBoard();
}
적이 다 쓰러지는 것까지 확인한다.
쓰러지는 타이밍을 수동으로 만드는 게 나을지도 모르겠다. 너무 많이 생성하는 거 같기도 하다.
IEnumerator WaitSkillUsed (Enemy enemy, float farFrom)
{
var collider = weapon .GetChild(0 ).GetComponent<BoxCollider >();
board .line .gameObject .SetActive (false );
gameManager .somthingOn = true ;
model .position = this .transform .position - enemy .direction / farFrom ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (! Physics .Raycast (weapon .position + pos , Vector3 .right , GameUtility .interval / beta , LayerMask .GetMask ("Enemy" )))
{
yield return null ;
}
enemy .animator .SetTrigger ("Die" );
while (enemy .animator .GetCurrentAnimatorStateInfo(0 ).normalizedTime < endTime )
{
yield return null ;
}
print ("End" );
board .line .gameObject .SetActive (true );
ending = true ;
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position ;
currentVigor = 0 ;
gameManager .EndSkill();
board .ResetBoard();
}
일단 자동으로 만들어지도록 했다.
IEnumerator AllEnemy (float farFrom = 0 )
{
foreach (var enemy in currentEnemyList )
{
ending = false ;
// enemy.animator.SetTrigger ("Die");
animator .SetTrigger ("BaseAttack" );
transform .LookAt (enemy .transform );
StartCoroutine (WaitSkillUsed (enemy , farFrom ));
while (! ending )
{
yield return null ;
}
}
}
이게 더 깔끔한 듯싶다.
IEnumerator WaitSkillUsed (Enemy enemy, float farFrom)
{
var collider = weapon .GetChild(0 ).GetComponent<BoxCollider >();
board .line .gameObject .SetActive (false );
gameManager .somthingOn = true ;
model .position = this .transform .position - enemy .direction / farFrom ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (animator .GetCurrentAnimatorStateInfo(0 ).normalizedTime < hitTime )
{
yield return null ;
}
enemy .animator .SetTrigger ("Die" );
while (enemy .animator .GetCurrentAnimatorStateInfo(0 ).normalizedTime < endTime )
{
yield return null ;
}
print ("End" );
board .line .gameObject .SetActive (true );
ending = true ;
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position ;
currentVigor = 0 ;
gameManager .EndSkill();
board .ResetBoard();
}
대각선일 때는 굳이 뒤로 무를 필요까진 없는 듯싶다.
if (enemy .direction == Vector3 .forward ||
enemy .direction == Vector3 .back ||
enemy .direction == Vector3 .left ||
enemy .direction == Vector3 .right )
{
model .position = this .transform .position - enemy .direction / farFrom ;
}
아 그리고 여려 명일 때는 화면을 돌려야겠다.
IEnumerator AllEnemy (float farFrom = 0 )
{
foreach (var enemy in currentEnemyList )
{
ending = false ;
// enemy.animator.SetTrigger ("Die");
animator .SetTrigger ("BaseAttack" );
transform .LookAt (enemy .transform );
if (enemy != currentEnemyList [0 ]) cameraController .RotateScreen();
StartCoroutine (WaitSkillUsed (enemy , farFrom ));
while (! ending )
{
yield return null ;
}
enemy .direction = Vector3 .zero ;
}
currentEnemy = null ;
}
이제 이펙트 같은 거 넣으면 되려나 싶다.
public void BaseCloseAttack ()
{
print (gameManager .currentPlayer .playerActiveState );
currentEnemyList = null ;
var enemyDirection = new Vector3 ();
var currentEnemy = new Enemy ();
currentEnemyList = new List <Enemy >();
foreach (var direction in GameUtility .eightDirections )
{
RaycastHit hit;
if (Physics .Raycast (transform .position + Vector3 .up , direction , out hit , GameUtility .interval * alpha , LayerMask .GetMask ("Enemy" )))
{
if (hit .transform == null ) continue ;
var enemy = new Enemy ();
enemyDirection = direction ;
hit .transform .LookAt (this .transform );
enemy = hit .transform .GetComponent<Enemy >();
enemy .direction = direction ;
currentEnemyList .Add (enemy );
}
}
if (currentEnemyList == null ) return ;
StartCoroutine (AllEnemy (2f));
}
IEnumerator AllEnemy (float farFrom = 0 )
{
board .line .gameObject .SetActive (false );
gameManager .somthingOn = true ;
activeOff .Invoke();
cameraController .CameraMoveKey (isClosed , false );
cameraController .CloseCamera (this .transform , isClosed , true );
cameraController .Canvas .SetActive (false );
foreach (var enemy in currentEnemyList )
{
ending = false ;
// enemy.animator.SetTrigger ("Die");
animator .SetTrigger ("BaseAttack" );
transform .LookAt (enemy .transform );
if (enemy != currentEnemyList [0 ]) cameraController .RotateButon (1 );
StartCoroutine (WaitSkillUsed (enemy , farFrom ));
while (! ending )
{
yield return null ;
}
enemy .direction = Vector3 .zero ;
}
currentEnemy = null ;
board .line .gameObject .SetActive (true );
gameManager .somthingOn = false ;
cameraController .CameraMoveKey (isClosed , true );
cameraController .CloseCamera (this .transform , isClosed , false );
cameraController .Canvas .SetActive (true );
gameManager .CheckPlayerTurn();
model .position = this .transform .position ;
currentVigor = 0 ;
gameManager .EndSkill();
board .ResetBoard();
}
IEnumerator WaitSkillUsed (Enemy enemy, float farFrom)
{
if (enemy .direction == Vector3 .forward ||
enemy .direction == Vector3 .back ||
enemy .direction == Vector3 .left ||
enemy .direction == Vector3 .right )
{
model .position = this .transform .position - enemy .direction / farFrom ;
}
while (! animator .GetCurrentAnimatorStateInfo(0 ).IsTag ("Action" ))
{
yield return null ;
}
gameManager .somthingOn = true ;
while (animator .GetCurrentAnimatorStateInfo(0 ).normalizedTime < hitTime )
{
yield return null ;
}
enemy .animator .SetTrigger ("Die" );
while (enemy .animator .GetCurrentAnimatorStateInfo(0 ).normalizedTime < endTime )
{
yield return null ;
}
ending = true ;
}
근접 전투 완성이다. 이제 이펙트 넣어서 그럴듯하게 만들면 될 듯싶다.
VIDEO
https://store.steampowered.com/app/2114090/Goetita_Turnbased_City/
Goetita: Turn-based City on Steam
Goetita: Turn-based city is a turn-based strategy game controlling the element of luck through rational judgment. Survive even in a desperate situation when all your resources are running out with your strategy in the cold and dark city!
store.steampowered.com