728x90

이 글은 인프런 "따라하면서 배우는 고박사 유니티 기초 " 강의를 수강한 후 정리한 글 입니다. 

 

[지금 무료] 따라하면서 배우는 고박사의 유니티 기초 | 고박사 - 인프런

고박사 | 유니티로 게임을 개발하고 싶은 초보자를 대상으로 하며, 유니티 설치부터 2D/3D 게임 개발에 필요한 기초 지식까지 자세하게 설명합니다. (강의에 사용되는 모든 리소스는 영상 상단의

www.inflearn.com

 


Animation Layer

  1. 씬 이름 설정 : #01_AnimationLayer
  2. Main Camera의 위치를 Position(0, 1, -2)로 설정
  3. unitychan FBX 모델을 Hierarchy View로 Drag & Drop
  4. unitychan 오브젝트의 회전 값을 Rotaion(0,135,0)으로 설정
  5. Animator Controller를 생성하고, unitychan 게임오브젝트에 등록

 

 
 

​project에 animation layer을 생성한 뒤 unitychan에 contorller에 생성한 animation layer을 등록한다. Animator View로 가서 Base Layer에 걷는 애니메이션인 WALK00_F를 등록한다.

 

 

게임을 실행하면 걷는 애니메이션이 재생된다. 

Avatar Mask 생성 및 설정

현재 상태에서 상체만 다른 애니메이션을 적용하도록 한다. Project View > “+” > Avatar Mask 생성 후 이름을 UpperBodyAvatar 로 등록한다. 

이후 생성한 Avatar Mask를 선택하여 상체만 제어할 수 있도록 하체는 연결을 해제한다.

 

 

이후 Animator View에서 새로운 layer를 생성한 뒤에 설정 버튼으로 가준치를 최대인 1로 설정하고 mask에 UpperBodyAvatar를 등록한다. 그리고 Upper Layer에 WAIT01 애니메이션을 등록한다.

 

이후 게임을 실행하게 되면 하체는 걷고, 상체는 대기 애니메이션을 재생하는 것을 확인할 수 있다. 

 
 

 


Bland Tree 1D

  1. 새로운 씬을 생성하고, #02_BlendTree_1D으로 씬 저장
  2. Main Camera의 위치를 Position(0, 1, -2)로 설정
  3. unitychan FBX 모델을 Hierarchy View로 Drag & Drop
  4. Animator Controller를 생성하고, unitychan 게임오브젝트에 등록

 

Ctrl + N으로 새로운 scene을 생성해서 #02_BlendTree_1D로 저장한다. 새로 생성한 Scene에 unitychan 모델을 Hierarchy View에 추가하고 main camera 위치를 (0,1,-2)로 설정하고, unitychan 모델의 Rotation 값을 (0,135,0)으로 설정한다. 

 

Animation controller를 생성해서 "1D" 라고 생성하고 모델에 등록한다. 

 
 

 

Window > Animation > Animator view를 열어서 Blend Tree를 생성한다. 

 
 

 

생성된 Blend Tree를 더블 클릭하여 내부로 이동한다. 파라미터에 movespeed 를 추가하였고, 모션에 대기, 걷기, 뛰기를 순서대로 등록하였다.

 

위에 설정에서 생성된 모션의 Threshold 값이 0, 0.5, 1로 저장되며 Automate Thresholds를 해제하면 수동으로 값을 바꿀수 있다. 

 

이로써 movespeed값이 변화하면 그 값에 따라 애니메이션이 블렌드되어 재생되며, movespeed 값을 코드에서 변화시킬 수 있도록 할 것이다.

 

 

단축키 등록

우선 걷기, 달리기 부분을 위해 shift키를 단축키로 등록해 사용하도록 한다.  Edit > Project Settings > Input Manager 에 들어가면 사이즈를 19로 올려준다.

 

 

PlayerController1D.cs 스크립트

using UnityEngine;

public class PlayerController1D : MonoBehaviour
{
    private Animator animator;
    // private float walkSpeed = 4.0f;
    // private float runSpeed = 8.0f;

    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        float vertical = Input.GetAxis("Vertical"); // 위, 아래 방향키 입력
        // shift키를 안누르면 최대 0.5, shift키를 누르면 최대 1까지 값이 바뀌게 된다
        float offset = 0.5f + Input.GetAxis("Sprint") * 0.5f;
        //오른쪽 방향키를 누르면 forward가 +이지만 왼쪽 방향키를 누르면 forward가 -이기 때문에 애니메이션 파라미터를 설정할 땐 절대값으로 적용한다
        float moveParameter = Mathf.Abs(vertical * offset);

        // moveParameter 값에 따라 애니메이션 재생 (0: 대기, 0.5: 걷기, 1: 뛰기)
        animator.SetFloat("moveSpeed", moveParameter);

        //이동속도: Shift키를 안눌럿을 땐 walkSpeed, Shift키를 눌렀을 땐 runSpeed값이 moveSpeed에 저장
        // float moveSpeed = Mathf.Lerp(walkSpeed, runSpeed, Input.GetAxis("Sprint"));
        // 실제 이동
        // transform.position += new Verctor3(vertical, 0, 0) * moveSpeed * Time.deltaTime;
    }
}

 

 

모델에 스크립트를 추가하고 실행하면 방향키를 이용해 걷는 애니메이션과 shift + 방향키를 이용해 뛴다. 


Bland Tree 2D Simple Directional

  1. 새로운 씬을 생성하고, #03_BlendTree_2DSimpleDirectional 으로 씬 저장
  2. Main Camera의 위치를 Position(0, 1, -2)로 설정
  3. unitychan FBX 모델을 Hierarchy View로 Drag & Drop
  4. Animator Controller를 생성하고, unitychan 게임오브젝트에 등록

 

이전 #02 씬을 복제해서 #03 씬을 생성하고 unitychan 모델과 AnimationController(2DSimpleDirectional)을 새로 생성하고, Animator view에 가서 새로운 Blend Tree를 생성한다. 

 

 

생성한 Blend tree의 내부로 이동해서 아래 단계에 맞춰서 설정한다. 파라미터 생성시 float로 생성해야한다. 

 

모션에 대기, 앞으로 걷기, 뒤로 걷기, 왼쪽으로 걷기, 오른쪽으로 걷기 애니메이션을 등록한다. 각각의 모션의 Pos x, Pos y 값을 다음과 같이 설정한다.

 

 

PlayerController2DSimple.cs

위의  Blend Tree를 제어하는 스크립트 코드를 작성해보았다. 

using UnityEngine;

public class PlayerController2DSimple : MonoBehaviour
{
    private Animator animator;

    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        float horizontal = Input.GetAxis("Horizontal"); // 좌, 우 방향키 입력
        float vertical = Input.GetAxis("Vertical"); // 위, 아래 방향키 입력

        // horizontal 값에 따라 애니메이션 재생 (-1: 왼쪽, 0: 가운데, 1: 오른쪽)
        animator.SetFloat("Horizontal", horizontal);
        // vertical 값에 따라 애니메이션 재생 (-1: 뒤, 0: 가운데, 1: 앞)
        animator.SetFloat("Vertical", vertical);

        // 이동속도
        // float moveSpeed = 5.0f;
        // 실제 이동
        // transform.position += new Vector3(horizontal, 0, vertical) * moveSpeed * Time.deltaTime;
    }
}

 

게임을 실행했을 때 입력하는 화살표 방향대로 움직이는 것을 확인할 수 있다. 


Blend Tree 2D Freeform Directional 

  1. 새로운 씬을 생성하고, #04_BlendTree_2DFreeformDirectional 으로 씬 저장
  2. Main Camera의 위치를 Position(0, 1, -2)로 설정
  3. unitychan FBX 모델을 Hierarchy View로 Drag & Drop
  4. Animator Controller를 생성하고, unitychan 게임오브젝트에 등록

 

unitychan 오브젝트를 Hierarchy view에 등록해서 생성한 Animation Controller를 등록한 뒤 Animator view에서 Blend Tree를 생성한다.  이후 아래의 단계를 따른다. 

 

Blend Type을 2D Freeform Directional로 설정하고, Parameters 2개 이름을 “Horizontal”, “Vertical”로 설정하고, Blend Tree의 Parameter에 등록한다.

Add Motion으로 9개의 Motion 생성해서 대기, 각각의 방향 대한 걷기 각각의 방향 대한 달리기를 등록한다. (앞, 뒤, 왼, 오 순서) 뒤로 달리는 것은 없기 때문에 뒤로 걷기를 한번 더 등록하고, Pos x, Pos y를 아래와 같이 설정한다.

 

PlayerController2DFreeformD.cs

위의 Blend Tree를 제어하기 위해 스크립트를 작성해보았다. 
using UnityEngine;

public class PlayerController2DFreeformD : MonoBehaviour
{
    private Animator animator;
    // private float walkSpeed = 4.0f;
    // private float runSpeed = 8.0f;

    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        float horizontal = Input.GetAxis("Horizontal"); // 좌, 우 방향키 입력
        float vertical = Input.GetAxis("Vertical"); // 위, 아래 방향키 입력
        // shift 키를 안누르면 최대 0.5, shift 키를 누르면 최대 1까지 값이 바뀌게 된다
        float offset = 0.5f + Input.GetAxis("Sprint") * 0.5f;

        // horizontal 값에 따라 애니메이션 재생 (-1: 왼쪽, 0: 가운데, 1: 오른쪽)
        animator.SetFloat("Horizontal", horizontal * offset);
        // vertical 값에 따라 애니메이션 재생 (-1: 뒤, 0: 가운데,1: 앞)
        animator.SetFloat("Vertical", vertical * offset);

        // 이동속도 : shift키를 안눌렀을 땐 walkSpeed, shift키를 눌렀을 땐 runSpeed값이 moveSpeed에 저장
        // float moveSpeed = Mathf.Lerp(walkSpeed, runSpeed, Input.GetAxis("Sprint"));
        // 실제이동
        // transform.position += new Vector3(horizontal, 0, vertical) * moveSpeed * Time.deltaTime;
    }
}

 

위의 스크립트를 등록하면 Horizontal과 Vertical 값이 바뀌는걸 볼 수 있다. 

 


Blend Tree 2D Freeform Cartesian 

기본 설정

  1. 새로운 씬을 생성하고, #05_BlendTree_2DFreeformCartesian 으로 씬 저장
  2. Main Camera의 위치를 Position(0, 1, -2)로 설정
  3. unitychan FBX 모델을 Hierarchy View로 Drag & Drop
  4. Animator Controller를 생성하고, unitychan 게임오브젝트에 등록

Blend Tree 설정

 
  1. Parameters 2개 이름을 “Horizontal”, “Vertical”로 설정하고, Blend Tree의 Parameter에 등록
  2. Blend Type을 2D Freeform Cartesian으로 설정
  3. Add Motion으로 4개의 Motion 생성
  4. Assets - unity-chan! - Art - Animations 폴더의 애니메이션을 Motion에 등록

 

모션에 대기, 앞으로 뛰기, 왼쪽으로 뛰기, 오른쪽으로 뛰기 등록하고 Pos x, Pos y을 지정한다. 

 

 

 

 

PlayerController2DFreeformC.cs

using UnityEngine;

public class PlayerController2DFreeformC : MonoBehaviour
{
    private Animator animator;
    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        float horizontal = Input.GetAxis("Horizontal"); // 좌, 우 방향키 입력
        float vertical = Input.GetAxis("Vertical"); // 위, 아래 방향키 입력

        // horizontal 값에 따라 애니메이션 재생 (-1: 왼쪽, 0: 가운데, 1: 오른쪽)
        animator.SetFloat("Horizontal", horizontal);
        // vertical 값에 따라 애니메이션 재생 (0: 가운데, 1: 앞)
        animator.SetFloat("Vertical", vertical);
    }
}
 
 
 

움직이는 방향키에 따라 자연스럽게 사선으로 회전하여 달린다.


Blend Tree Direct

기본 설정

  1. 새로운 씬을 생성하고, #06_BlendTree_Direct로 씬 저장
  2. Main Camera의 위치를 Position(0, 1.3, -0.5)로 설정
  3. unitychan FBX 모델을 Hierarchy View로 Drag & Drop
  4. Animator Controller를 생성하고, unitychan 게임오브젝트에 등록

 

블랜드 트리할 것이 얼굴이기 때문에 Animator view > base layer에 wait00이라는 애니메이션을 등록한다.

 

Project View > “+” >  Avatar Mask 해서 FaceAvatar 을 생성한다. 

 
 

FaceAvatar에 unitychanAvatar을 등록후 얼굴만 해야하기 때문에 import skeleton을 한다. 모든 관절의 정보를 다 해제하고 설정을 해준 상태에서 아래의 얼굴 정보를 찾아서 다시 설정한다. 

 

face layer라는 새로운 레이어를 생성해서 가중치는 1, 생성한 face avatar를 등록한다.

 

Blend Tree 설정

  1. 4개의 표정 모션을 사용하기 때문에 Parameters를 4개 생성 (angry, eye, sap, smile)
  2. Blend Type을 Direct로 설정
  3. Add Motion으로 4개의 Motion을 생성하고, Parameter 등록

 

1번
2,3번

PlayerControllerDirect.cs

using System.Collections;
using UnityEngine;

public class PlayerControllerDirect : MonoBehaviour
{
    private Animator animator;

    private void Awake()
    {
        animator = GetComponent<Animator>();
    }

    private void Update()
    {
        KeyEvent(0, KeyCode.Q, "angry"); // Q키를 누르면 angry 파라미터 값 증가
        KeyEvent(1, KeyCode.A, "angry"); // A키를 누르면 angry 파라미터 값 감소

        KeyEvent(0, KeyCode.W, "eye"); // W키를 누르면 eye 파라미터 값 증가
        KeyEvent(1, KeyCode.S, "eye"); // S키를 누르면 eye 파라미터 값 감소

        KeyEvent(0, KeyCode.E, "sap"); // E키를 누르면 sap 파라미터 값 증가
        KeyEvent(1, KeyCode.D, "sap"); // D키를 누르면 sap 파라미터 값 감소

        KeyEvent(0, KeyCode.R, "smile"); // R키를 누르면 smile 파라미터 값 증가
        KeyEvent(1, KeyCode.F, "smile"); // F키를 누르면 smile 파라미터 값 감소

    }

    private void KeyEvent(int type, KeyCode key, string parameter)
    {
        // key를 누르면 파라미터 값 증가/감소 시작
        if (Input.GetKeyDown(key))
        {
            string coroutine = type == 0 ? "ParameterUp" : "ParameterDown";
            StartCoroutine(coroutine, parameter);
        }
        // key를 때면 파라미터 값 증가/감소 중지
        else if (Input.GetKeyUp(key))
        {
            string coroutine = type == 0 ? "ParameterUp" : "ParameterDown";
            StopCoroutine(coroutine);
        }

    }

    private IEnumerator ParameterUp(string parameter)
    {    
        // 현재 파라미터 값을 받아온다
        float percent = animator.GetFloat(parameter);

        // 파라미터 값을 증가시키는 코루틴이기 때문에 1이 될때까지 실행

        while (percent < 1)
        {
            percent += Time.deltaTime; // percent 값 증가
            animator.SetFloat(parameter, percent);

            yield return null;
        }
    }

    private IEnumerator ParameterDown(string parameter)
    {
        // 현재 파마미터 값을 받아온다
        float percent = animator.GetFloat(parameter);

        // 파라미터 값을 감소시키는 코루틴이기 때문에 0이 될때까지 실행
        while (percent > 0)
        {
            percent -= Time.deltaTime; // percent 값 감소 
            animator.SetFloat(parameter, percent);

            yield return null;
        }
    }
}
 

 

설정한 단축키에 따라 각각의 파라미터 값이 변하는 것을 확인할 수 있다.

728x90

이 글은 인프런 "따라하면서 배우는 고박사의 유니티 기초" 강의를 수강한 후 정리한 글입니다. 

 

[지금 무료] 따라하면서 배우는 고박사의 유니티 기초 | 고박사 - 인프런

고박사 | 유니티로 게임을 개발하고 싶은 초보자를 대상으로 하며, 유니티 설치부터 2D/3D 게임 개발에 필요한 기초 지식까지 자세하게 설명합니다. (강의에 사용되는 모든 리소스는 영상 상단의

www.inflearn.com


Animation Layer

게임 캐릭터가 공격을 한다고 할 때 공격은 점프하면서, 걸으면서 할 수 있는데, 걸으면서 아이템 사용, 총 재장전 등을 할 수 있다. 이러한 애니메이션들을 독립적으로 제작하는 것이 아닌 애니메이션 레이어를 이용하여 구현할 수 있다.

 

Animation Layer은 부위별로 서로 다른 애니메이션을 재생하는 것으로 하체는 걷고, 상체는 공격 등의 다른 애니메이션을 재생하는 것이 가능하다.

 

기본 레이어(Base Layer)

기본 레이어는 여러 layer를 만들어 부위별로 다른 애니메이션을 재생하거나 같은 부위도 비율에 따라 애니메이션을 혼합하여 사용할 수 있다.

Animator View > Layers 탭의 위에서부터 순서대로 레이어가 실행되며 +를 눌러 새로운 레이어를 생성할 수 있다. 

Layer 생성

 

각 layer에는 설정 버튼이 존재하며, 가중치를 설정하거나 어느 부위에만 해당 레이어의 애니메이션을 재생할 것인지 설정하는 등 다양한 옵션이 있다. 

 

layer option

​순방향 운동학(Forward Kinematics, FK)과 역운동학(Inverse Kinematics, IK)

 

애니메이션은 기본적으로 순방향 운동학 FK를 바탕으로 애니메이션이 재생되고, 애니메이션이 재생되는 순서는 관절에서 손 끝으로 진행된다.

역 운동학은 손 끝, 발 끝이 먼저 움직이면 그 위치에 맞춰 관절들이 움직이기 때문에 계단을 밟는 것과 같은 애니메이션 재생 시 발바닥이 먼저 닿고 다리 무릎 허벅지 몸 순으로 연산이 되기 때문에 실제 계단을 밟고 있는 것과 같이 더 자연스러운 애니메이션 재생이 가능하다.

Avatar Mask

 

아바타 마스크는 Project View > “+” > Avatar Mask 에서 생성할 수 있다. 신체 부위를 활성/비활성화 하여 애니메이션을 재생하는 부위와 재생하지 않는 부위를 설정할 수 있다. 

 

 

아바타 마스크는 Humanoid, Transform 설정이 있다. 

  • Humanoid: 스켈레톤 단위로 큰 부위를 지정할 수 있다. 부위를 클릭해서 초록색(사용O)/빨간색(사용X)으로 변경
  • Transform: 유니티 게임오브젝트의 레이어 단위로 부위를 지정한다. Animation Type이 Humanoid가 아닐 때나 Humanoid지만 좀 더 세부적으로 부위를 선택할 때 사용한다. (체크된 부위만 사용)

 


Blend Tree

 

Blend Tree는 하나의 상태 안에 여러 개의 애니메이션 클립을 갖게 하고 상태 안에 있는 10억 애니메이션 클립을 파라미터 값에 따라 온전한 하나 또는 두 개 이상의 애니메이션을 혼합해서 재생하는 기능이다.

예를 들어 대기와 걷기 애니메이션을 하나의 브랜드 트리 상태로 설정하고 대기와 걷기 뿐만 아니라 서서히 걷기, 서기와 같은 애니메이션을 재생할 수 있다. 

Blend Tree는 Animator View > 마우스 오른쪽 클릭 > Create State > From New Blend Tree 로 생성할 수 있다

Blend Tree를 생성하면 Float 파라미터 1개가 자동으로 생성된다. 상태를 선택하면 inspector view의 현재 Blend Tree의 기본 정보가 출력되며 이름, 속도 등을 설정할 수 있다. 

 

Blend Tree 설정

블렌드 트리 용도에 따라 설정한다. 타입에 따라 파라미터 개수가 달라진다.

  • Blend Type: 블렌드 트리의 속성 (1D, 2D, Direct)
  • Parameter : 어떤 애니메이션 클립 or 블렌드 트리를 재생할 것인지 제어 (현재 Animator의 파라미터 목록에서 선택)
  • Motion : 블렌드 트리에 등록되는 애니메이션 클립 or 블렌드 트리

Blend Type

블렌드 트리는 블렌드 방식에 따라 아래 5가지로 나뉜다. 

 

 

Blend Type : 1D

하나의 파라미터로 애니메이션을 블랜드하며, 대기/걷기/뛰기를 매끄럽게 연결하고 이동속도의 변화에 따라 서서히 뛰기, 서서히 멈추기 등의 애니메이션을 블렌드 하려고 할 때 사용한다. 

 

애니메이터에 비해 파라미터 목록에서 float 파라미터를 선택해서 설정하고 모션에 원하는 애니메이션을 등록한다. 이때 모션에 등록되는 애니메이션의 개수에 따라 최대 2개의 애니메이션이 블랜드 될 수 있도록 영역이 분할된다. 

위의 예제와 같이 3개의 애니메이션을 등록하면 3개의 영역으로 분할된다. 

결과적으로 위와 같은 설정을 하는 경우 movespeed의 값이 변환되면 그에 따라 재생되는 애니메이션이 달라지게 된다.

 

Blend Tree : 2D Simple Directional

방향성을 가지는 Blend Tree로 2 개의 파라미터로 애니메이션 블렌드 시에 사용한다.

​2D는 사용용도에 따라서 세 종류로 나눌 수 있으며 2D Simple Directional의 경우 모두 다른 방향을 향하는 애니메이션을 하나의 Blend Tree로 구성할 때 사용한다. 

 

아래 화면과 같이 대기 및 각 방향 걷기(전/후/좌/우)를 등록하였을 대 파라미터를 두 개 사용하기 때문에 Threshold 값 대신 pos X, pos  Y 값을 설정한다. 

 

​파라미터 값에 따라 온전한 1개의 애니메이션이 재생되거나 애니메이션이 블랜드 되어 재생될 것이다. 결과적으로 Horizonts와 Vertical 값 변화에 따라 재생되는 애니메이션이 달라지게 된다. 

 

2D Simple Directional의 특징

Blend Tree : 2D Freeform Directional

다른 방향과 같은 방향이 함께 있는 경우에 사용하며, 같은 방향에 여러 개의 애니메이션 배치가 가능하기 때문에 걷기, 뛰기를 함께 배치한다.

결과적으로 대기, 각 방향 걷기(전/후/좌/우), 각 방향 뛰기(전/후/좌/우)를 등록하여 파라미터 갯수나 모션에 설정되는 옵션은 2D Simple Directional과 동일하며 결과적으로 Horizonts와 Vertical 값 변화에 따라 재생되는 애니메이션이 달라지게 된다. 

 2D Freeform Directional vs 2D Freeform Cartesian

이는 두 모션에 범위가 설정되는 모양이 다르다. 

 

Blend Tree : 2D Freeform Cartesian

 

주로 동일한 방향에 대한 애니메이션에 사용하도록 권장한다. 예시를 들어, 전방의 좌/우를 쳐다보며 이동 중인 FPS 캐릭터가 45도 방향으로 총구를 겨누는 것과 같은 애니메이션에서 사용된다. 

 

 

 
 

​Blend Type : Direct

모션 별로 별도의 파라미터를 설정할 수 있으며, 얼굴의 모션과 같이 각기 다른 부위를 조금씩 혼합하여 싶을 때 사용한다.

 

 

728x90

이 글은 인프런 "솔리디티 깨부수기" 강의를 수강한 후 정리한 글입니다. 

 

[지금 무료] 솔리디티 깨부수기 | D_One - 인프런

D_One | 이 강의를 통해서, 스마트 컨트랙 제작을 위한 솔리디티 언어를 배울수 있습니다., 코딩이 처음인 분들도 OK! 처음 배우는 솔리디티, 쉽게 시작해보세요. 강의 주제 📖 [사진] 이 강의에서

www.inflearn.com


상속

상속이란, 윗 사람이 죽으면, 그 죽은 사람의 재산 이나 권리를 아랫 사람에게 주는것으로 스마트 컨트랙 내에서도 상속이 이루어진다. 

스마트 컨트랙 사이의 상속은 재산이나 권리를 주는것이 아닌, 변수와 함수들을 상속 해준다.

 

예제 코드를 작성하자면,  Father 과 Son 두개의 부자관계의 컨트랙을 생성하고 Father 컨트랙에 기능을 구현 후, 아들이 아버지의 기능을 상속받도록 구현하였다. 

contract Father{
    string public familyName = "Kim";
    string public givenName = "Jung";
    uint256 public money = 100; 
    
    function getFamilyName() view public  returns(string memory){
        return familyName;
    } 
    
    function getGivenName() view public  returns(string memory){
        return givenName;
    } 
    
    function getMoney() view public returns(uint256){
        return money;
    }
    

}

현재 아버지 컨트랙에는 3개의 변수 3개의 함수가 있으며, familyName 과 givenName, money 3개의 변수를 정의한다. 

성은 kim 이름은 Jung 이며 money는 아버지의 재산이라고 가정하고,  100 이라는 값을 입력한다. 

 

나머지 3 개의 함수들은 각각 3개의 변수 성 familyName, 이름 givenName, 재산 money 를 리턴한다. 

 

이후 아들 컨트랙에서 아버지 컨트랙에서 정의한 3개의 변수와 함수를 상속 받아서, 해당 함수들과 변수들을 접근하려고 한다. 

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract Father{
    string public familyName = "Kim";
    string public givenName = "Jung";
    uint256 public money = 100; 
    
    function getFamilyName() view public  returns(string memory){
        return familyName;
    } 
    
    function getGivenName() view public  returns(string memory){
        return givenName;
    } 
    
    function getMoney() view public returns(uint256){
        return money;
    }
    

}

contract Son is Father{
    
}

 

상속하는 방법은 간단하다. 상속해야할 입장의 컨트랙에서 상속해야할 컨트랙을 작성하면 된다. 

 

상속 받을 컨트랙 is 상속 주는 스마트 컨트랙 {

       //....

}

 

위의 예제와 같이 코드를 작성하면 아들 컨트랙을 배포했을 때, 아버지 컨트랙의 함수들과 변수들에 접근할 수 있다. 

 

 

 

그렇다면 아버지 컨트랙에 constructor가 있다면 constructor까지 상속을 해야하는지에 대해서 알아보고자 한다. 

 

contract Father{
    string public familyName = "Kim";
    string public givenName = "Jung";
    uint256 public money = 100; 
    
    constructor(string memory _givenName) public {
        givenName = _givenName;
    }
    
    
    function getFamilyName() view public  returns(string memory){
        return familyName;
    } 
    
    function getGivenName() view public  returns(string memory){
        return givenName;
    } 
    
    function getMoney() view public returns(uint256){
        return money;
    }
    

}

위의 예제에서 아버지 컨트랙을 보면 constructor 가 정의되었으며, givenName을 변경할 수 있다.

이는 아들이 아버지의 것을 상속받는다했을 때, 성은 동일하지만 이름은 다르기 때문에 constructor을 통해서 이름을 다르게 지정할 수 있도록 할 수 있다. 

 

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract Father{
    string public familyName = "Kim";
    string public givenName = "Jung";
    uint256 public money = 100; 
    
    constructor(string memory _givenName) public {
        givenName = _givenName;
    }
    
    
    function getFamilyName() view public  returns(string memory){
        return familyName;
    } 
    
    function getGivenName() view public  returns(string memory){
        return givenName;
    } 
    
    function getMoney() view public returns(uint256){
        return money;
    }
    

}

contract Son is Father("James"){
    
  

}

위에 예제와 같이 파라미터 값으로 아들의 이름을 입력 받을 수 있다. 

 

 

아들 컨트랙을 배포하면  givenName이 아버지의 이름 Jung 이 아닌 James임 을 알수가 있다.

728x90

이 글은 인프런 "솔리디티 깨부수기" 강의를 수강한 후 정리한 글입니다. 

 

[지금 무료] 솔리디티 깨부수기 | D_One - 인프런

D_One | 이 강의를 통해서, 스마트 컨트랙 제작을 위한 솔리디티 언어를 배울수 있습니다., 코딩이 처음인 분들도 OK! 처음 배우는 솔리디티, 쉽게 시작해보세요. 강의 주제 📖 [사진] 이 강의에서

www.inflearn.com


constructor

생성자는, 스마트컨트랙이 생성 또는 배포, 그리고 인스턴스화 될때 초기값을 설정해주는 용도로 사용하며, 주로 변수의 값을 초기화할 때 사용한다. 

스마트 컨트랙이 처음 생성될 때 배포되거나 인스턴스화 될 때 초기 변수의 파라미터 값을 고 스마트 컨트랙이 생성된다.

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract A{
    
    string public name;
    uint256 public age;
    
    constructor(string memory _name, uint256 _age){
        name = _name;
        age = _age;
    }
        
}

contract B{
    
  A instance = new A("Alice", 52);
  function get() public view returns(string memory, uint256) {
        return (instance.name(), instance.age());

}

위의 예제에서 A 컨트랙를 인스턴스화했는데 constructor을 정의함으로 A의 초기값을 정의할 수 있다. 즉 생성자는 어떠한 인스턴스, 컨트랙을 인스턴스화 할 때 초기값을 넣어주게 한다. 

위의 예제에서는 name 과 age 변수 값을 정의하고 constructor에 두 변수를 파라미터 값으로 입력 받아온다. 

그리고 B 컨트랙에서 A 컨트랙의 인스터스화를 위하여 constructor 생성자에서 받아온 파라미터 값을 넣어준다. 각각 name과 age 변수는 "Alice" ,52로 입력받게 된다. 

 

해당 값들을 리턴하기 위해서 B 컨트랙에서 get() 함수로 name과 age 복수의 변수값을 리턴할 수 있다. 컨트랙을 배포하면 name과 age 입력된 값을 확인할 수 있다. 

 

 

다음으로 name,age 값을 변경하는 실습을 진행하겠다. 함수를 통해서 값을 변경하기 위해서는 A 컨트랙에 정의한 name과 age 변수 값들 또한 변경해줘야한다. 이는 change 함수를 이용하여 생성자에서 설정한 name과 age 값을 변경할 수 있다. 

 

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract A{
    
    string public name;
    uint256 public age;
    
    constructor(string memory _name, uint256 _age){
        name = _name;
        age = _age;
    }
        
    function change(string memory _name, uint256 _age) public  {
         name = _name;
         age = _age;
    }
}

contract B{
    
  A instance = new A("Alice", 52);
  
  function change(string memory _name, uint256 _age) public  {
        instance.change(_name,_age);
    }
  
  function get() public view returns(string memory, uint256) {
        return (instance.name(), instance.age());
    }

}

위의 예제에서 A 컨트랙에 change 함수를 정의하고 B 컨트랙에서는 A 컨트랙을 인스턴스화해서 change함수에 접근한다.  사용자에게 입력을 받고 파라미터 값들을 바꿀 수 있다. 

위에는 B 컨트랙을 배포하여 A 인스턴스를 통해 name과 age 변수값을 받고 change 함수를 통해 변경할 수 있다. 그렇다면 A 컨트랙을 배포한다면 어떻게 될까? 

배포를 하기 전에 constructor은 a를 쓰기 전에 먼저 지정을 해줘야 하기 때문에 값을 받는다. 값이 따로 저장된 것을 확인할 수 있는데, 이는 A와 인스턴스 A는 완전히 별개의 것이기 때문이다. 

 

이런 식으로 B 컨트랙 안에 A 컨트랙을 인스턴스화해서 접근하는 방식은 많은 가스 비용을 유발한다. 이는 B 컨트랙에서 A컨트랙의 전부를 가져오기 때문에 인스턴스화해서 사용하는 방식은 운영하고자 하는 스마트 컨트랙이 어떻게 동작하냐에 따라 신중하게 선택할 필요가 있다. 

 

비용적인 측면보다 블록마다 가스를 소비할 수있는 양은 제한적이며 초과하게 되는 경우 이더리움 자체에서 에러가 발생해 스마트 컨트랙 배포가 불가능하게되는 상황이 발생한다. 

 

이러한 블록마다 가스 비용을 제한하는 것은 보안적인 측면에서 고려한 것으로 클론 팩토리 패턴을 이용해서 가스 비용을 획기적으로 줄일 수 있는 방법또한 있다.

728x90

이 글은 인프런 "솔리디티 깨부수기" 강의를 듣고 정리한 글 입니다. 

 

[지금 무료] 솔리디티 깨부수기 | D_One - 인프런

D_One | 이 강의를 통해서, 스마트 컨트랙 제작을 위한 솔리디티 언어를 배울수 있습니다., 코딩이 처음인 분들도 OK! 처음 배우는 솔리디티, 쉽게 시작해보세요. 강의 주제 📖 [사진] 이 강의에서

www.inflearn.com


Instance 정의

Instance는 하나의 컨트랙에서 다른 컨트랙을 접근할 때 사용한다.

예를 들어 A 와 B 컨트랙이 있을 때,  B 컨트랙에서 A 의 함수나 변수들을 접근하여 사용하고자 한다면, A 인스턴스를 만들어 B 컨트랙 안에서 사용하면 된다. 

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract A{
    
    uint256 public a = 5;
    
    function change(uint256 _value) public {
        a = _value;
    } 

}

contract B{

}

위의 예제에서는 B 컨트랙에서  A 컨트랙에 접근하여, 변수 a 와 change 함수를 사용하려고 한다. 이때 B 컨트랙과 A 컨트랙과의 연결을 위해 B 컨트랙에서 A를 인스턴스 정의를 해야한다.

 

contract B{
    
    A instance = new A();
    
  }

인스터스를 정의할 때에는 [컨트랙이름]  [인스터스의 이름] = new  [컨트랙이름](); 식으로 인스턴스를 정의할 수 있다.

이렇게 인스턴스를 생성하였고, 생성된 인스턴스를 통해서 A 컨트랙의 변수와 함수에 접근하도록 하겠다. 

// SPDX-License-Identifier:GPL-30
pragma solidity >= 0.7.0 < 0.9.0;

contract A{
    
    uint256 public a = 5;
    
    function change(uint256 _value) public {
        a = _value;
    } 

}

contract B{
    
    A instance = new A();
    
    function get_A() public view returns(uint256) {
        return instance.a();
    }
    function change_A(uint256 _value) public  {
        instance.change(_value);
    }    

}

위의 예제에서 B 컨트랙은 A 컨트랙의 a 변수를 리턴하는 get_A() 함수와 a 변수를 변경해주는 change_A() 함수가 있다. 생성한 A instance 는 . 붙여서 해당하는 변수나 함수에 접근할 수 있다.

get_A() 에서 컨트랙 A의 a 변수에 접근해야 하므로 instance.a()를 썼다. 여기서 변수를 접근할 때에 뒤에 ()를 붙여야 리턴이 된다.

instance.change() 에 파라미터 값에 value를 넣어준다. view를 사용한 이유는 a 변수 값을 읽어만 오고, 변경하지 않기 때문에 view 키워드를 사용하였다.

 

(좌) 변경 전, (우) 변경

instance 는 A 컨트랙의 원본의 것을 가지고 오는 것이 아닌 분신을 만들어 가지고와 사용하기 때문에, instance를 만들어 변수 a의 값을 변경한다고 해도 A 컨트랙 자체만 따로 배포한 곳의 값에는 영향을 주지 않는다. 

즉 A 컨트랙을 따로 배포하고, 인스턴스 A를 B 컨트랙을 통해서 배포한다고 가정하였을때, 이 두개의 컨트랙은 완전히 다르다.

 

+ Recent posts