[unity#2] 유니티에 관절바디(articuration body)로 기계적 움직임을 표현해보기! (녹칸다 디지털트윈/digitaltwin)
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편의 유니티패키지
유니티 에디터에 구, 큐브, 실린더 3개가 있을때~
1.gameObject 한 개당 스크립트를 한 개씩 컴포넌트로 추가하기
-script1.cs : 사용자가 숫자키1을 누르면 구가 녹색, 2를 누르면 빨간색으로 바뀐다!(구에 컴포넌트로 추가)
-script2.cs : 사용자가 숫자키3을 누르면 큐브가 녹색, 4를 누르면 빨간색으로 바뀐다!(큐브에 컴포넌트로 추가)
-script3.cs : 사용자가 숫자키5을 누르면 실린더가 녹색, 6를 누르면 빨간색으로 바뀐다!(실린더에 컴포넌트로 추가)
-만약 구와 큐브와 실린더에 script1을 모두 부여한다면 script1의 코드에 의해서 동시에 색이 바뀌게된다!
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;
}
}
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;
}
}
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을 누르면 동시에 빨간색이 되도록 하시오!
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한 멤버함수를 호출함으로써 기능을 실현함!
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)
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)
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)
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)
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);
}
}
}