제한된 이미지 사이즈 안에서 들어가야 할 글자가 초과될 경우 사용하면 될듯하다.

좌우 방향 설정과 속도조절이 가능하다.

 

 

깃허브 링크

https://github.com/hahahohohun/PublicCode/blob/main/README.md#-cmovetextcs

 

GitHub - hahahohohun/PublicCode

Contribute to hahahohohun/PublicCode development by creating an account on GitHub.

github.com

+) 특정 상태에 따라 흐를 것인가 멈출 것인가를 기능을 넣으면 좋을 듯

반응형

타이머를 간단하게 만들어봤습니다. 

 

타이머 시작 부분

    public void StartTimer(int nRemain, Text txtTimer = null, UnityAction EndCallBack = null)
    {
        ClearTimer();
        _CorTimer = StartCoroutine(CorStartTime(nRemain, txtTimer, EndCallBack));
    }

 

nRemain : 파라미터로 타이머를 동작시킬 시간

txtTimer : 남은 시간을 표기할 Text UI

EndCallBack : 타이머가 완료 후 실행시킬 함수.

 

코 루틴으로 작동되기 때문에 Clear 하는 부분을 꼭 넣어주도록 합니다. 

    private void ClearTimer()
    {
        if (_CorTimer != null)
        {
            StopCoroutine(_CorTimer);
            _CorTimer = null;
        }
        _bPause = false;
    }

타이머 동작 부분

    private IEnumerator CorStartTime(int nRemain = 5, Text txtTimer = null, UnityAction EndCallBack = null)
    {
        while (nRemain >= 0)
        {
            txtTimer.text = nRemain + " 초 남음";

            while (_bPause)
            {
                yield return null;
            }

            yield return new WaitForSeconds(1f);
            nRemain--;
        }
        EndCallBack?.Invoke();
    }

 

이 타이머스크립트에는 코 루틴으로 작동되며, WaitForSeconds(1f)로 1초마다 남은 시간을 감소하도록 했습니다. 저는 EndCallBack으로 델리게이트로 넘겨받도록 했는데 이유는 다른 곳에서도 쓰일 수 있도록 했습니다. 

 

 

그리고 매프 레임 텍스트만 바꾸지만 매 프레임 단위로 실행시키는 함수가 필요하면 EndCallBack처럼 받고 매프 레임 실행시켜주면 되겠죠. 


일시정지

타이머를 잠깐 멈추는 일시정지를 하는 부분입니다. 버튼 부분에 달아주고 OnPointerDown과 OnPointerUp을 통해 제어하도록 해줬습니다.

public class EventButton : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    private TimerUI _TimerUI = null;
    public void SetData(TimerUI TimerUI)
    {
        _TimerUI = TimerUI;
    }
    //클릭 누름.
    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.LogError("퍼즈");
        _TimerUI.ins_Timer.SetPause(true);
    }
    //클릭 뗌.
    public void OnPointerUp(PointerEventData eventData)
    {
        Debug.LogError("퍼즈 취소");
        _TimerUI.ins_Timer.SetPause(false);
    }

}

 ins_Timer는 타이머 동작부분이 구현되어있는 스크립트입니다. SetPause를 통해 코루틴을 잠시 멈추도록합니다.

 


구현결과

반응형

스크롤 셀을 만들 때 셀에 들어가는 데이터가 같은 글자 수면 참 좋겠지만 그렇지 않은 경우가 많다. 예를 들어 퀘스트 스크롤을 제작한다고 하자.

퀘스트의 설명이 어떤 퀘스트는 아주 길고 또 어떤 퀘스트의 내용은 짧고 또는 예상할수 없는 길이의 데이터가 입력될 수 있다.

그렇다고 셀들의 크기를 설명이 큰 내용의 맞추어 크게 만들 수는 없다. 또 유지보수에도 좋지않다.(이미 지정한 크기 이상의 데이터는 추가될 수도 없기 때문이다.)

이쁘지않다.

그렇다면 입력되는 데이터 텍스트의 수의 따라 파란배경 이미지의 사이즈 변경이 필요하다.

방법은 Content Size Fitter와 Layout Group컴포넌트를 이용해하는 것이다. 

사실 위 두개 컴포넌트가 텍스트 사이즈의 맞게 바로바로 변경되면 좋겠지만 그렇지 못하는 경우가 있다. LayoutRebuilder.ForceRebuildLayoutImmediate요 함수를 통해 즉시 정렬하도록 해줬다.

(요 함수는 오브젝트가 켜져있어야 정상 작동한다)

반응형

유니티) 포물선 궤적그리기


포탄을 날리거나 포탄 궤적을 보여주기 위해 사용된다.

유니티에서는 Line Renderer을 이용해봤다.



나는 포탄궤적이 아닌 캐릭터가 날아갈 점프 궤적을 그리는데 이용했다.


스크립트


셋팅


playerPlane :  라인이 그려질 plane(땅)의 위치를 셋팅해준다. 궤적이 시작하는 위치


마우스로 캐릭터 방향바꾸기 글에서 학습한적이 있었다.

https://funfunhanblog.tistory.com/40 (평면을 결정하는 최소 조건)


targetPoint는 포물선이의 끝점이된다. (내 게임에서는 노란색 circle에서 최종 위치를 받아온다)


체크



Raycast를 통해 마우스가 위치하는 곳을 가져온다. 

center : 시작벡터와 착지위치벡터의 합에 1/2은 위치가 포물선의 중간위치가 된다.

targetRotation : 라인위치와 최종위치를 빼면 포물선의 방향백터를 구할 수 있다. 

(벡터OA -벡터 OB = 벡터BA) center가 아닌 캐릭터의 위치로 계산해도됨)

Physics.Linecast : 포물을 그리는 라인에 물체가 걸리면 부딪힌 지점을 넘겨준다.



실제로 궤적(라인)을 그리는 부분




theArc : 두 벡터 사이를 원하는 간격으로 보간 부분

(이해를 못함.. 이쪽은 공부가 필요하다)

lineRenderer.SetPosition : 위에서 구해준 라인의 벡터들의 위치를 설정



학습참고 : http://maedoop.dothome.co.kr/660









반응형

미니맵 만들기 ( RenderTexture)


미니맵을 만드는 방법도 여러가지가 있겠지만 

이번에 학습할 내용은 랜더텍스처로 카메라를 추가해 캐릭터를 밑에 바라보게 하는것이다.

(보통은 카메라도 연산비용이 크기 때문에 카메라를 추가하지 않고 

캐릭터 실제 움직이는 위치를 계산해 이미지로 작은 미니맵을 만들어 준다고 한다.)


1) 카메라 추가 

위에서 밑을 바라보는 카메라를 만들어 미니맵처럼 보이기위함이다.

하이라키창에서 마우스 오른쪽 클릭하고 카메라를 추가해준다.

이름은 기존 카메라와 헷갈리지 않게 미니맵카메라 정도로 바꿔준다.


2) 캐릭터 플레이어를 대신 할 오브젝트 추가

새로 추가한 카메라가 플레이어 캐릭터를 비추면되지만 보통 캐릭터에는 폴리곤과 많은 이미지들이 붙어 있기 때문에 미니맵에는 이렇게 보일 필요가 없다. 

캐릭터의 어디에 있는지 위치정도만 보여주면 되기 때문에 나는 큐브를 생성하고 플레이어 자식으로 넣었다.

(미니맵 카메라는 사각이미지로 보일것이다.)

그리고 이 큐브 레이어를 'playercube'로 해준다. 이유는 밑에 설명


3) RenderTexture추가

랜더텍스처를 추가한다.

Render Texture는 런타임에서 생성 및 갱신되는 특수한 Texture로 카메라가 비추는 화면을 텍스처럼 가지고 있고 원하는 이미지에 그려줄 수 있는 텍스처라고 생각하면 된다.


4) 미니맵카메라 인스펙터 설정

새로 추가한 카메라에 셋팅을 해줘야한다. 

첫 번째로 카메라가 Culling Mask를 설정해준다. 

Culling Mask는 카메라가 보여질 레이어들은 체크하는 것이다. 맨 처음에는 Everything으로 되어 있을것이다. 

방금 추가한 Cube는 'playercube'이기 때문에 이것은 체크해주고 player(실제 캐릭터)는 체크 해제 해준다.

나머지는 그릴 필요가 있는지 없는지 체크해서 상황에 맞게 설정해준다. 


두 번째는 Target Texture를 아까 생성한 RenderTexture를 추가한다.


5) Raw Image 미니맵 이미지 생성

캔버스 밑에 Raw Image를 생성한다. 

일반 Image와 다르게 텍스처를 설정 할 수 있기때문이다.

Texture에 여기에도 아까 생성한 랜더텍스처를 넣어준다.


플레이 (우측 상단)


여기서 추가 셋팅은 기존 카메라에서는 당연히 하늘을 보게 되면 아까 추가한 큐브가 보일 것이다. 

기존 카메라에서 Culling Mask 'playercube'를 체크 해제해서 안보이게 해주어야한다.


랜더 텍스처 : https://docs.unity3d.com/kr/530/Manual/class-RenderTexture.html

반응형

Physics.Raycast 오브젝트 검출하기




레이를 쏴서 그 오브젝트가 어떤 오브젝트인지 파악하고 각각 다른 액션이 필요하다.


타입을 나누는 이유는 캐릭터가 검출대상(box,무기,아이템등..)의 대한 메소드를 캐릭터 스크립트에서 모두 정의 하는것은 다향성부분에도 떨어지고, 코드도 보기가 좋지 않다. 오브젝트 객체가 각각 가지고 있는 스크립트에서 정의해주고 캐릭터는 어떤 상황에 어떤 함수를 실행할 것 인지 제어해 주는것이 좋을 것 같다.

그래서 타입을 나누고, 인터페이스를 활용한다.  


타입 나누기

타입의 따른 설정을 주기 위해 열거형으로 만들어줬다.


인터페이스 만들기 

InterType : 어떤 타입인지 받아 오기위함

enable : 오브젝트 스크립트에서 제어 하기 위함

ActionInter : 입력버튼을 실행 할 경우 실행되는 메서드

ShowInter, NonShowInter : 각각 상황에 맞게 실행 


박스 스크립트 부분(인터페이스)

Box, Npc, Monster 등등 IInteraction을 인터페이스 구현이 필요하다.


플레이어스크립트 레이캐스트

if (hit.transform.CompareTag(Tag.RAYCAST_TAG_INTERACTION)) 

=> 오브젝트가 INTERACTION 태그인지 확인한다.

if (iInteraction.enable==true)

=> 오브젝트 enable를 체크한다.

UI_Hud.Ins.StringSetText(iInteraction.InterString);

=> 오브젝트 스크립트에 있는 InterString를 UI_Hud에 보낸다.(싱글턴)

UI_Hud.Ins.StringSetText

=> 각각 오브젝트 스크립트에서 설정한 텍스트 박스를 띄워준다.

 


반응형

 마우스로 캐릭터 방향 바꾸기



스크립트 작성

 Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);

        Plane GroupPlane = new Plane(Vector3.up, Vector3.zero);

float rayLength;

        if(GroupPlane.Raycast(camearRay, out rayLength))

        {

            Vector3 pointTolook = camerRay.GetPoint(rayLength);

            transform.LookAt(new Vector3(pointTolook.x, transform.position.y, pointTolook.z));

        }


코드분석

Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition); : 마우스의 위치를 ScreenPointToRay를 이용해 카메라로 부터의 스크린의 점을 통해 레이를 반환한다.

Plane  GroupPlane = new Plane(Vector3.up, Vector.zero); : 월드 좌표로 하늘방향에 크기가 1인 단위 백터와 원점을 갖는다.

if(GroupPlane.Raycast(cameraRay, out rayLength) ; : 레이가 평면과 교차했는지 여부를 체크한다.

Vector3 pointTolook = camerRay.GetPoint(rayLenghth); : rayLenghth거리에 위치값을 반환한다.

transform.LookAt ~~: 위에서 구한 pointTolook 위치값을 캐릭터가 바라 보도록 한다.

Plane GroupPlane  = new Plane(Vector3.up, Vector.zero); 그냥 쓸수 없고 이렇게 하는 이유는??

유니티에서 Plane을 만드는 생성자는 3가지로 오버로딩 되어있다.(= 평면을 만들 수 있는 조건)

평면을 결정하는 최소 조건!

  1. 한 직선 위에 있지 않은 세 점
  2. 한 직선과 그 직선 위에 있지 않은 한 점
  3. 한 점에서 만나는 두 직선
  4. 서로 평행한 두 직선

첫 번째 사용

normal은 평면의 수직 방향을 얘기한다. 벡터는 방향과 크기를 가지고있지만 특정 위치를 나타내지는 않는다.
그래서 위치를 표현 할 수 있는 점이나, 거리를 인자로 받아야한다. 
1) public Plane(Vector3 inNormalVector3 inPoint);
노멀위치부터 한점의 위치,
2) public Plane(Vector3 inNormal, float d);
노멀위치로 부터 길이(d : 원점으로 부터의 거리)
3) public Plane(Vector3 a, Vector3 b, Vector3 c);
평면을 만드는 조건 :  한직선위에 있지 않는 세점

학습참고 평면조건 https://docs.unity3d.com/ScriptReference/Plane-ctor.html

반응형

2D Light 




어셋 다운로드 Light2D


레이어 설정

3가지 레이어를 추가해 준다.


2D Light System 설정 (GameObject -> Light 2D -> LightSystem )

추가한 레이어를 맞게 설정해주고 create 한다.

그러면 메인카메라 밑에 라이트카메라가 생성된다.


Main Camera 설정

Clear Flag -> Solid Color 변경

Projection -> Orthographic 변경(원근감과 공간감이 없는)

culling Mask -> 게임화면에 오브젝트가 안보이면 확인해준다.

(생성된 라이트카메라의 background Color값을 바꾸면 전역광 효과를 낼 수 있다.)



Light Source 생성

라이트를 표현 해 줄 라이트를 생성해준다.

Sprite. Color : 라이트소스의 컬러의 알파값이 빛의 세기가 됨

Shape : 포인트를 라인으로 바꾸면 선형 빛의 모양으로 바뀜


오브젝트 레이어 설정

이제 각 오브젝트마다 표현해 주려는 요소의 맞게 설정해 준다.

AmbientLight : 장면 전체에 존재하는 빛

LightObstacles : 장애물 빛을 받지 않는다.

LightSoucre : 빛을 표현해줌


      






반응형

Fade(In,Out)


(fadeIn 효과)


위 그림처럼 게임 시작 시 알파값을 조절해 fadeIn 효과를 연출할 수 있다.


1) Image 생성

Canvas -> UI -> Image를 생성한 뒤 Color

까맣게 만들어 준다.

2) 스크립트 생성

public class FadeIn : MonoBehaviour

{

    public float FadeTime = 2f; // Fade효과 재생시간

    Image fadeImg;

    float start;

    float end;

    float time = 0f;

    bool isPlaying = false;


    void Awake()

    {

        fadeImg = GetComponent<Image>();

        InStartFadeAnim();

    }

    public void OutStartFadeAnim()

    {

        if(isPlaying == true) //중복재생방지

        {

            return;

        }

start = 1f;

         end = 0f;

        StartCoroutine("fadeoutplay");    //코루틴 실행

    }

public void InStartFadeAnim()

    {

        if (isPlaying == true) //중복재생방지

        {

            return;

        }

        StartCoroutine("fadeIntanim");

    }

    IEnumerator fadeoutplay()

    {

        isPlaying = true;


        Color fadecolor = fadeImg.color;

        time = 0f;

        color.a = Mathf.Lerp(start, end, time);


            while (fadecolor .a > 0f)

            {

                time += Time.deltaTime / FadeTime;

                fadecolor .a = Mathf.Lerp(start, end, time);

                fadeImg.color = fadecolor ;

                yield return null;

            }

            isPlaying = false;

    }

코드분석

while(color.a > 0f) {    } :  이미지 색상의 알파값이 0으로 가까워 질 수록 투명해짐(이미지 색상이 약해짐?)

time += Time.deltaTime / FadeTime; : 지정한 시간만큼 효과를 주기 위해 1초를 나눠줌

fadecolor.a = Math.Lerp(start, end, time); : start와 end 중간값을 리턴

yield return null; :  다음 프레임까지 대기


Math.Lerp(start, end, time);

선형 보간을 할때 사용.

시작과 끝을 알고 정해진 시간동안 진행되야될 경우에 사용 
0일경우 시작값을, 1일 경우 끝 값을 반환하는데,

0.4일경우 시작값 40%,끝 값 60%값을 반환해서 자연스러운 연출이 가능하다.

(매 프레임 마다 증가하는 time값과 감소하는 알파값을 Debug.log를 찍어봤다)

Math.Lerp를 사용하면 time값에 따라 0에서 1로 갈수록 점점 큰 약한 알파값을 반환함으로서 자연스럽게 연출이 가능해진다.

FadeOut

같은 코드로 start값과 end값 그리고 while조건문 값만 수정하면 연출이 가능하다.



이 블로그에 더 자세히 나와있음 : http://ronniej.sfuh.tk/%EC%BD%94%EB%A3%A8%ED%8B%B4coroutine%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-fade-%EC%95%A0%EB%8B%88%EB%A9%94%EC%9D%B4%EC%85%98-%EB%A7%8C%EB%93%A4%EA%B8%B0/

반응형

FloatingText 


데미지값 출력해주기!




1) 프리팹제작

Canvas안에 UI -> Text로 만들어준다.


2) FloatingText 스크립트(프리팹에 추가할 스크립트)

    public void print(string Text)

    {

        FloatTextPrint.text =  string.Format(" {0}",Text);


}

private void Start()

{

moveSpeed = 5f; //위로 움직이는 속도값

destroyTime = 3f; //몇초 후 삭제 될건지

}

void Update()

        {

vector.Set(FloatTextPrint.transform.position.x, FloatTextPrint.transform.position.y 

             + (moveSpeed + Time.deltaTime), FloatTextPrint.transform.position.z);


FloatTextPrint.transform.position = vector;


destroyTime -= Time.deltaTime;


if(destroyTime <=0)

{  

Destroy(this.gameObject);

}


}

 vector.Set(FloatTextPrint.transform.position.x, FloatTextPrint.transform.position.y 

             + (moveSpeed + Time.deltaTime), FloatTextPrint.transform.position.z);

생성된 FloatTextPrint 위치를 Y값으로 증가 시킨다.



3) UI.Mgr 스크립트

public void SetFloating(GameObject vr, string bulletpower) //몬스터의 위치, 총알의 공격력을 받아옴

{

  

PrefabFloatingTXT = Resources.Load<GameObject>("prefab/FloatingTxt");

if(PrefabFloatingTXT == null)

{

Debug.Log("FloatingTxt Null");

}

                GameObject TXT = Instantiate(PrefabFloatingTXT);


Vector3 uiPosition = Camera.main.WorldToScreenPoint(vr.transform.position);


    TXT.transform.localPosition = uiPosition;

            TXT.transform.SetParent(canvas.gameObject.transform);

            Ftxt = TXT.gameObject.transform.GetComponent<FloatingText>();

    Ftxt.print(bulletpower);


}

Vector3 uiPosition = Camera.main.WorldToScreenPoint(vr.transform.position);

UI 오브젝트 이기 때문에 몬스터의 position값을 넣어도 화면에 보이지 않는다. 

Camer.main.WorldToScreenPoint를 월드좌표에서 스크린좌표로 값을 변환해준다.


반응형

Vector3.Distance


두 위치 사이의 거리를 반환한다.


일정거리 안에 플레이어가 접근하면 반응하도록 하기위해 Vector3.Distance를 이용한다.


Vector3.Distance() 사용법

float distance = Vector3.Distance(코인의 위치, 플레이어의 위치);


적용하기

Coin 스크립트

public void CoinMove()

{

dir= (playerpos.position - transform.position).normalized;

acceleration= 0.2f;

velocity = (velocity + acceleration* Time.deltaTime);

float distance = Vector3.Distance(playerpos.position, transform.position);

if (distance <= 3.0f)

{

transform.position = new Vector3(transform.position.x + (dir.x * velocity),

   transform.position.y,

transform.position.z+(dir.z * velocity));

}

else

{

velocity = 0.0f;

}

}

코드해석

direction = (playerpos.position - transform.position).normalized; : 코인위치와 플레이어의 위치를 뺀 값을 단위 백터화 한다.

acceleration= 0.2f;  : 가속도

velocity = (velocity + acceleration* Time.deltaTime); :  한 프레임으로 가속도 계산


간단하게 구현하기에는 Distance를 사용하면 좋긴하지만, 좀 더 최적화된 퍼포먼스를 위해서는 밑에 있는 것들을 이용하는것을 추천한다.ㅎㅎ

1) Vector3.Distance

2) Vector3.magnitude

3) Vector3.sqrMagnitude


참고 : https://docs.unity3d.com/kr/530/ScriptReference/Vector3.Distance.html


반응형

Random.Range 


컴퓨터 프로그래밍 언어에서는 난수라고도 한다.

사실 컴퓨터는 랜덤이란게 있을 수 없기 때문에 일정 범위에 숫자값을 집어넣고

그중에 윈도우나 유니티상에서 시간값을 가지고 숫자를 뽑아내는 것을 난수라고 한다.


유니티에서는 Random.Range가 존재한다.


사용법

Random.Range(min,max ) //min [inclusive]과 max [inclusive]사이의 랜덤 float 수를 반환


주의할점을 값이 int일 경우 max값은[exclusive] 나오지 않는다. 


public class ItemDrop : MonoBehaviour {


    public GameObject Item;


void Start () {

        InvokeRepeating("Spawnitem", 1, 1); //1초에 1번씩 Spawnitem()를 호출한다.

    }


    void Spawnitem()

    {

        

        float randomX = Random.Range(-23f, 19f); 

        if(true)

        {

            Debug.Log("생성");

            GameObject item = (GameObject)Instantiate(Item, new Vector3(randomX, 1.1f,0f), Quaternion.identity);

        }

    }

}


InvokeRepeating : time 초에 /methodName/메서드를 호출한 후, 매 /repeatRate/초 마다 반복적으로 호출

Instantiate(Item, new Vector3(randomX, 1.1f,0f), Quaternion.identity); Item이라는 프리팹을 생성한다.

Quaternion.identity : 회전없음



생성될 아이템 프리팹을 설정한다.



아이템이 랜덤으로 생성되는것을 볼 수 있다.

위 코드는 X위치만 랜덤 생성해 주었지만 Z값도 랜덤 설정하면 사방에서 스폰 될 것이다.



반응형

카메라 시점 바꾸기



Left Shift 버튼을 눌렀을 때 시점을 바꿔준다.

시점이 3개이기 때문에 카메라도 3개가 필요하다

메인카메라 프로젝트 생성시 존재하는 카메라


시점카메라(1인칭)

캐릭터가 움직일때 같이 따라 와야하기 때문에 카메라는 캐릭터 오브젝트 자식으로 넣어둔다.




캐릭터 정면에서 바라보는 카메라


메인카메라를 제외하고 모두 비활성화 해준다.

PlayerController스크립트


public class PlayerController : MonoBehaviour

{

public Camera[] arrCam; //카메라 요소들을 추가한다.

int nCamCount = 3;

int nNowCam = 0;

// 필드값 세팅

Camera[] arrCam : 카메라 활성화/비활성화를 해주기 위한 배열

nNowCam : 현재 활성화 된 카메라의 번호

nCamCount : 카메라 갯수


void Update ()

{

if( Input.GetButtonUp("Fire3"))

{

++nNowCam;


if (nNowCam >= nCamCount)

{

nNowCam = 0;

}


for ( int i=0; i<arrCam.Length; ++i )

{

arrCam[i].enabled = (i == nNowCam);

}

}

}

if( Input.GetButtonUp("Fire3"))...

버튼이 눌리면 nNowCam값을 1증가 시킨다.

if (nNowCam >= nCamCount) ...

세 번째 카메라까지 순서대로 보여주고 다시 첫 번째 카메라로 돌아가게 해주는 코드이다.

for ( int i=0; i<arrCam.Length; ++i )...

NowCam(0번카메라)이면 enabled=true 해주고 나머지 1,2번은 false해준다.

또 NowCam(1번카메라)값이 1이면 카메라 컴포넌트를 enabled=true 해주고 나머지 0,2번은 false해준다.

2번 카메라 일때도 마찬가지 나머지 요소는 enabled를 false시킴


*Fire3가 무엇이냐? InputManager



반응형

캐릭터 점프구현


이번에도 역시나 Roll a Ball을 활용한다.


캐릭터 점프는 실제 위치값을 움직이는 Translate보다는 

물리적 힘을 위로 주어서 튀어 오르는듯한 느낌을 주는 AddForce를 이용하는게 좋아보인다.


먼저 소스코드를 살펴보자


void Start( )

{       

        rb = GetComponent<Rigidbody>();

        jumpCount = 1; //점프 가능횟수

        isGround = true; //땅에 있을때

}

jumpCount는 1로 초기화 해준다.

isGround는 true로 땅에 있을때 캐릭터가 점프를 할 수 있는 환경이라고 판단하기 위해 선언 한 것이다.


void FixedUpdate ()

{        

        if (isGround) 

        {

            jumpCount = 1;

            if (Input.GetKeyDown("space")) //점프

           { 

                if (jumpCount==1){             

                    rb.AddForce(0, 300f, 0); //점프

                    isGround = false;

                    jumpCount = 0;

                }

           }

        }

    }

update문에서는 우선 플에이어가 있는 위치가 땅바닥인지 체크를 해준다.

땅바닥이라면 jumpCount값을 1로 만들어준다.

그리고 스페이스바가 눌리면 다시 jumpCount가 1인지 체크를 한다. 

두 if문이 모두 맞다면 플레이어의 rigidbody에 y값에 힘을 주어 캐릭터가 위로 튀어 오르게 만들어준다.

점프를 하고 있는 중에는

플레이어의 위치가 땅바닥이 아니기 때문에 isGround는 false로 설정하고

점프를 한번 했기 때문에 다시 jumCount는 0으로 만들어준다.(다시 점프를 할수 없게)

    private void OnCollisionEnter(Collision col)

    {

        if (col.gameObject.tag == "ground")

        {

            isGround = true;    //Ground에 닿으면 isGround는 true

            jumpCount = 1;          //Ground에 닿으면 점프횟수가 1로 초기화됨

        }

    }

OnCollision물체가 플레이어에게 닿으면 아래 코드들이 활성화된다.

플레이어에게 Collision(여기서는 땅바닥)이 닿게 되면 

jumCount를 1로 만들어준다. 


여기서 알아야 할 것은 

JumCount와 플레이의 위치 isGround를 체크 하지 않고 스페이스바를 여러번 누르게 되면 

계속해서 하늘로 치솟아 무한 점프가 될것이다 

그것을 방지하기 위해 체크한다. (캐릭터가 땅에 도착해야 다시 점프를 할 수 있게)

그리고 OnTrigger이 아닌 OnCllision을 사용했다는 점도 파악해야한다.


반응형



캐릭터 회전시키기 :

마우스 이동 시 큐브가 좌우로 움직임


public class PlayerMove : MonoBehaviour {

     

       float rotSpeed = 1.0f; //ADD

// Update is called once per frame

void Update () {

      


       // 마우스 입력

       float MouseX = Input.GetAxis("Mouse X");


       transform.Rotate(Vector3.up * rotSpeed * MouseX);

}

}

transform.Rotate(회전할 기준 좌표 축 * Time.deltaTime * 회전 속도 * 변위 값)

출처:http://itmining.tistory.com/48



반응형



위 그림처럼 큐브가  키보드 입력을 받으면 앞,뒤,왼쪽,오른쪽으로 이동하게 만들기




public float speed = 5.0f

    //캐릭터가 움직일 스피드설정 public으로 함으로써 유니티 인스펙터 창에 설정이 가능해짐


void Update () { // 매프레임 반복되기때문에 Update에 써준다.


if(Input.GetKey(KeyCode.UpArrow)) //키보드 위쪽 화살표가 눌릴경우  

{ this.transform.Translate(Vector3.forward * speed * Time.deltaTime); } 

// this(이스크립트를 가지고있는).transform(컴포넌트).Translate(움직을 주는)값을

// Vector3(3D 방항).forward(앞).*speed(속도).*Time.deltaTime(1초당)

if(Input.GetKey(KeyCode.DownArrow))

{ this.transform.Translate(Vector3.back * speed * Time.deltaTime); }

if(Input.GetKey(KeyCode.RightArrow))

{ this.transform.Translate(Vector3.right * speed * Time.deltaTime); }

if(Input.GetKey(KeyCode.LeftArrow))

{ this.transform.Translate(Vector3.left * speed * Time.deltaTime);}



*Delta Time 이전 프레임의 시작 시간과 현재 프레임의 시작 시간의 차이



반응형

+ Recent posts