1 minute read

1. ํ๋ธŒ ๊ตด๋ฆฌ๊ธฐ

ํ˜„์žฌ ์Šคํ„ฐ๋””๋ฅผ ํ•˜๊ณ  ์žˆ๋Š” ๊ณณ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ตด๋Ÿฌ๊ฐ€๋Š” ํ๋ธŒ์— ๋Œ€ํ•ด ํ•œ๋ฒˆ ๋งŒ๋“ค์–ด ์˜ค๋ผ๊ณ  ๊ณผ์ œ๋ฅผ ๋‚ด์ฃผ์…จ๋‹ค.

project


์ฒ˜์Œ์— ์ด ๊ณผ์ œ๋ฅผ ๋‚ด์ฃผ์‹œ๊ณ  ๋‚˜์„œ ์ด๊ฑธ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ•ด์•ผ ํ•˜๋Š”์ง€ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ wasd ๋ฐฉํ–ฅํ‚ค์— ๋”ฐ๋ผ Rotation์„ ๋ฐ”๊พธ๋Š” ์‹์œผ๋กœ ํ•˜๊ธฐ๋กœ ๊ตฌ์ƒ์„ ํ•˜์˜€๋‹ค.

2. ์ดˆ๊ธฐ๊ตฌ์ƒ


images

์œ„์™€ ๊ฐ™์ด ๋‹จ์ˆœํ•˜๊ฒŒ ๋ฐ›์€ ๊ฐ’์œผ๋กœ ๊พธ์ค€ํžˆ Rotate๋ฅผ ํ•˜๋Š” ์‹์œผ๋กœ ๊ตฌํ˜„์„ ํ•˜์˜€๋‹ค.

rolling_cube1


๊ทธ๋Ÿฌ์ž ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž˜ ๊ตฌํ˜„์ด ๋˜์—ˆ๋‹ค.


3. ๋ฌธ์ œ์  ๋ฐœ๊ฒฌ


๊ทธ๋Ÿฐ๋ฐ ์ด ์ฝ”๋“œ์— ๋‹จ์ˆœํžˆ ์ค‘๋ ฅ์„ ์ ์šฉ์‹œํ‚ค์ž ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ด์ƒํ•˜๊ฒŒ ํ๋ธŒ๊ฐ€ ๊ตด๋Ÿฌ๊ฐ”๋‹ค. ์ด๊ฒƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ์œ„ํ•ด ๋งˆ์ฐฐ๋ ฅ, ์ค‘๋ ฅ์— ๋Œ€ํ•ด์„œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์„ค์ •์„ ํ•ด์คฌ๋Š”๋ฐ๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ์–ด๋– ํ•œ ํ•ด๊ฒฐ์ฑ…์ด ๋‚˜์˜ค์ง€ ์•Š์•˜๋‹ค.

rolling_cube2


4. ์ตœ์ข… ์ฝ”๋“œ

๊ฒฐ๊ตญ ๊ตฌ๊ธ€๋ง์„ ํ•˜๋ฉฐ ๋ฐฉ๋ฒ•์„ ์ฐพ๋‹ค๊ฐ€ rolling cube๋ผ๊ณ  ๊ฒ€์ƒ‰์„ ํ•˜์ž ์ฐธ๊ณ ํ•  ๋งŒํ•œ ์˜์ƒ์ด ๋‚˜์™”๋‹ค.

https://www.youtube.com/watch?v=06rs3U2bpy8

์ด ๋™์˜์ƒ์„ ์ฐธ๊ณ ํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์งฐ๋‹ค.


Update๋ฌธ

void Update()
    {
        if (_isRolling != true)
        {
            if (Input.GetKey(KeyCode.W)) { Rolling_Manage(Vector3.forward); }
            else if (Input.GetKey(KeyCode.S)) { Rolling_Manage(Vector3.back); }
            else if (Input.GetKey(KeyCode.D)) { Rolling_Manage(Vector3.right); }
            else if (Input.GetKey(KeyCode.A)) { Rolling_Manage(Vector3.left); }
        }
    }

์ด๋™์ค‘์— ์ด๋™ํ•˜๋Š”๊ฒƒ์„ ๋ง‰๊ธฐ ์œ„ํ•˜์—ฌ _isrolling์ด false์ผ ๋•Œ๋งŒ ์ž‘๋™ํ•˜๊ฒŒ ํ•˜์˜€๋‹ค.
ํ‚ค๋ณด๋“œ์˜ ์ž…๋ ฅ์— ๋”ฐ๋ฅธ ์ด๋™์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ wasd์— ๋”ฐ๋ฅธ Rolling_Manage ํ•จ์ˆ˜๋ฅผ ์ž‘๋™์‹œํ‚ค๊ฒŒ Update๋ฌธ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.


Rolling_Manager

void Rolling_Manage(Vector3 dir)
    {
        var axis = transform.position + (Vector3.down + dir) * 0.5f;
        var angle = Vector3.Cross(Vector3.up, dir);
        StartCoroutine(Rolling(axis, angle));
    }

์—ฌ๊ธฐ์„œ ๋งŒ์•ฝ d๊ฐ’์ด ๋“ค์–ด์™”์„ ์‹œ์— axis๋Š” transform.position์ด๋ผ๋Š” ํ˜„์žฌ ์œ„์น˜์— Vector3.down (0, -1, 0)์™€ dir (1, 0, 0)์ด๋ผ๋Š” ๋ฒกํ„ฐ๊ฐ’์„ ํ•ฉ์น˜๊ณ  2๋กœ ๋‚˜๋ˆˆ ๊ฐ’์ธ (0.5, -0.5, 0)๋งŒํผ ์›€์ง์ด๋ฉด ๋ฌผ์ฒด์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ 1์ด๋ผ ํ–ˆ์„๋•Œ, ๊ทธ ๋ฌผ์ฒด์˜ ๋ชจ์„œ๋ฆฌ์˜ ์ขŒํ‘œ๊ฐ€ ๋‚˜์˜จ๋‹ค.


image


๋˜ angle์€ Vector3.Cross๋ผ๋Š” ์™ธ์ ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ Vector3.up (0, 1, 0)๊ณผ dir (1, 0, 0)์„ ์™ธ์ ์‹œํ‚ค๋ฉด +๊ฐ’์ด ๋‚˜์˜จ๋‹ค. ์ด๋ ‡๊ฒŒ ๋‘ ๊ฐ’์„ ์™ธ์ ์‹œํ‚จ ๊ฐ’์˜ ๋ถ€ํ˜ธ๋ฅผ ํ†ตํ•ด์„œ ํ๋ธŒ๊ฐ€ ์–ด๋Š ๋ฐฉํ–ฅ์œผ๋กœ ๊ตด๋Ÿฌ๊ฐˆ์ง€๋ฅผ ์ •ํ•ด์ฃผ์—ˆ๋‹ค. ํ”„๋กœ๊ทธ๋žจ์ด ์ž‘๋™ํ•˜๋Š” ๋„์ค‘์— ๋”ฐ๋กœ ์ž‘๋™๋˜๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•˜์—ฌ coroutine์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค.


rolling

IEnumerator Rolling(Vector3 axis, Vector3 angle)
    {
        _isRolling = true;
        for (int i = 0; i < (90 / speed); i++) {
            transform.RotateAround(axis, angle, speed);
            yield return null;
        }
        _isRolling = false;
    }


์ดํ›„ Rolling์ด๋ผ๋Š” ํ•จ์ˆ˜์—์„œ๋Š” _isRolling์„ true๋กœ ๋ณ€๊ฒฝํ•˜๊ณ , RotateAround๋ผ๋Š” axis๊ฐ’์„ ๊ธฐ์ค€์œผ๋กœ angle๋ฐฉํ–ฅ์œผ๋กœ ๋Œ๋ ค์ฃผ๋Š” ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•˜์—ฌ ํ๋ธŒ๋ฅผ 90๋„ ๋Œ๋ ค์ฃผ์—ˆ๋‹ค.


๊ฒฐ๊ณผ๋ฌผ

rooling_cube

์ดํ›„ ์™„์„ฑ๋œ ๊ฒฐ๊ณผ๋ฌผ์ด๋‹ค.




๊ฐœ์ธ ๊ณต๋ถ€ ๊ธฐ๋ก์šฉ ๋ธ”๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.
ํ‹€๋ฆฌ๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์ œ๋ณดํ•ด์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.๐Ÿ˜