(C# 및 UNITY) 롤링 볼

https://learn.unity.com/project/roll-a-ball-1

이 예를 보고 배우십시오!

게임 구현 환경을 만들고 코드를 입력해야 합니다.

아직 초보자이기 때문에 기존 도형으로 작업할 수 있습니다.

스크립트를 입력하려면 C# 언어를 알아야 하므로 주의 깊게 공부하십시오.

1. 플레이어 컨트롤러

에이전트를 움직이게 하는 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed; //물체의 속도, public float형은 유니티 에디터에서 직접 값을 입력할 수 있다. 당장 값을 입력해주지 않아도 괜찮다
    private Rigidbody rb; //우리가 정한 물리엔진

    // Start is called before the first frame update
    void Start() // 첫 번째 프레임이 나올 때 항상 실행되는 함수, 전에 정한 물리엔진을 불러올 것이다.
    {
        rb = GetComponent<Rigidbody>();
        
    }

    // Update is called once per frame
    void Update() //일단 여기서는 업데이트 함수를 쓰지 않을 것이다.
    {
        
    }

    // 업데이트 함수는 매 프레임마다 실행됨
    // fixed 업데이트 함수는 간격?을 두고 실행됨

    void FixedUpdate() // 고정된 프레임 수마다 실행되는 함수
    {
        // 키보드로부터 입력을 받는 것
        float moveHorizontal = Input.GetAxis("Horizontal"); //수평으로 움직임
        float moveVertical = Input.GetAxis("Vertical"); //수직으로 움직임

        // 입력받은 값을 물리엔진에 적용
        Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);

        //함수에 대한 자세한 내용을 알고 싶을 땐 unity api를 검색, 구글 검색
        rb.AddForce(movement * speed);
    }
}

2. 카메라 컨트롤러

게임 화면을 표시하기 위해 카메라를 제어하는 ​​코드

항상 프록시를 따르도록 카메라를 설정합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class NewBehaviourScript : MonoBehaviour
{
	// 스크립트에서 public타입의 변수는 유니티 에디터에서 지정할 수 있다.
    public GameObject player; // 플레이어가 public, 아직 정해지지 않음
    private Vector3 offset; // 카메라와의 거리값

    // Start is called before the first frame update
    void Start() // 처음에 프레임을 불러왔을 때 실행되는 함수
    {
        // 초기 플레이어 위치와 카메라 위치의 차이를 구함
        // camera.transform이 아닌 이유는 이 코드를 camera에 대입을 시킬 것이기 때문, 그럼 자동으로 카메라 정보가 들어감
        offset = transform.position - player.transform.position;
    }

    // Update is called once per frame
    void Update() // 아직 당장은 안 쓸 것
    {
        
    }

    // 유니티에는 굉장히 많은 업데이트 함수가 존재한다.
    // 모든 업데이트가 실행이 되고 맨 마지막에 실행이 되는 업데이트 함수다.
    // 카메라 같은 경우는 플레이어가 움직이고 나서 최종적으로 나중에 움직이기 때문에 
    void LateUpdate()
    {
        // 매 순간 플레이어 위치에 초기 차이값을 더해준다.
        // 결과적으로 카메라가 플레이어의 위치가 바껴도 계속 카메라와 플레이어의 간격이 유지된다.
        transform.position = player.transform.position + offset;
    }
}

3. 회전 큐브

보상을 받는 큐브를 완벽하게 회전시킵니다.

중심 축이 약간 기울어지도록 큐브를 회전합니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Rotator : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    // 매 프레임마다 큐브가 돌아가도록 만들것이다.
    void Update()
    {
    	// 돌아가는 축 정보가 들어간다.
    	// time.deltatime -> 시간마다 돌아가야 하니까
        transform.Rotate(new Vector3(15, 30, 45) * Time.deltaTime);
    }
}

4. 플레이어 충돌 감지 추가

플레이어가 큐브와 충돌할 때 플레이어가 충돌할 때 큐브가 피커가 될 충돌력과 크기를 설정하는 코드입니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed; 
    private Rigidbody rb; 

    // Start is called before the first frame update
    void Start() 
    {
        rb = GetComponent<Rigidbody>(); 
    }

    // Update is called once per frame
    void Update() 
    {
        
    }

    void FixedUpdate() 
    {
        float moveHorizontal = Input.GetAxis("Horizontal"); 
        float moveVertical = Input.GetAxis("Vertical"); 

        Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);

        rb.AddForce(movement * speed);
    }

	// 플레이어 컨트롤러가 속한 플레이어가 다른 게임 오브젝트와 만났을 때 이 함수가 호출되고
    void OnTriggerEnter(Collider other)
    {
    	// 조건문. 모든 객체마다 태그를 붙일 수 있다. 명찰 같은 느낌
        if (other.gmaeObject.CompareTag("PickUp")) //픽업이라는 명찰을 단 오브젝트와 만났을 때
        {
        	// 해당 게임 오브젝트는 active가 비활성화된다. 멈춘다? 먹어진다. 없어진다.
            other.gameObject.SetActive(false);
        }
    }
}

5. 채점

플레이어가 큐브와 충돌할 때 보너스를 받을 수 있는 코드입니다. 이것을 PlayerController 파일에 넣기만 하면 됩니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    public float speed; 
    private Rigidbody rb;
    private int count; // 점수

    // Start is called before the first frame update
    void Start() 
    {
        rb = GetComponent<Rigidbody>();
        count = 0;
    }

    // Update is called once per frame
    void Update() 
    {
        
    }

    void FixedUpdate() 
    {
        float moveHorizontal = Input.GetAxis("Horizontal"); 
        float moveVertical = Input.GetAxis("Vertical"); 

        Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);

        rb.AddForce(movement * speed);
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("PickUp"))
        {
            other.gameObject.SetActive(false);
            count = count + 1; // 충돌, 점수를 획득
        }
    }
}

6. 텍스트 추가

다음은 플레이어에 점수 및 승리 문구를 표시하는 텍스트를 추가하는 코드입니다. 다시 말하지만 이것을 PlayerController 파일에 추가할 수 있습니다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UnityEngine.UI; // UI를 생성했으므로

public class PlayerController : MonoBehaviour
{
    public float speed; 
    private Rigidbody rb;
    private int count;
	
	// 텍스트 요소를 추가한다.
    public Text CountText; 
    public Text WinText;

    // Start is called before the first frame update
    void Start() 
    {
        rb = GetComponent<Rigidbody>();
        count = 0;
        SetText(); // 처음 시작할 때 텍스트를 불러주고
    }

    // Update is called once per frame
    void Update() 
    {
        
    }

    void FixedUpdate() 
    {
        float moveHorizontal = Input.GetAxis("Horizontal"); 
        float moveVertical = Input.GetAxis("Vertical"); 

        Vector3 movement = new Vector3(moveHorizontal, 0, moveVertical);

        rb.AddForce(movement * speed);
    }

    void OnTriggerEnter(Collider other)
    {
        if (other.gameObject.CompareTag("PickUp"))
        {
            other.gameObject.SetActive(false);
            count = count + 1;
            SetText(); // 충돌해 점수를 획득할 때마다 텍스트를 불러준다.
        }
    }
    
	// 텍스트와 관련된 함수를 만든다. 
    void SetText()
    {
        if (count >= 5) // 픽업들 5개를 다 획득을 했다면
        {
            CountText.text = ""; // 이겼으므로 더 이상의 카운트는 하지 않아도 된다.
            WinText.text = "You Win!" // 이겼다!
        }
        else // 아직 다 획득하지 못했다면
        {
            CountText.text = "Count : " + count.ToString(); // 점수 
            // count가 int값이므로 문자열로 바꿔준다
            // c#에서는 문자열과 문자열의 덧셈이 가능하다
            WinText.text = "";
        }
    }
}

Roll-a-Ball 예제를 구현하는 비디오

롤링볼 구현 동영상

이와 같이 볼 에이전트가 회전하는 대상을 터치하면 보상이 1포인트 증가한 것을 알 수 있습니다.