프로그래밍/유니티(unity)

[unity#2] 유니티에 관절바디(articuration body)로 기계적 움직임을 표현해보기! (녹칸다 디지털트윈/digitaltwin)

덕력킹 2025. 2. 25. 23:14
반응형

https://youtube.com/live/qqLLCIVEPzg

[unity#2] 유니티(unity)에 관절바디(articuration body)로 기계적 움직임을 표현해보기! (녹칸다 디지털트윈/digitaltwin/튜토리얼)

녹칸다의 내맘대로 유니티(unity) 시리즈이다!

이번편의 내용은 아래 슬라이드로 공유된다!
https://docs.google.com/presentation/d/1yiia2U7D-iLx6HU1SVTbA4632Rpbq3rOaz8UXqatIcg/edit#slide=id.g3395a51d9a1_1_63

이번편은 관절바디(articuration body)가 무엇이고 어떻게 사용하는지에 대해서 알아보도록 한다!

 

유니티2편의 유니티패키지

unity02.unitypackage
0.05MB

 

유니티 에디터에 구, 큐브, 실린더 3개가 있을때~
1.gameObject 한 개당 스크립트를 한 개씩 컴포넌트로 추가하기
    -script1.cs : 사용자가 숫자키1을 누르면 구가 녹색, 2를 누르면 빨간색으로 바뀐다!(구에 컴포넌트로 추가)
    -script2.cs : 사용자가 숫자키3을 누르면 큐브가 녹색, 4를 누르면 빨간색으로 바뀐다!(큐브에 컴포넌트로 추가)
    -script3.cs : 사용자가 숫자키5을 누르면 실린더가 녹색, 6를 누르면 빨간색으로 바뀐다!(실린더에 컴포넌트로 추가)
    -만약 구와 큐브와 실린더에 script1을 모두 부여한다면 script1의 코드에 의해서 동시에 색이 바뀌게된다!

script1.cs
0.00MB

 

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

public class script1 : MonoBehaviour
{
    Material mymaterial;

    void Start()
    {
        mymaterial = this.GetComponent<Renderer>().material;
    }

    // Update is called once per frame
    void Update()
    {
        //사용자가 키보드 뭘 입력했으려나~
        if(Input.GetKeyDown(KeyCode.Alpha1)) {
            //이 클래스의 주인의 색상을 녹색으로 바꾼다
            //this.GetComponent<Renderer>().material.color
            //mymaterial.color = Color.green;
            green_color();
        }
        if (Input.GetKeyDown(KeyCode.Alpha2))
        {
            //이 클래스의 주인의 색상을 빨간색으로 바꾼다
            //mymaterial.color = Color.red;
            red_color();
        }
    }
    //외부에서 호출하면 이 스크립트의 주인의 색이 녹색으로 바뀌는 함수
    public void green_color()
    {
        mymaterial.color = Color.green;
    }
    public void red_color()
    {
        mymaterial.color = Color.red;
    }
}

script2.cs
0.00MB

 

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

public class script2 : MonoBehaviour
{
    Material mymaterial;

    void Start()
    {
        mymaterial = this.GetComponent<Renderer>().material;
    }

    // Update is called once per frame
    void Update()
    {
        //사용자가 키보드 뭘 입력했으려나~
        if (Input.GetKeyDown(KeyCode.Alpha3))
        {
            //이 클래스의 주인의 색상을 녹색으로 바꾼다
            //this.GetComponent<Renderer>().material.color
            //mymaterial.color = Color.green;
            green_color();
        }
        if (Input.GetKeyDown(KeyCode.Alpha4))
        {
            //이 클래스의 주인의 색상을 빨간색으로 바꾼다
            //mymaterial.color = Color.red;
            red_color();
        }
    }
    public void green_color()
    {
        mymaterial.color = Color.green;
    }
    public void red_color()
    {
        mymaterial.color = Color.red;
    }
}

script3.cs
0.00MB

 

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

public class script3 : MonoBehaviour
{
    Material mymaterial;

    void Start()
    {
        mymaterial = this.GetComponent<Renderer>().material;
    }

    // Update is called once per frame
    void Update()
    {
        //사용자가 키보드 뭘 입력했으려나~
        if (Input.GetKeyDown(KeyCode.Alpha5))
        {
            //이 클래스의 주인의 색상을 녹색으로 바꾼다
            //this.GetComponent<Renderer>().material.color
            //mymaterial.color = Color.green;
            green_color();
        }
        if (Input.GetKeyDown(KeyCode.Alpha6))
        {
            //이 클래스의 주인의 색상을 빨간색으로 바꾼다
            //mymaterial.color = Color.red;
            mymaterial.color = Color.red;
        }
    }
    public void green_color()
    {
        mymaterial.color = Color.green;
    }
    public void red_color()
    {
        mymaterial.color = Color.red;
    }
}


2.한 개의 스크립트로 여러개의 gameObject에 스크립트 적용하기
    -script4.cs : 구,큐브,실린더 3개를 public한 gameObject로 입력받아서 숫자키 7을 누르면 동시에 녹색이되고, 8을 누르면 동시에 빨간색이 되도록 하시오!

script4.cs
0.00MB

 

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

public class script4 : MonoBehaviour
{
    public GameObject mysphere;
    public GameObject mycube;
    public GameObject mycylinder;
    // Start is called before the first frame update
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Alpha7))
        {
            mysphere.GetComponent<Renderer>().material.color = Color.green;
            mycube.GetComponent<Renderer>().material.color = Color.green;
            mycylinder.GetComponent<Renderer>().material.color = Color.green;
        }
        if (Input.GetKeyDown(KeyCode.Alpha8))
        {
            mysphere.GetComponent<Renderer>().material.color = Color.red;
            mycube.GetComponent<Renderer>().material.color = Color.red;
            mycylinder.GetComponent<Renderer>().material.color = Color.red;
        }
    }
}


3.gameObject의 컴포넌트에 직접 접근하는 방식(지금계속 하고있는방식)
4.스크립트에 포함된 멤버함수를 호출하는 방식(script1~scrip3을 약간 수정함) 
   -script5.cs : script4와 동일한데, 숫자키 9와 0으로 색이 바뀌도록 하시오!  
   -script5에서 script1~script3에 있는 public한 멤버함수를 호출함으로써 기능을 실현함!

script5.cs
0.00MB

 

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

public class script5 : MonoBehaviour
{
    public GameObject mysphere;
    public GameObject mycube;
    public GameObject mycylinder;

    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Alpha9))
        {
            //mysphere가 가지고있는 script1이라는 컴포넌트가 있는데
            //그 스크립트에는 public한 접근제한자로 선언된 green_color라는 함수가있으니
            //그것을 호출해라!
            mysphere.GetComponent<script1>().green_color();
            mycube.GetComponent<script2>().green_color();
            mycylinder.GetComponent<script3>().green_color();
        }
        if (Input.GetKeyDown(KeyCode.Alpha0))
        {
            mysphere.GetComponent<script1>().red_color();
            mycube.GetComponent<script2>().red_color();
            mycylinder.GetComponent<script3>().red_color();
        }
    }
}

prismatic joint를 이용한 기본 예시!(ex1)

script6.cs
0.00MB

 

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

public class script6 : MonoBehaviour
{
    //이 스크립트의 this는 ex1_cylinder이다!

    ArticulationBody mybody;

    void Start()
    {
        mybody = this.GetComponent<ArticulationBody>();
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Q))
        {
            //Q가 눌러지면 이녀석의 관절바디의 설정값을 -2로 바꿈!
            mybody.SetDriveTarget(ArticulationDriveAxis.X, -2);
        }
        if (Input.GetKeyDown(KeyCode.W))
        {
            //Q가 눌러지면 이녀석의 관절바디의 설정값을 0로 바꿈!
            mybody.SetDriveTarget(ArticulationDriveAxis.X, 0);
        }
    }
}

revolute joint를 이용한 기본 예시!(ex2)

script7.cs
0.00MB

 

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

public class script7 : MonoBehaviour
{
    ArticulationBody myjoint;
    void Start()
    {
        myjoint = this.GetComponent<ArticulationBody>();
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.E))
        {
            //180도회전
            myjoint.SetDriveTarget(ArticulationDriveAxis.X, 180);
        }
        if (Input.GetKeyDown(KeyCode.R))
        {
            //0도회전
            myjoint.SetDriveTarget(ArticulationDriveAxis.X, 0);
        }
        if (Input.GetKeyDown(KeyCode.T))
        {
            //-180도회전
            myjoint.SetDriveTarget(ArticulationDriveAxis.X, -180);
        }
    }
}

Spherical Joint를 이용한 기본 예시!(ex3)

script8.cs
0.00MB

 

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

public class script8 : MonoBehaviour
{
    ArticulationBody myjoystick;

    void Start()
    {
        myjoystick = this.GetComponent<ArticulationBody>();
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.UpArrow))
        {
            //y축을 -45도로 이동
            myjoystick.SetDriveTarget(ArticulationDriveAxis.Y, -45);
        }
        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            //y축을 45도로 이동
            myjoystick.SetDriveTarget(ArticulationDriveAxis.Y, 45);
        }
        if (Input.GetKeyDown(KeyCode.RightArrow))
        {
            //z축을 -45도로 이동
            myjoystick.SetDriveTarget(ArticulationDriveAxis.Z, -45);
        }
        if (Input.GetKeyDown(KeyCode.LeftArrow))
        {
            //z축을 45도로 이동
            myjoystick.SetDriveTarget(ArticulationDriveAxis.Z, 45);
        }
        if (Input.GetKeyDown(KeyCode.P))
        {
            //원위치
            myjoystick.SetDriveTarget(ArticulationDriveAxis.Y, 0);
            myjoystick.SetDriveTarget(ArticulationDriveAxis.Z, 0);
        }
    }
}

 

여러개의 joint를 이용한 예제(ex4)

script9.cs
0.00MB

 

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

public class script9 : MonoBehaviour
{
    //원래 아래와 같이 녹칸다는 object를 에디터에서 입력을 받는 형식으로 안내했다!
    //public GameObject joint1;
    //그러나 입력받을 object가 관절바디 컴포넌트를 가지고 있다면 아래와 같이 쓸수있다!
    public ArticulationBody joint1;
    public ArticulationBody joint2;
    public ArticulationBody joint3;

    
    void Start()
    {
        
    }

    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.Keypad4))
        {
            //joint1을 90도회전
            joint1.SetDriveTarget(ArticulationDriveAxis.X, 90);
        }
        if (Input.GetKeyDown(KeyCode.Keypad5))
        {
            //joint1을 0도회전
            joint1.SetDriveTarget(ArticulationDriveAxis.X, 0);
        }
        if (Input.GetKeyDown(KeyCode.Keypad6))
        {
            //joint1을 -90도회전
            joint1.SetDriveTarget(ArticulationDriveAxis.X, -90);
        }
        if (Input.GetKeyDown(KeyCode.Keypad8))
        {
            //joint3을 x=0의 위치로 이동
            joint3.SetDriveTarget(ArticulationDriveAxis.X, 0);
        }
        if (Input.GetKeyDown(KeyCode.Keypad2))
        {
            //joint3을 x=-3의 위치로 이동
            joint3.SetDriveTarget(ArticulationDriveAxis.X, -3);
        }
        if (Input.GetKeyDown(KeyCode.Keypad7))
        {
            //joint2을 y=0의 위치로 이동
            joint2.SetDriveTarget(ArticulationDriveAxis.Y, 0);
        }
        if (Input.GetKeyDown(KeyCode.Keypad9))
        {
            //joint2을 y=-3의 위치로 이동
            joint2.SetDriveTarget(ArticulationDriveAxis.Y, -3);
        }
    }
}
반응형