반응형

Consumer는 1개의 Type T 인자를 받고 리턴 값이 없는 함수형 인터페이스입니다.

@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

}

Example 1 : Consumer

Consumer는 Lambda 표현식으로 구현할 수 있습니다. accept() 호출과 함께 인자를 전달하면 구현된 내용이 수행됩니다.

import java.util.function.Consumer;

public class ConsumerExample1 {

    public static void main(String[] args) {
        Consumer<String> consumer = s -> System.out.println(s.toUpperCase());

        consumer.accept("hello world");
    }
}

Output:

HELLO WORLD

Example 2 : Primitive Consumer

Java는 Primitive type에 대한 Consumer 클래스를 제공합니다. IntConsumer 외에 DoubleConsumer, LongConsumer가 있습니다.

import java.util.function.IntConsumer;

public class ConsumerExample2 {

    public static void main(String[] args) {
        IntConsumer consumer = n -> System.out.println(n * 100);

        consumer.accept(5);

        consumer.accept(10);
    }
}

Output:

500
1000

Example 3 : List.forEach()

List.forEach()는 인자로 Consumer를 받습니다.

다음과 같이 Consumer를 이용하여 List의 모든 아이템들을 출력할 수 있습니다.

 

Output:

APPLE
KIWI
ORANGE

Example 4 : andThen()

andThen()은 Consumer들을 연결해주는 Chaining 메소드입니다.

아래 코드에서 addNumber.andThen(printList).accept(fruits)를 호출하면 addNumber()가 수행된 이후에 printList()가 수행됩니다. 두개의 메소드로 전달되는 인자는 fruits로, 동일한 객체가 전달됩니다.

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample4 {

    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("apple", "kiwi", "orange");

        Consumer<List<String>> addNumber = list -> {
            for (int i = 0; i < list.size(); i++) {
                list.set(i, (i + 1) + ". " + list.get(i));
            }
        };

        Consumer<List<String>> printList = list -> {
            for (String fruit : list) {
                System.out.println(fruit);
            }
        };

        addNumber.andThen(printList).accept(fruits);
    }
}

Output:

1. apple
2. kiwi
3. orange

실제로 andThen()은 아래처럼 구현되어있습니다.

// Consumer.java
public interface Consumer<T> {
  ...
  default Consumer<T> andThen(Consumer<? super T> after) {
      Objects.requireNonNull(after);
      return (T t) -> { accept(t); after.accept(t); };
  }
}

Example 5 : 함수의 인자로 Consumer 전달 (Higher Order Function)

다음과 같이 Consumer를 인자로 받는 함수를 정의할 수 있습니다.

import java.util.Arrays;
import java.util.List;
import java.util.function.Consumer;

public class ConsumerExample5 {

    public static void main(String[] args) {
        List<String> fruits = Arrays.asList("apple", "kiwi", "orange");

        Consumer<String> printFruit = fruit -> System.out.println("I like " + fruit);

        forEach(fruits, printFruit);
    }

    static <T> void forEach(List<T> list, Consumer<T> consumer) {
        for (T t : list) {
            consumer.accept(t);
        }
    }

}

Output:

I like apple
I like kiwi
I like orange

 

 

ref : https://codechacha.com/ko/java8-consumer-example/

반응형
반응형

 

그림 1은 런타임 라이브러리 종속 항목을 가진 앱을 보여줍니다. 앱 코드를 검사하는 동안 R8은 MainActivity.class 진입점에서 foo(), faz(), bar() 메서드에 연결할 수 있다고 판단합니다. 그러나 런타임에 OkayApi.class 클래스 또는 baz() 메서드가 앱에서 전혀 사용되지 않으며 R8은 앱을 축소할 때 이 코드를 삭제합니다.

 

\

R8은 프로젝트의 R8 구성 파일 -keep 규칙을 이용하여 진입점을 결정합니다. 즉, keep 규칙은 앱을 축소할 때 R8이 삭제하면 안 되는 클래스를 지정하고 R8은 이 클래스를 앱의 진입점으로 사용할 수 있다고 간주합니다. Android Gradle 플러그인과 AAPT2는 앱의 활동, 보기 및 서비스와 같이 대부분의 앱 프로젝트에서 필요한 keep 규칙을 자동으로 생성합니다. 그러나 추가적인 keep 규칙을 사용하여 이 기본 동작을 맞춤설정해야 하는 경우 유지할 코드를 맞춤설정하는 방법에 관한 섹션을 참조하세요.

대신 앱 리소스의 크기를 줄이는 데만 관심이 있다면 리소스 축소 방법에 관한 섹션을 참조하세요.

 

 

 

유지할 코드 맞춤설정

대부분의 상황에서는 기본 ProGuard 규칙 파일(proguard-android- optimize.txt)만 있으면 R8을 이용하여 미사용 코드를 삭제할 수 있습니다. 그러나 R8에서 정확하게 분석하기 어려운 상황도 있으며 실제로 앱에서 사용하는 코드를 삭제하는 경우도 발생할 수 있습니다. 다음은 코드를 잘못 삭제할 수 있는 몇 가지 예입니다.

  • 앱이 자바 네이티브 인터페이스(JNI)에서 메서드를 호출하는 경우
  • 앱이 런타임에 리플랙션 등을 사용하여 코드를 찾는 경우

앱을 테스트하면 잘못된 코드 삭제로 인한 오류가 나타나지만 삭제된 코드 보고서를 생성하여 삭제된 코드를 검사할 수도 있습니다.

오류를 수정하고 R8이 특정 코드를 유지하도록 하려면 ProGuard 규칙 파일에 -keep 줄을 추가합니다. 예:

 
-keep public class MyClass

또는 유지하려는 코드에 @Keep 주석을 추가할 수 있습니다. @Keep을 클래스에 추가하면 전체 클래스가 그대로 유지됩니다. 이 주석을 메서드나 필드에 추가하면 메서드/필드 및 그 이름뿐만 아니라 클래스 이름도 그대로 유지됩니다. 참고로 이 주석은 축소 사용 방법에 관한 섹션에 설명한 대로 AndroidX 주석 라이브러리를 사용하고 Android Gradle 플러그인과 함께 패키징된 ProGuard 규칙 파일을 포함할 때만 사용할 수 있습니다.

-keep 옵션을 사용하려면 고려해야 하는 사항이 많습니다. 규칙 파일을 맞춤설정하는 방법에 관한 자세한 정보는 ProGuard 설명서를 참조하세요. 문제 해결 섹션에서는 코드를 제거할 때 발생할 수 있는 다른 일반적인 문제를 간략히 설명합니다.

 

 

 

ref : https://developer.android.com/studio/build/shrink-code?hl=ko

반응형

'프로그래밍(Programming) > Java' 카테고리의 다른 글

Java : Consumer  (0) 2022.01.12
스트림 변환 메서드들 표  (0) 2021.12.31
interface default 키워드로 메소드 구현하기  (0) 2021.12.30
[Java] Comparable, comparator  (0) 2021.12.15
[Java] Collection , Map, Tree  (0) 2021.12.15
반응형

2022년(2021년 귀속분) 연말정산 부터 국세청 홈택스에 접속할 필요 없이 회사가 정리한 서류를 확인하는 방식으로 간소화됩니다.

 

 

연말정산 미리보기

연말정산시, 잘 못 정산을 하여 돈을 환급해줘야 하는 경우가 생기는 되는데요. 이를 위해 홈택스 사이트에서 제공되는 미리보기 서비스에 들어가면 올해 1월부터 9월가까지의 신용.체크카드, 현금영수증 사용내역을 볼수 있습니다. 10월 이후의 예상 사용액을 입력하면 연말 정산 예상 결과를 확인할 수 있습니다. (팁! 부부 가운데 어느 쪽에 공제를 몰아주는 것이 좋을지 모의 계산도 가능합니다)

 

연말정산 미리보기 모의계산하는 방법

① 국세청 홈택스 홈으로 들어갑니다.

② 세금종류별 서비스 > 세금모의 계산으로 들어갑니다.

 

 

③ 모의계산 화면에서 연말정산 자동계산> 아래 칸 연말정산 자동계산하기를 클릭하여 2021년귀속분을 선택합니다.

 

④ 2021년 귀속 연말정산 자동계산화면에서 모의 계산을 해봅니다.

 

 

 

 

신용카드 공제 혜택

신용카드 등 사용액을 공제 받으려면 총 급여의 4분의 1이상을 사용해야 합니다.

① 아직 채우지 못했다면 지금부터 공제율이 15%인 신용카드보다 공제율이 30%인 현금이나 체크카드를 사용하는 것이 나을 수 있습니다.

② 공제 한도를 다 채운 경우라면 전통시장 사용이나 대중교통 이용액 같은 별도의 공제 항목을 채운것도 좋은 방법일 수 있습니다.

 

 

 

 

 

코로나19 공제 혜택

신용카드와 현금영수증을 모두 합쳐 작년보다 5%를 초과하여 사용하였다면, 초과 금액의 10%를 추가로 공제해줍니다.

예를들어 작년에 1천만을 사용하고 올해는 작년보다 500만원이 많은 1천500만원을 사용했다면, 5%인 50만원을 초과한 금액인 450만원에 대해서 10%인 45만원을 소득에서 공제해 줍니다. (한도액은 100만원입니다)

 

 

 

 

 

기부금 세액 공제

기부금 세액공제율도 올해 한시적으로 5% 늘어나는데 1천만원 이하의 기부금은 15%에서 20%로, 1천만원을 초과하면 30%에서 35%로 적용됩니다.

월세 세액 공제

무주택 세대주이면서 연봉 7천만원 이하의 국민 주택규모 85제곱미터 이하 아파트나 오피스텔 등에서 살면서 낸 월세연간 750만원 한도내에서 10%의 세액 공제를 받을 수 있습니다.( 단, 반드시 전입신고가 되어 있어야 합니다)

의료비공제

총 급여액의 3%를 초과하여 지출한 금액의 15%를 세액 공제를 받을 수 있습니다.

예를들어 총급여액이 5천만원인 사람은 3%인 150만원을 넘은 금액부터 공제를 받을 수 있습니다. 맞벌이 부부라면 조금이라도 소득이 적은쪽에 의료비를 몰아주는게 유리합니다. 또한 실손보험금을 받았다면 그 금액은 공제 받을 수 없으므로 제외하고 신고 해야합니다.

안경 콘택트렌즈 정산

안경과 콘택트렌즈 구입비가 올해부터 연말정산 간소화서비스 자료에 자동으로 입력이 됩니다. 총 급여 7천만원 이하 근로자는 200만원까지 의료비 공제에 합산이 가능합니다.

교육비 공제

초,중,고 학원비는 연말정산 대상이 아닙니다. 교복,체육복 구입비는 공제 대상이지만 반드시 교복 전문점에서 구입해야 하며, 만일 아닌 경우에는 증명 서류를 제출 해야합니다. (단, 취학 전 아동의 학원비는 연말 공제 대상에 포함 되며 자녀 1명 당 3백만원 한도로 실제 지출한 비용의 15%를 세액 공제 받을 수 있습니다. 올해 입학을 했다면 입학 전인 1~2월 학원비는 공제가 됩니다. 하지만 방문학습지, 백화점 문화센터, 사회복지기관 산하 교육기관의 수강료는 대상이 아닙니다.)

중고차 구입 공제

최대 350만원 한도로 중고차를 구매한 금액의 10%를 소득공제 받을 수 있습니다.( 2018년 도입)

퇴직연금(IRP) 공제

IRP계좌에 돈을 넣어두면 연간 700만원(연금저축 포함) 한도로 세액공제 헤택을 받을 수 있습니다.

종전 연말정산 자료 방식

① 노동자가 직접 세무서나 홈택스 누리집을 방문해 연말정산에 필요한 서류를 조회해 회사에 관련 자료를 제출해야 했습니다.

② 회사는 이를 받은 뒤에 연말정산 내용을 산정할 수 있었습니다.

③ 국세청은 연말정산을 위해 노동자들이 직접 조회하고 자료 제출 등의 불편이 줄고 고령자나 외국인 등 인터넷 사용에 익숙하지 않은 납세자들이 직접 세무서를 찾는 등의 번거로움도 감소할 것으로 예상하고 있습니다.

연말정산 간소화 방식

2021년 귀속분 연말정산은 회사가 세무당국의 자료를 넘겨받아 노동자의 연말정산 내용을 산정합니다. 노동자는 회사가 제시한 연말정산 결과를 보고 사실 여부만 판단하면 됩니다. 근로자는 추가 또는 수정할 사항이 있을 때만 회사에 증명 자료를 제출하면 됩니다.

근로자가 회사에 연말 정산 신청서를 제출하면, 회사는 국세청에 신청 명단을 등록합니다.

② 근로자 확인을 거친후, 국세청은 연말정산 간소화 자료를 회사에 일괄 제공합니다 (단, 노동자가 먼저 정보 제공에 동의해야 합니다.)

③ 회사는 연말정산을 진행하고 확인 결과를 근로자에게 제공합니다.

서비스는 신청 회사부터 우선 적용하고, 향후 대상을 확대할 계획입니다. 노동자는 서비스를 이용하려면 사전에 회사에 본인과 부양가족의 연말정산간소화 자료 제공에 동의해야 합니다.

근로자 신청서 제출과 명단 등록기간

2022년 1월 14일까지

근로자 확인

2022년 1월 19일

국세청 연말정산 자료 제공

2022년 3월 10일까지

참고사항

· 근로자가 신청 내역을 확인하지 않을 경우, 연말정산 간소화 자료가 회사에 제공되지 않습니다.

※ 근로자가 회사에 제공을 원치 않는 민감한 정보를 지정하면, 일괄제공 대상에서 배제됩니다.

· 회사는 국세청에서 제공 받은 간소화 자료를 활용해 공제신고서와 지급명세서를 한꺼번에 작성해 제출 할 수 있고, 근로자는 추가,수정할 사항이 있는 경우에만 증명자료를 회사에 제출학 소득,세액 공제 내역을 확인하는 방식으로 연말정산을 완료할 수 있습니다.

· 내년 1~2월에 받는 연말정산의 경우 신청한 회사에 한해 서비스를 제공하고, 2023년(2022년 귀속분)부터 전 국민에게 확대할 계획입니다.

 

반응형
반응형

 

 

ref : https://www.youtube.com/watch?v=VUh_t_j9qjE&list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp&index=171

반응형

'프로그래밍(Programming) > Java' 카테고리의 다른 글

Java : Consumer  (0) 2022.01.12
Java @Keep (Android )  (0) 2022.01.03
interface default 키워드로 메소드 구현하기  (0) 2021.12.30
[Java] Comparable, comparator  (0) 2021.12.15
[Java] Collection , Map, Tree  (0) 2021.12.15
반응형

인터페이스의 default method

인터페이스의 default 메소드

JAVA 8이 등장하면서 interface에 대한 정의가 몇 가지 변경되었다.

default메소드

  • 인터페이스가 default키워드로 선언되면 메소드가 구현될 수 있다. 또한 이를 구현하는 클래스는 default메소드를 오버라이딩 할 수 있다.
    public interface Calculator {
        public int plus(int i, int j);
        public int multiple(int i, int j);
        default int exec(int i, int j){      //default로 선언함으로 메소드를 구현할 수 있다.
            return i + j;
        }
    }

    //Calculator인터페이스를 구현한 MyCalculator클래스
    public class MyCalculator implements Calculator {

        @Override
        public int plus(int i, int j) {
            return i + j;
        }

        @Override
        public int multiple(int i, int j) {
            return i * j;
        }
    }

    public class MyCalculatorExam {
        public static void main(String[] args){
            Calculator cal = new MyCalculator();
            int value = cal.exec(5, 10);
            System.out.println(value);
        }
    }
  • 인터페이스가 변경이 되면, 인터페이스를 구현하는 모든 클래스들이 해당 메소드를 구현해야 하는 문제가 있다. 이런 문제를 해결하기 위하여 인터페이스에 메소드를 구현해 놓을 수 있도록 하였다.

static메소드

    public interface Calculator {
        public int plus(int i, int j);
        public int multiple(int i, int j);
        default int exec(int i, int j){
            return i + j;
        }
        public static int exec2(int i, int j){   //static 메소드 
            return i * j;
        }
    }

    //인터페이스에서 정의한 static메소드는 반드시 인터페이스명.메소드 형식으로 호출해야한다.  

    public class MyCalculatorExam {
        public static void main(String[] args){
            Calculator cal = new MyCalculator();
            int value = cal.exec(5, 10);
            System.out.println(value);

            int value2 = Calculator.exec2(5, 10);  //static메소드 호출 
            System.out.println(value2);
        }
    }
  • 인터페이스에 static 메소드를 선언함으로써, 인터페이스를 이용하여 간단한 기능을 가지는 유틸리티성 인터페이스를 만들 수 있게 되었다.

 

 

ref : https://programmers.co.kr/learn/courses/5/lessons/241

반응형

'프로그래밍(Programming) > Java' 카테고리의 다른 글

Java @Keep (Android )  (0) 2022.01.03
스트림 변환 메서드들 표  (0) 2021.12.31
[Java] Comparable, comparator  (0) 2021.12.15
[Java] Collection , Map, Tree  (0) 2021.12.15
RMI 개념, 분산 시스템이란  (0) 2012.10.31
반응형

 

 

 

역대 사상 최대의 실업률..  25.6%..      4명중 한명은 직장이 없는 상태로 심각한상태..

 

여기에 기업들의 눈높이는 더욱 더 높아지는 상태

 

 

한국경제 자료

출처 : 이미지 출처 슈카티비

 

반응형
반응형

 

 

 

https://youtu.be/Rt_UqUm38BI

 

Official Teaser 

반응형
반응형

 

 

 

TreeSet 에서  비교 클래슬를 생성자에서 받을때는 Comparable 을 상속받은 클래스는 불가하고

Comparator 를 상속받은 클래스를 생성자에 Functor 식으로 넣어서 비교기준으로 삼는 것은 가능하다

class TestCopmp implements Comparator {

    public int a;

    @Override
    public int compare(Object o1, Object o2) {
        return ((Test)o1).a - ((Test)o2).a;
    }
}

 

Set set = new TreeSet( new TestCopmp() );

마치 C++ 에서 Fuctor 를 만든것 처럼 끝 어미도 tor 이다, 사용법도 유사하다 볼수 있다

Comparator 는 sort 시에도 정렬 기준으로 던져줄수 있는 Fuctor 다

 

 

 

위 처럼 생성자에 넣는 것이 아닌 클래스 자체에 비교 함수를 override 하는 방법이 있는데 그것이 Comparable 이다

class Test implements Comparable {
    public int a;

    @Override
    public int compareTo(Object o) {
        return a - ((Test)o).a;
    }
}
//원소 추가함과 동시에 정렬됨
Set set = new TreeSet();

for (int i=0; set.size() < 6;++i)
{
    int nm = (int)(Math.random()* 45) + 1;
    Test ss= new Test();
    ss.a = nm;

    set.add(ss);

}

 

 위 처럼 하면 가능 하지만 Test 클래스가 Comparator 를 상속을 받는것은 가능하나
 객체간의 비교로 사용용도로 사용되진 못한다, 사용하면 크래쉬 (Comparable 로 캐스팅 하지 못한다는 에러 발생)

Exception in thread "main" java.lang.ClassCastException: class Test cannot be cast to 
class java.lang.Comparable (Test is in unnamed module of loader 'app'; 
java.lang.Comparable is in module java.base of loader 'bootstrap')

	at java.base/java.util.TreeMap.compare(TreeMap.java:1563)
	at java.base/java.util.TreeMap.addEntryToEmptyMap(TreeMap.java:768)
	at java.base/java.util.TreeMap.put(TreeMap.java:777)
	at java.base/java.util.TreeMap.put(TreeMap.java:534)
	at java.base/java.util.TreeSet.add(TreeSet.java:255)
	at comp.main(comp.java:98)

 

 

 

 

 

 

[Comparable 의 사용 예시]

import java.util.*;

//하나의 자바 소스 파일에 작성된 클래스 중 오직 한 클래스만 public으로 선언할 수 있습니다.

//Comparable 상속받아 정렬 기준을 만들수 있다
class Player implements Comparable<Player>
{
    private String name;
    private int score;

    public int getScore(){ return score; }

    @Override
    public int compareTo(Player o) {
        return o.getScore() - this.getScore();
    }

    public Player(String name, int score)
    {
        this.name = name;
        this.score = score;
    }
}

public class comp {

    public static void main(String[] args)
    {
        List<Player> players = new ArrayList<>();
        players.add(new Player("Alice", 899));
        players.add(new Player("Bob", 982));
        players.add(new Player("Chloe", 1090));
        players.add(new Player("Dale", 982));
        players.add(new Player("Eric", 1018));

        //이때 Comparable 이 사용됨
       주석 제거하면 Comparable 가 작동하여 정렬된다
        //Collections.sort(players);


        //comparator 를 통해 클래스 밖에서 정렬 기준을 다르게 하여 정렬 할수 있다
        Comparator<Player> comparator = new Comparator<Player>() {
            @Override
            public int compare(Player a, Player b)
            {
                return a.getScore() - b.getScore();
            }
        };

        //Collection<Integer> sdf = new LinkedList<>();
        Collections.sort(players, comparator);


    }

}

 

 

 

 

 

Comparable 인터페이스

객체의 정렬 기준을 정의하는 첫번째 방법은 정렬 대상 클래스를 자바에서 기본적으로 제공하고 있는 Comparable 인터페이스를 구현하도록 변경하는 것입니다. 이를 적용하면 Player 클래스는 다음과 같이 수정됩니다.

public class Player implements Comparable<Player> {
    // Fields, Getters, Setters 생략

    @Override
    public int compareTo(Player o) {
        return o.getScore() - getScore();
    }
}

Comparable 인터페이스의 compareTo() 메서드를 통해 인자로 넘어온 같은 타입의 다른 객체와 대소 비교가 가능합니다. 메서드를 호출하는 객체가 인자로 넘어온 객체보다 작을 경우에는 음수를 리턴하고, 크기가 동일하다면 0, 클 경우에는 양수를 리턴해야합니다.

게이머 랭키 페이지의 경우 높은 점수 순으로 내림 차순 정렬을 원하기 때문에, 인자로 넘어온 게이머의 점수에서 메서드를 호출하는 게이머의 점수를 빼면 됩니다. 예를 들어 인자로 넘어온 게이머의 점수가 982이고 compareTo() 메서드를 호출하는 객체의 점수가 1018이라면, compareTo() 메서드는 음수(982-1018)를 리턴하게 되며, 이는 곧 메서드를 호출하는 게미머가 인자로 넘어온 게이머보다 작다는 것을 의미합니다. 다시 말해, 메서드를 호출를 호출하는 메서드가 점수가 더 크지만, 객체 자체 비교에서는 인자로 넘어온 게이머보다 작은 객체가 됩니다.

 

Collections.sort(players);
System.out.println(players); // [Player(name=Chloe, score=1090), Player(name=Eric, score=1018), Player(name=Bob, score=982), Player(name=Dale, score=982), Player(name=Alice, score=899)]

 

 

이제 Collections.sort() 메서드에는 Comparable 인터페이스를 구현한 Comparable 타입의 Player 객체의 리스트가 인자로 넘어가기 때문에 더 이상 컴파일 에러가 발생하지 않습니다. 정렬 후 게이머 리스트를 출력해보면 원하는 바와 같이 점수가 제일 높은 Chloe 가 리스트의 맨 앞으로 위치하고, 점수가 제일 낮은 Alice 가 리스트의 맨 뒤에 위치하게 됩니다.

 

 

 

Comparator 객체 사용

만약 정렬 대상 클래스의 코드를 직접 수정할 수 없는 경우에는 어떻게 객체의 정렬 기준을 정의할 수 있을까요? 또는 정렬 하고자 하는 객체에 이미 존재하고 있는 정렬 기준과 다른 정렬 기준으로 정렬을 하고 싶을 때는 어떻게 해야할까요?

이 때 필요한 것이 바로 Comparable 인터페이스와 이름이 유사한 Comparator 인터페이스입니다. Comparator 인터페이스의 구현체를 Arrays.sort()나 Collections.sort()와 같은 정렬 메서드의 추가 인자로 넘기면 정렬 기준을 누락된 클래스의 객체나 기존 정렬 기준을 무시하고 새로운 정렬 기준으로 객체를 정렬할 수 있습니다.

 

 

Comparator<Player> comparator = new Comparator<Player>() {
    @Override
    public int compare(Player a, Player b) {
        return b.getScore() - a.getScore();
    }
};

Collections.sort(players, comparator);
System.out.println(players); // [Player(name=Chloe, score=1090), Player(name=Eric, score=1018), Player(name=Bob, score=982), Player(name=Dale, score=982), Player(name=Alice, score=899)]

 

 

 

위 코드는 Comparator 객체를 Collections.sort() 메서드의 두번째 인자로 넘겨서 이전 섹션과 동일한 정렬 결과를 만들어 내고 있습니다. 이렇게 Comparator 객체를를 인자로 넘기면, 정렬 대상 객체가 Comparable 인터페이스를 구현 여부와 상관없이, 넘어온 Comparator 구현체의 compare() 메서드 기준으로 정렬을 수행합니다. compare() 메서드는 비교 대상 2 개의 객체를 인자를 차례로 인자로 받습니다. 첫번째 인자가 두번째 인자보다 작다면 음수, 같다면 0, 크다면 양수를 리턴하면 됩니다.

 

 

람다 함수로 대체

Comparator 객체는 메서드가 하나 뿐인 함수형 인터페이스를 구현하기 때문에 람다 함수로 대체가 가능합니다.

 

 

Collections.sort(players, (a, b) -> b.getScore() - a.getScore());
System.out.println(players); // [Player(name=Chloe, score=1090), Player(name=Eric, score=1018), Player(name=Bob, score=982), Player(name=Dale, score=982), Player(name=Alice, score=899)]

 

 

 

 

Stream 으로 정렬

Stream 클래스의 sorted() 메서드도 Comparator 객체를 인자로 받아 정렬을 해줍니다. 스트림을 사용하면 위에서 살펴본 배열과 리스트의 정렬과 달리 기존 객체의 순서를 변경하지 않고, 새롭게 정렬된 객체를 생성하고자 할 때 사용됩니다.

 

List<Player> sortedPlayers = players.stream()
        .sorted((a, b) -> b.getScore() - a.getScore())
        .collect(Collectors.toList());
System.out.println(sortedPlayers); // [Player(name=Chloe, score=1090), Player(name=Eric, score=1018), Player(name=Bob, score=982), Player(name=Dale, score=982), Player(name=Alice, score=899)]

 

 

 

ref : https://www.javastudypoint.com/2019/03/comparable-vs-comparator-in-java.html

ref : https://www.daleseo.com/java-comparable-comparator/

ref :https://server-engineer.tistory.com/808

반응형
반응형

JAVA에서 기본적인 자료 구조를 제공하기 위한 환경을 JAVA Collection Framework라고 한다.

다음은 JAVA Collection Framework의 상속 기본 구조이다.

 

 

 

 

 

  1.  Collection 인터페이스를 상속받아 List와 Set 인터페이스가 된다. List는 순서가 있는 Collection, 그리고 List는 Data 중복을 허락한다. 하지만 Set은 순서의 의미가 없으며 Data를 중복해서 포함할 수 없다.
  2. Collection
  • List 인터페이스의 특징
    • 순서가 있는 Collection.(이 순서는 삽입된 순서를 의미한다.)
    • Data를 중복해서 포함할 수 있다.
    • Stack의 특징
      • Data의 삽입과 추출이 후입선출(Last-In First-Out) 구조로 되어 있다.
      • push() method : Data 삽입할 때 사용
      • pop() method : Data 추출할 때 사용
      • peek() method : 추출할 Data를 삭제하지 않고 Data만을 가져 올 때 사용
      • search() method : Stack으로부터 Data를 검색할 때 사용
    • Vector의 특징
      • 자동으로 동기화를 보장해준다.
      • ArrayList에 동기화가 보장되도록 최적화한 클래스이다.
      • JAVA 5.0 이 후로는 AutoBoxing/AutoUnBoxing을 지원한다.
        • AutoBoxing이란? 기본 Data 타입을 Wrapper 클래스형의 객체로 자동으로 변환해주는 기능. AutoUnBoxing은 AutoBoxing의 반대 개념
        • JAVA 1.4까지
Vector v = new Vector();
v.addElement(new Integer(100));
  • JAVA 5.0이후
Vector v = new Vector();
v.addElement(100); // AutoBoxing 발생, 자동으로 Wrapper class인 Integer로 변경
  • addElement() method : Data를 삽입할 때 사용
  • elementAt() method : Data를 추출할 때 사용, Index에 해당하는 객체를 얻어냄
  • size() method : Vector 내에 존재하는 객체의 수를 얻어낼 대 사용
  • insertElementAt() method : Vector 내에 중간 삽입할 때 사용
  • setElementAt() method : Vector 내에 존재하는 Data를 수정할 때 사용
  • indexOf() method : Vector 내에 Data를 검색할 때 사용, Index를 반환
  • contains() method : Data의 존재 유무를 알기 위해 사용.
  • ArrayList의 특징
    • 동기화를 보장해주지 않는다.
    • 배열에 동적 메모리 증가 기능을 구현한 클래스이다.
    • 동기화 지원 방법 : List list = Collections.synchronizeList(new ArrayList(…));
    • add() method : Data 삽입할 때 사용
    • get(0 method : Data 추출할 때 사용
    • toArray() method : ArrayList로부터 배열 얻어낼 때 사용
    • contains() method : Data의 존재 유무를 알기 위해 사용
    • size() method : ArrayList의 요소 개수를 얻어낼 때 사용
  • Set 인터페이스의 특징
    • 집합적인 개념의 Collection
    • 순서의 의미가 없다.
    • Data를 중복해서 포함할 수 없다.
    • HashSet의 특징
      • add() method : Data 삽입할 때 사용
      • next() method : Data 추출할 때 사용
        • HashSet의 Data 추출은 Iterator을 이용하면 된다. Iterator는 Collection내의 모든 Data에 접근할 수 있는 특징이 있다. 그리고 Data의 마지막에 상관하지 않고 검색하기 위한 인터페이스이다. Set의 Iterator() method로 Iterator를 얻어 낼 수 있으며, Iterator의 hasNext() method를 이용해서 Data 끝을 만날 때까지 next() method를 호출해서 Data를 추출할 수 있다.
Iterator<String iter = set.iterator();
while(iter.hasNext()) {
String temp = iter.next();

System.out.print(temp + ", ");
}
  • remove() method : Data를 삭제할 때 사용
  • contains() method : Data의 포함여부를 알기 위해 사용
  • size() method : HashSet의 요소 개수를 얻어낼 때 사용
       
  1. Map
    List와 Set이 순서나 집합적인 개념의 인터페이스라면 Map은 검색의 개념이 가미된 인터페이스이다. Map 인터페이스는 데이터를 삽입할 때 Key와 Value의 형태로 삽입되며, Key를 이용해서 Value를 얻을 수 있다.
  • Hashtable, HashMap의 공통점
    • 내부적으로 모두 Hash 기법을 이용한다.
    • Map 인터페이스를 구현하고 있다.
    • Key와 Value를 이용해서 Data를 관리한다.
  • Hashtable, HashMap의 차이점
    • Hashtable은 동기화가 보장된다.
    • HashMap은 동기화가 보장되지 않는다.
    • HashMap의 동기화 지원 방법 : Map m = Collections.synchronizedMap(New HashMap(…));
  • Hashtable, HashMap과 HashSet과의 관계
    • Hashtable과 HashMap은 둘 다 Map 인터페이스를 구현하고 있다.
    • HashSet은 내부적으로 Hash기법을 사용하지만 Set인터페이스를 구현하고 있다.
  • HashMap
    • 객체 생성 : Map<String, Integer> map = new HashMap<String, Integer>();
    • put() method : Data 삽입할 때 사용
    • get() method : Data를 추출할 때 사용, argument값은 Key를 사용
  • Hashtable
    • 객체 생성 : Hashtable<String, Object> h = new Hashtable<String, Object>();
    • put() method : Data 삽입할 때 사용
    • get() method : Data를 추출할 때 사용, argument값은 Key를 사용

   

  1. Sorted
    Set과 Map 인터페이스를 상속받아 정렬 기능이 추가된 SortedSet과 SortedMap 인터페이스가 된다. 그리고 이들은 각각 TreeSet 클래스와 TreeMap 클래스로 구성된다. TreeSet과 TreeMap은 Set과 Map의 기능을 가지고 있으면서 정렬 기능이 가미되었다는 것이 특징이다.
  • Sorted를 지원하지 않는 클래스
    • HashSet, HashMap
  • Sorted를 지원하는 클래스
    • TreeSet, TreeMap
  • TreeMap
    • Key와 Value로 Data를 관리
    • Key를 기준으로 오름차순으로 정렬된다.
    • Map 인터페이스를 상속한 SortedMap 인터페이스를 구현한 클래스
  • TreeSet
    • Set 인터페이스를 상속한 SortedSet 인터페이스를 구현한 클래스
    • 데이터들이 자동으로 오름차순으로 정렬된다.
  • Comparator
    • TreeSet과 TreeMap은 사용자가 직접 정렬의 방식을 지정할 수 있다.
    • TreeSet과 TreeMap은 정렬을 위한 Comparator 인터페이스를 구현하면 된다.
    • TreeSet에 Data를 집어 넣으면 기본적으로 오름차순(Ascending) 정렬이 되지만 그것도 문자열이나 기본 데이터 타입과 같은 단순한 것에만 해당된다. 이에 사용자가 직접 비교법을 넣어주기 위해 사용하는 것이 Comparator 인터페이스이다.
    • Comparator의 구현 방법 : Comparator 내부에 compare() method를 구현하면 된다.
class Mycomparator<T> implements Comparator<T> {
public int compare(T o1, T o2) {
// 비교방법 구현
}
  • Comparator가 추가된 TreeSet의 생성
TreeSet<Score> tset = new TreeSet<Score>(new MyComparator<Score>());
  • Comparator가 추가된 TreeMap의 생성
TreeMap<Score, String> tset = new TreeMap<Score, String>(new MyComparator<Score>());
  • 일반적인 정렬기능의 사용
    • HashSet이나 HashMap을 정렬 기능이 지원되는 TreeSet이나 TreeMap으로 변환해서 사용
    • HashSet을 이용한 TreeSet 생성
Set<String> set = new HashSet<String>();
...
TreeSet<String> ts = new TreeSet<String>();
ts.addAll(set);
  • HashMap을 이용한 TreeMap 생성
Map<String, Integer> map = new HashMap<String, Integer>();
...
Map<String, Integer> sortedMap = new TreeMap<String, Integer>();
sortedMap.putAll(map);




ref : https://withwani.tistory.com/150

반응형
반응형

3DMP 에서 배워 이직/합격/수강하신 분들의 주요 회사들입니다

 

+ 학원 같은 대규모 기업체가 아니기 때문에 개인 강의 여건상 많은 분들을 가르치진 못하지만

   꼼수가 아닌 확실한 것을 하나하나 이해될 때까지 알려드리려 노력하고
   수강생분들의 앞길에 실질적으로 도움이 될 수 있는 방안을 깊이 있게 고민하고 해결책을 드리려 합니다

 

 

EA 코리아, 넥슨 코리아, NC, 넷마블, 넷게임즈, 
크래프톤, 엔픽셀, 펍지, 펄어비스, 블루홀
스마일게이트, NHN

기타 다수..

 

현업 프로그래머 또한 듣는 과외입니다

직군에는 현업프로그래머, 게임 프로그래머,엔진 프로그래머, TA,

UI 등으로 취직, 이직 및 자기 개발등을 위해 수강을 하셨습니다

 

*나열된 순서는 회사와 무관합니다

이직 및 취직비율이 높습니다

+ No 베이스에서 시작하신 분들 또한 포함되어 있습니다

 

 

[ 그 외 수강하셨던 분들 ]

  • 국내 현업 게임 및 비게임 업계 종사자 대기업, 중견, 벤처 회사원과 기업가, 사업가(CEO)/임원
  • 대학생(취준생), SKY 포함 상위 약 10% 이상 대학생, 유학생
  • 전공자/컴퓨터 관련 전공자가 아니지만 게임이나 프로그램 쪽으로 진로를 희망하시는 분들
    (비전공자 일지라도 많은 상당수의 분들이 원하는 성과를 이루고 가셨습니다)
  • 전문 프로그래머로 진로를 정하시거나 또는 희망하시는 분들
  • 프로그램을 혼자 하기엔 막연하여 그룹(단체) 배워보고자 하시는 분들
  • 초심자, 프로그램 배워보려 했지만 진입 장벽 때문에 포기하신 분들
  • 게임이 아닌 회사들

 

반응형
반응형

3DMP 에서 배워 합격하신 분들의 주요 회사들입니다

 

넥슨 : 게임 프로그래머

NC  : 프로그래머

넷마블 :  게임 프로그래머 (UE4)

엔픽셀 :  TA 프로그래머 (UE4)

넷게임즈 : 엔진 프로그래머 (UE4)

크래프톤 : 게임프로그래머 (UE4, Unity) 

펍지 : 게임프로그래머 (UE4) 

펄어비스 : 게임 프로그래머 (자체 엔진)

블루홀 : 게임프로그래머 (Unity)


최근실적 : 넷마블 게임프로그래머 부문 1위로 입사 (22년도)
신입프로그래머를 1:1 교육하여  연봉 1600만원 인상 이직 (22년도)

기타 다수..

*나열된 순서는 회사와 무관합니다

 

 

+ 포함된 회사 목록 :  (게임프로그래머/엔진프로그래머/TA 로 취직, 공채, 이직)

   + No 베이스에서 시작하신 분들 또한 포함되어 있습니다

   + 현업 프로그래머이셨던 분들이 3DMP 에서 배워 이직하신 분들 또한 포함되어 있습니다
      (No 베이스와 현업 프로그래머가 섞여 있음)

 

 

- 제외된 회사 목록 : 

    - 직장인이지만 이직 목적이 아닌 역량강화가 목적인 프로그래머의 회사들

    - 프로그래머가 아닌 그 외 직군(아트, 기획, TA, 등등) 분들의 회사

    - 게임이 아닌 회사들

    - CEO/임원 분들의 회사들

 

 

* 수강 후기는 댓글 조작 및 신뢰도가 떨어진다 생각하여 올리진 않습니다

 

 

+ 학원 같은 대규모 기업체가 아니기 때문에 개인 강의 여건상 많은 분들을 가르치진 못합니다

   하지만 꼼수가 아닌 확실한 것을 하나하나 이해될 때까지 알려드리려 노력하고
   수강생분들의 앞길에 실질적으로 도움이 될 수 있는 방안을 깊이 있게 고민하고 해결책을 드리려 합니다

   그 바람이 와닿았으면 좋겠습니다

반응형
반응형

 

 

All you have to do is locate the code at the top of the page

 

이문장을 보고 나는 locate의 과거분사 형태가 locate인가 했다

is가 나왔기때문에 locate라는 동사가 나올수 없기 때문에 대충 무슨의미인줄 알았으나 껄끄러운 해석있었다.

 

해석이 안되는 이유는 locate의 명확의 의미가 안떠올랐다.

처음에

너가 해야될 일은 (all을 전부혹은 모든 그런식으로 해석하기 보다 "바로"같은 강조의 느낌임)

page위에 있는 코드를 위치하는것이다?

해석할때 그냥 page위에 있는 코드를 locate하는 것이라고 해석하고 넘어갔다.

좀더 완벽한 한국어 locate의 의미는 (위치를)찾다인 find다.

 

locate

1.…의 정확한 위치를 찾아내다
2.(특정 위치에) 두다[설치하다]
3.(특정 장소에서) 사업을 시작하다

 

즉 나는 2번으로 해석을 잘못했다.

 

두번째

~하는 것이다 할때의미인 to가 왜 빠져있는가?

be동사 다음에 동사 원형이 온것이 비문처럼 보이지만 실제론 

 

to가 생략된 것이다. 

 

즉 All you have to do is (to) locate the code at the top of the page 가 원문이다. 

이는 특별한 이유는 없고 영어에서 습관적으로 to를 생략한다. 

생략한 개념이기 때문에 all you have to do is 뒤에 

간혹 to 부정사가 보이기도 하고, 동명사 형태가 나오기도 한다. 즉

All you have to do is to locate the code at the top of the page.

All you have to do is locating the code at the top of the page.

식의 영작도 가능하다. 

 

이런 비슷한 거로는

all ~~,the only thing , the first thing , the least (thing) , what 절이 주어가 오고 

be동사가 오는 문장에서 to 부정사에서 to가 생략되곤 한다. 

 

ex) All you have to do is press this button.  너는 그저 이 버튼을 누르기만 하면 돼.

ex) The only thing that you have to do is be sure to get a receipt. 너가 꼭 해야 할일은 오직 영수증을 받는것이다.

ex) The first thing you should do is tell them to stop bothering you. 니가 해야할 첫번재 일은 그들에게 그만 괴롭히라고 말하는거야. 

ex) I feel that the least we all deserve is respect and dignity given the sacrifices expected. 내 생각엔 우리가 마땅히 받아야 할 최소한의 것은 존중과 존언성이야. 앞으로 올 희생을 고려하면. 

ex) What you have to do is go home and wait. 니가 해야할 일은 집에 가서 기다리는거야. 

 

 

ref : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=shy1004jh&logNo=111148641

반응형
반응형

ScriptableObject

ScriptableObject는 클래스 인스턴스와는 별도로 대량의 데이터를 저장하는 데 사용할 수 있는 데이터 컨테이너입니다. ScriptableObject의 주요 사용 사례 중 하나는 값의 사본이 생성되는 것을 방지하여 프로젝트의 메모리 사용을 줄이는 것입니다. 이는 연결된 MonoBehaviour 스크립트에 변경되지 않는 데이터를 저장하는 프리팹이 있는 프로젝트의 경우 유용합니다.

이러한 프리팹을 인스턴스화할 때마다 해당 데이터의 자체 사본이 생성됩니다. 이러한 방법을 사용하여 중복 데이터를 저장하는 대신 ScriptableObject를 이용하여 데이터를 저장한 후 모든 프리팹의 레퍼런스를 통해 액세스할 수 있습니다. 즉, 메모리에 데이터 사본을 하나만 저장합니다.

MonoBehaviour와 마찬가지로 ScriptableObject는 기본 Unity 오브젝트에서 파생되나, MonoBehaviour와는 달리 게임 오브젝트에 ScriptableObject를 연결할 수 없으며 대신 프로젝트의 에셋으로 저장해야 합니다.

에디터 사용 시, ScriptableObject에 데이터를 저장하는 작업은 편집할 때나 런타임에 가능합니다. 이는 ScriptableObject가 에디터 네임스페이스와 에디터 스크립팅을 사용하기 때문입니다. 배포된 빌드에서는 ScriptableObject를 사용하여 데이터를 저장할 수 없으나, 개발 시 설정한 ScriptableObject 에셋의 저장된 데이터를 사용할 수 있습니다.

에디터 툴에서 에셋 형태로 ScriptableObject에 저장한 데이터는 디스크에 작성되므로 세션 간에도 그대로 유지됩니다.

ScriptableObject 사용하기

ScriptableObject의 주요 사용 사례는 다음과 같습니다.

  • 에디터 세션 동안 데이터 저장 및 보관
  • 데이터를 프로젝트의 에셋으로 저장하여 런타임 시 사용

ScriptableObject를 사용하려면 애플리케이션의 Assets 폴더에 스크립트를 생성하고 ScriptableObject 클래스에서 상속하도록 해야 합니다. CreateAssetMenu 속성을 사용하면 더욱 간편하게 클래스를 이용하여 커스텀 에셋을 생성할 수 있습니다. 다음 예를 참조하십시오.

 

바로 메뉴에 보이는게 아니고 SpawnManagerScriptableObject

클래슬르 먼저 만들고 ScriptableObject 를 만들고 menuName 을 따라가보면 생성할수 있는 메뉴가 나온다

 

[사용예시 더보기 클릭]

 

더보기

생성방법

[CreateAssetMenu(fileName = "New HeroData", menuName = "Sword HeroData", order = 2)]

public class test : ScriptableObject

{

 

}

유니티에서 스크립트를 생성하면 Monobehaviour를 자동으로 상속 받게 되는데 지우고

ScriptableObject를 상속받아온다.

 

[CreateAssetMenu] : 없어도 되지만 있으면 편함

fileName : 새로 제작하게되면 임시로 생성된다. 

menuName : 유니티 메뉴에 표기되는 이름

order : 메뉴에서 보일 순서

Assets -> Create 보면 방금 생성한 HeroData가 보이게 된다.

 

SerializeField의 원본 데이터들은 수정되면 안되기 때문에 

데이터 값을 받을 게터를 public으로 추가해준다.

public class test : ScriptableObject

{

    [SerializeField]

    string heroName;

    [SerializeField]

    string description;

    [SerializeField]

    int goldCost;

 

    public string sName => heroName;

    public string sDesc => description;

    public int    nCoin => goldCost;

}

 

사용법

데이터 값 입력

ScriptableObject를 받을 코드 작성

public class Scene : MonoBehaviour

{

    public Text m_txtUI;

    public test m_Data;

    void Start()

    {

        m_txtUI.text = string.Format(m_Data.sName + " // " + m_Data.sDesc);

    }

}

Data 매칭 인스펙터 창에서 끌어다 놓는다

 

 

 

 

 

using UnityEngine;

[CreateAssetMenu(fileName = "Data", menuName = "ScriptableObjects/SpawnManagerScriptableObject", order = 1)]
public class SpawnManagerScriptableObject : ScriptableObject
{
    public string prefabName;

    public int numberOfPrefabsToCreate;
    public Vector3[] spawnPoints;
}

 

 

 

 

Assets 폴더의 상기 스크립트를 이용하여 Assets > Create > ScriptableObjects > SpawnManagerScriptableObject 로 이동하여 ScriptableObject의 인스턴스를 생성할 수 있습니다. 새 ScriptableObject 인스턴스에 알아볼 수 있는 이름을 지정하고 값을 변경합니다. 이러한 값을 사용하려면 ScriptableObject를 참조하는 새로운 스크립트를 만들어야 합니다(이 경우 SpawnManagerScriptableObject). 다음 예를 참조하십시오.

 

using UnityEngine;

public class Spawner : MonoBehaviour
{
    // The GameObject to instantiate.
    public GameObject entityToSpawn;

    // An instance of the ScriptableObject defined above.
    public SpawnManagerScriptableObject spawnManagerValues;

    // This will be appended to the name of the created entities and increment when each is created.
    int instanceNumber = 1;

    void Start()
    {
        SpawnEntities();
    }

    void SpawnEntities()
    {
        int currentSpawnPointIndex = 0;

        for (int i = 0; i < spawnManagerValues.numberOfPrefabsToCreate; i++)
        {
            // Creates an instance of the prefab at the current spawn point.
            GameObject currentEntity = Instantiate(entityToSpawn, spawnManagerValues.spawnPoints[currentSpawnPointIndex], Quaternion.identity);

            // Sets the name of the instantiated entity to be the string defined in the ScriptableObject and then appends it with a unique number. 
            currentEntity.name = spawnManagerValues.prefabName + instanceNumber;

            // Moves to the next spawn point index. If it goes out of range, it wraps back to the start.
            currentSpawnPointIndex = (currentSpawnPointIndex + 1) % spawnManagerValues.spawnPoints.Length;

            instanceNumber++;
        }
    }
}

 

위의 스크립트를 의 게임 오브젝트에 연결하십시오. 그런 다음 인스펙터에서 Spawn Manager Values 필드를 새로 설정한 SpawnManagerScriptableObject로 설정해야 합니다.

Entity To Spawn 필드를 Assets 폴더의 아무 프리팹으로 설정하고, 에디터의 Play 를 클릭하십시오. Spawner에서 참조한 프리팹이 SpawnManagerScriptableObject 인스턴스에서 설정된 값을 사용하여 인스턴스화됩니다.

인스펙터에서 ScriptableObject 레퍼런스로 작업할 때 레퍼런스 필드를 더블 클릭해서 ScriptableObject의 인스펙터를 열 수 있습니다. 또한 인스펙터가 나타내는 데이터의 관리에 도움이 되도록 모양을 정의해 커스텀 에디터를 만들 수도 있습니다.

 

 

 

ref : https://funfunhanblog.tistory.com/81

ref : https://docs.unity3d.com/kr/2019.4/Manual/class-ScriptableObject.html

반응형
반응형

property

wrapper to specify read and write variable functionality using functions

 

template <typename Read, typename Write>
decltype(auto) property ( Read&& read_function, Write&& write_function );
template <typename Read>
decltype(auto) property ( Read&& read_function );
template <typename Write>
decltype(auto) property ( Write&& write_function );

 

These set of functions create a type which allows a setter and getter pair (or a single getter, or a single setter) to be used to create a variable that is either read-write, read-only, or write-only. When used during usertype construction, it will create a variable that uses the setter/getter member function specified.

 

#define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>

#include "assert.hpp"

#include <iostream>

class Player {
public:
	int get_hp() const {
		return hp;
	}

	void set_hp( int value ) {
		hp = value;
	}

	int get_max_hp() const {
		return hp;
	}

	void set_max_hp( int value ) {
		maxhp = value;
	}

private:
	int hp = 50;
	int maxhp = 50;
};

int main (int, char*[]) {

	std::cout << "=== properties from C++ functions ===" << std::endl;

	sol::state lua;
	lua.open_libraries(sol::lib::base);

	lua.set("theplayer", Player());

	// Yes, you can register after you set a value and it will
	// connect up the usertype automatically
	lua.new_usertype<Player>( "Player",
		"hp", sol::property(&Player::get_hp, &Player::set_hp),
		"maxHp", sol::property(&Player::get_max_hp, &Player::set_max_hp)
	);

	const auto& code = R"(
	-- variable syntax, calls functions
	theplayer.hp = 20
	print('hp:', theplayer.hp)
	print('max hp:', theplayer.maxHp)
	)";

	lua.script(code);

	return 0;
}

 

 

ref : https://sol2.readthedocs.io/en/latest/api/property.html?highlight=sol%3A%3Aproperty#property

반응형
반응형

 

 

 

아래 주소에서 

 

 

아래 주소에서  이 프로그램을 받으면 되는데 

 

이 붉은색이라면 바이오스 세팅 Advance TPM 을 켜줍니다 

 

하지만 이게 없다면 지원 불가능 (신형 CPU 의 경우 대부분 TPM 을 내장하고 있습니다)

 

https://github.com/rcmaehl/WhyNotWin11/releases

 

Releases · rcmaehl/WhyNotWin11

Detection Script to help identify why your PC is not Windows 11 Release Ready - rcmaehl/WhyNotWin11

github.com

 

 

 

 

반응형

'윈도우' 카테고리의 다른 글

NT Kernel & System CPU 점유율  (0) 2021.01.26
반응형

 

 

 

영화의 느낌은 아직 트레일러라 정확하다고 말할 순 없겠지만 오랜 시간에 걸처 폐인이 되어버린 네오가 이를 극복해가면서 다시 메트릭스의 세계로 가야만 하는 일이 생기게 되면서 영화의 서막이 시작되는것 같습니다

 

 

 

일할려면 휴식이 필요해...

 

 

 

엄청 오랜 시간 끝에 재회 장면

 

 

 

 

그리고 그 전 세계관에 비해 상당히 많이 바뀐 세상을 현실적으로 예고하는 것 같은 느낌이네요

 

 

 

다시 이런 가상 훈련 씬도 나오는 것 같은데 (장풍?!)

 

 

 

매트릭스의 세계관을 얘기하는 장면 같네요

 

 

 

메트릭스 특허인 벽을 타고 회전하면서 싸우는 씬

 

 

 

다시 메트릭트로 돌아가려고 하냐는 씬이 나오면서 예고는 끝나게 됩니다 (12월 개봉!)

 

 

 

메트릭스 리저렉션

 

반응형
반응형

아주 갱장한 소식입니다

이제 언리얼4 에서도 안드로이드 디버깅이 가능해졌다고 하네요!!

 

 

Android용 Visual Studio 디버깅

이제 Android 프로젝트에서도 Visual Studio 디버깅 워크플로를 사용할 수 있습니다. Google의 Visual Studio용 AGDE 플러그인을 설치하면, Android 프로젝트 생성 시 언리얼 엔진에서 해당 플러그인을 내부적으로 활성화합니다. 이를 통해 Visual Studio에서 직접 프로젝트를 디플로이 및 디버그할 수 있습니다.

 

 

 

 

https://docs.unrealengine.com/4.27/ko/WhatsNew/Builds/ReleaseNotes/4_27/

반응형
반응형

 

오른쪽 하단 (...) 버튼 -> 톱니바퀴 ->  친구 -> "업데이트한 친구보기" 를 꺼주면 됩니다

 

 

 

 

 

반응형
반응형

 

 

 

 

 

전반적인 강화 학습의 형태

강화 학습에는 Agent, Action , State ,Reward , Environment 가 존재한다

 

Agent 는 알고리즘 이라고 생각하면 되는데 

 

 

이와 같은것들이 있다

 

 

 

환경을 제작할 수 있는 엔진에는 유니티, 언리얼 등등이 있다

 

 

 

 

 

 

 

강화 학습에는 Agent, Action , State ,Reward 가 있으며 이것이 Environment에서 돈다

 

 

Agent 는 강화학습 딥러닝으로 많이들 한다

이때 딥러닝은 파이썬이나 TensorFlow 등등을 이용함

 

머신러닝과 가장 큰 차이점 딥러닝은 분류에 사용할 데이터를 스스로 학습할 수 있는 반면 

머신 러닝은 학습 데이터를 수동으로 제공해야한다는점이 딥러닝 머신러닝의 가장 큰 차이점입니다.

 

머신 러닝이란?
인공지능의 하위 집한 개념인 머신러닝은 정확한 결정을 내리기 위해 제공된 데이터를 통하여 스스로 학습할 수 있습니다. 처리될 정보에 대해 더 많이 배울 수 있도록 많은 양의 데이터를 제공해야 합니다.

즉, 빅데이터를 통한 학습 방법으로 머신러닝을 이용할 수 있습니다. 머신 러닝은 기본적으로 알고리즘을 이용해 데이터를 분석하고, 분석을 통해 학습하며, 학습한 내용을 기반으로 판단이나 예측을 합니다. 따라서 궁극적으로는 의사 결정 기준에 대한 구체적인 지침을 소프트웨어에 직접 코딩해 넣는 것이 아닌, 대량의 데이터와 알고리즘을 통해 컴퓨터 그 자체를 ‘학습’시켜 작업 수행 방법을 익히는 것을 목표로 한답니다.

 

 

환경은 내가 알아서 만듬(유니티, 언리얼 같은것으로)

 

 

Agent 와 환경은 둘이 다른 환경(프로그래밍 언어등)인데 이 둘 사이를 연결해주는것을 보고 유니티에서

 

ML-Agent 라하며 이것을 ToolKit 이라 볼 수 있다

 

#1

 

이 그림에서 보면 Learnig Enviroment 유 유니티 같은 환경에서 보상과 관측된 정보를 Python API 로 넘긴다

Python API  에서 넘어온 정보를 기반으로 강화학습 알고리즘을 만들어(Python Low-Level API) 알고리즘을 통하여 Action 을 다시 환경으로 넘겨주게 할 수 있다

그런데 강화학습 알고리즘을 직접 짜곳 싶지 않다면 유니티에서 제공하는 Python Trainer 를 갖고 학습을 시킨후

액션을 선택하여 환경에 넘겨줘 서로 통신할수 있게 할 수 있다

 

 

 

Trainers 를 통해서 할대는 학습이 완료된 .nn 이라는 파일을 유니티로 내장 후 이것을 그대로 사용 할 수 있다

 

 

 

ML-Agent 1.0 에선 다음과 같은것들이 있었음

 

 

 

 

Agents 스크립트는 

 

환경을 다 구성해 놓고 어떤 정보와 어떤 액션들어오는 지에 따라서 어떻게 행동 할지를 결정 할수 있는 스크립트

보상과 게임 종료 조건도 결정 할 수 있다

 

 

Behavior 스크립트(예전에는 Brain 이였다고함) ( 위 그림에서 Behavior Parameters 스크립트)

 

1.0 에서

예젠에는 Acamedy 가 있었는데(빌드된 화면의 환경크기, 몇프레임마다 화면 업데이트 할지등등)

지금은 Acamedy 가 사라지고 파이썬으로 옮겨갔음

 

 

 

 

 

Agent 하나당  하나의 Behavior 스크립트가 붙어야 하며 이 Behavior  는 Agents 에 대한 구체적인 설정을 하게된다

 

Vector Observation : x,y,z 위치, 속도 등 관측에 필요한 정보개수들 설정 

Stacked Vectors : 이전것 그 전전의 것 그 전전전의 것을 쌓아서 행동을 결정할때 쌓는정도를 말함

 

Space Type : 액션의 타입인데 연속적인 액션 또는 비연속적인 액션등으로 설정 할 수 있음

 

 

 

 

 

학습환경 내에 있는 Agent A1, Agent A2 가 사용하는 Behavior 가 같다면 Behavior 를 하나로 묶어줘도 된다

 

그다음 이렇게 묶인 것을 Communicator 를 통해서 Python API 와 통신하게 만든다 (#1)

 

 

 

여기서 오른쪽에 Behavior C 는 inference 와 견결 되어 있는데 inference  는 이미 학습된 강화 학습을 통한 결과를 통해 곧바로 행동 할수 있도록 하는것 

 

Behavior D 는 Heuristic 과 연결 되어 있는데 이것은 정해진 규칙에 의해서 움직이게 할 수 있다

사람이 제어하게 할수 있거나, 규칙에 따라 설정 해줄 수가 있다

 

 

 

 

유니티와 파이썬 사이에 직접적으로 연관 없는데이터를 교환하는 것이 가능하다

 

ex ) 자동차를 강화 학습 하는데 자기자신이 아닌 앞차나 뒷차의 정보가 앞차와 뒷차의 거리 등등이 궁금할때(log) Side Channel 을 통해 해볼 수 있다

 

 

 

 

위 처럼 하나를 

 

Agent 를 하나가 아닌 여러개로 구성하여 강화학습을 좀 더 빠르게 하는 방법들이 존재..

Distributed Agents : 

 

이것처럼 여러개로 만들어 좀 더 빠르고 정확한 결과를 볼 수도있음

 

 

Multi-agents : 양 한마리에 여러 사자들이 협력하여 양을 잡을 수 있게 할 수있음

 

 

1:1로 붙는 agents 학습을 말함 알파고 바둑 같은 경우를 말함 , 흑/백돌

둘이서 Self play 환경 (ai 끼리 대결하면서 하는 학습방식)

이때 학습 해놓은것에서 하나를 빼고 대신 사람이 플레이하게 해서 학습 할 수 도 있게 할수 있따

 

 

 

파란색이 주황색공을 피하게 한다

limitation Learning 은 사람이 하는 행동을 따라하는 것을 말함

우선 사람이 플레이를 한다음 그때의 행동이나 데이터를 기반으로해서 사람이 한것을 따라해보라고 학습을 시키는 것을 말한다

학습이 이상하면 플레이어의 문제 일 수도 있음

 

 

 

 

 

중간 사각형의 색상에 따라서 파란색 삭각형이 색상에 일치하는 문으로 가는  Agent 의 예시이다

 

 

이것 같은 경우에는 골기퍼들이 하나씩 있고 스트라이커들이 골을 넣는 환경으로 

각자의 Agents 의 역할이 다르다 행동들도 다르다, 즉 Multi Agent 이다 

 

 

 

 

강화 핛브에는 오른쪽 그림 처럼 Exploitation 이냐 Exploration 이냐에 따라서 학습 되는것이 다르다 

이것은 강화 학습에서 중요한 문제인데, 오른쪽 그림에서 로봇이 아래로만 가도 reward 를 1 을 얻기 때문에

계속 아래로만 갈 수 있다는것 위로가면 더 좋은 보상을 얻을 수 있지만 위로 가기전까진 모름으로

어떻게 에이전트가 다양한 경험을 하면서 학습할지가 성능등 중요한 문제 중 하나

 

* 학습과 탐험을 적절히 섞어 행동하도록 하는것이 중요

 

e : 엡실론 (랜덤하게 액션을 선택할 확률)

x 값이 1에 가까워지면 행동 하던대로만 행동하게 되고 0에 가까워지면 여러 탐색을 먼저 시도를 하게 된다

이것이 엡실론 그리디 방식임

 

그렇지만 목표에 도달하는데까지 상황이 복잡해질 수록 랜덤하게 탐험 하는것인 목표에 도달하는데 거의 불가능에 가까워진다, 보상획득이 어려워져 학습이 불가

 

 이런것은 랜덤 학습으로 키 까지 도달하는데 어려움(거의 불가)

 

 

그런데 호기심(curiosity) 탐험 방식이 있는데 

다음 상태를 예측하기 어려워서 내부 보상을 부여하여 새로운 경험을 선택하도록함

외부 보상은 일반적으로 게임에 보이는 보상

 

 

스태이트와 다음 스태이트가 있을 경우 이것을 동일한 Feature 라는 네트워크를 몇번 통과 시킨다

(상태에서 Feature 를 뽑아냄)

 

이렇게 뽑아진 Feature 를 Forward Model 이라는 곳에 넣어서 다음 스태이트를 예측해본다 (즉 예측한 다음 상태가 나옴)

 

 

 

현재 상태와 다음 상태를 뽑고

 

현재 상태에서 내부 보상을 통하여 다음 상태를예측한다음(Forward Model)

 

현제에서다음을 예측한것과 다음 상태간의 차이를 구한다 

 

즉 이 차이를 이용하여 내부 보상을 만든다

 

내부 보상이 큰경우 : 현재 상태의 액션을 갖고 다음 상태를 예측 했을때 다음 상태와의 차이가 큰경우를 말함

 

내부 보상이 작은경우 : 현재 상태의 액션을 갖고 다음 상태를 예측 했을때 다음 상태와의 차이가 작은경우를 말함

 

 

inverse Model : 

 현재 상태의 state 와 다음 상태의 state 를 둘다 넣고 액션을 해봤을 때 추정하는것으로 추정된 액션과 실제 액션으로 잘 추정하도록 만드는것을 말함 , 즉 이것이 잘 되야 현재에서 다음상태로의 유의미한 Feature 를 뽑아낼수 있는것

 

정리하자면 다음 상태를 잘 모르겠는 상태일때 내부 보상을 크게 줘서 원하는곳으로 가도록 유도하는것 

가본적이 많이 없으면 내부 보상이 작아진다

 

즉 다른곳으로 가게 하려면 내부 보상을 줄이면 된다(새로운 곳으로 가도록 유도함)

처음 가보는 곳은 내부 보상이 커지게 바꾼다

 

 

즉 랜덤하게 돌아다니면 경우의 수가 너무 많기 때문에 이런 식으로 다음 탐험에 대한 방향성을 좁힐 수 있다

 

 

 

 

 

imitation

 

사람의 플레이를 통해서 경험을 쌓는 방식

만약 사람이 플레이를이상하게 하면 agent 도 이상하게 행동을 하게 된다

 

 

 

이미테이션 러닝에서 레퍼런스가 되는 애니메이션이 있고 여기에서 목표하는 타겟을 때리는 것을 강화학습으로 애니시키면 그냥 강화학습으로 목표를 때리는것보다는 자연스럽게 처리 할 수 있다

 

 

 

 

유니티 ML-Agents 에서 제공 하는 학습 방법은?

 

Self-Play : Agent 끼리 서로 대결하면서 학습하는 방식

  • Symmetric  액션이랑 보상함수가 동일한형태로  Policy 를 공유할수 있음

    Agent 의 위치와 속도 , 공의 위치, 속도 등의 요소를 고려하여 학습 
    https://openai.com/blog/emergent-tool-use/  같은 사이트에서 제공하는 학습이 있다 
    빨강애가 못오게 파랑색이 문을 막는다
  •  

Curriculum Learning : 어려운 문제를 한단계씩 쉬운 난이도 부터 학습해서 조금식 어렵게 바꿔나가는 방식

 

파란색이 초록색 박스를 밀어서 녹색 플러스에 집어 넣어야 한다, 빨간색 플러스쪽으로 밀어 넣으면 안됨

제대로 밀어 넣었으면 좀 더 어려운 다음 스테이지에서도 밀어 넣을 수 있도록 난이도를 점점 높여간다

엡실론 (랜덤하게 액션을 선택할 확률) 값을 적당히 높여서 다음 난이도에서 학습하도록함

 

 

Environment parameter Randomization

 

 

사각형 얼굴이 왔다갔다하면서 위에 공을 떨어뜨리지 않도록 할때 Environment parameter 를 쓸 수 있다

공의 크기 또한 바꿀 수 있도로고 파라미터화를 할 수도 있다 (이런 랜덤한 값이 실행활에 있을수 있으니 그런 경우에 유용하다)

 

 

 

 

자동차가 여러개 가고있는데 그중 하나가 끝착선에서 다른 끝차선으로 차선 변경할대 Multi-Agent 를 사용 할수 있다

차선을 이동하는 차가 아닌 다른 차들도 협력을해야 하는 상황

 

빨간색 공이 있는 차가 빨간선 라인으로 차선 변경을 하기 위해서 다른 차들이 비키거나 속력을 내서 공간을 확보한 이후 차선 변경이 되도록함, 하지만 다른 차들의 속도저하는 최소한으로 처리하도록 함

 

 

 

알까기 : 당구와 비슷 

알을 까서 이동하는 동안 상대방은 치면 안됨

액션을 결정하는데 조건이 있음 즉 상대방이 친 돌이 이동하고 멈춰야 내 돌이이동 할 수 있음

이때 어떤 조건에서 알을 까도록 decision 을 설정할 수 있는데 이것을 만들어 주면 가능함

 

 

ML-Agent 설계 팁

  • Obervation : 최대한 실제적인 것을 사용 하는것이 중요하다, 처음엔 목표달성에 너무 쉬운 정보들을 줬다가 점점 빼는 형태로 가면 학습 속도를 빨리 할 수 있다
  • Action : 너무 많을 수록 학습이 잘 안된다, 액션의 조합을 다 합처서 많으면 너무 선택이 많음으로
  • Reward : 어떻게 움직이고 싶어하는 목표에 맞춰서 만든다

 

전체적으로 너무 많은 변수들과 액션 리워드를 세팅 하면 처음 학습 자체가안되거나 어디서 문제가 발생이 됐는지 알기 어려움으로 환경을 과 액션 reward 를 최대한 간단하게 만들고 여기서 학습이 되는 것을 확인한 다음에 차츰 어려운 환경을 만들어 나가는 것이 최종 만들어나가는데 빠른길이 될 수 있다

 

 

 

 

ref : https://wendys.tistory.com/136

ref : https://youtu.be/APMAHDRNv2I

반응형
반응형

아래 옵션들을 체크해주면 된다

반응형
반응형

 

캐릭터 BP 의 컴포넌트들 에서 CharacterMovement 가 아래 처럼 존재할 수있다

 

ABaseCharacter::ABaseCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer.SetDefaultSubobjectClass<UTDCharacterMovementComponent>(CharacterMovementComponentName))
{

 

 

ObjectInitializer 파라메터로 받는 생성자에서 상위클래스 초기화될 때 파라메터로 커스텀하게 만든 캐릭터 무브먼트 컴포넌트를 생성해주면됨.

다만 기본 Getter 인 GetCharacterMovement() 는 기본 클래스인 UCharacterMovementComponent를 리턴하므로 부를때마다 캐스팅을 하던지, 아니면 그냥 아래와 같은 래퍼를 하나 쓰는것도 간단해서 괜찮아보이긴 함.

 

FORCEINLINE UTDCharacterMovementComponent* GetTDCharacterMovement() { return Cast<UTDCharacterMovementComponent>(GetCharacterMovement()); }

 

 

 

ref : https://bbagwang.com/unreal-engine/character-movement-%EC%A0%81%EC%9A%A9-%EB%B0%A9%EB%B2%95/

반응형
반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
-- 두 개의 연속된 대쉬는 그 대쉬가 있는 한 줄을 주석으로 처리합니다.
 
--[[
     ‘--[[‘는 여러 줄 주석의 시작을 
     ‘--]]’는 여러 줄 주석의 끝을 뜻합니다.
--]]
 
----------------------------------------------------
-- 1. 변수와 흐름 제어.
----------------------------------------------------
 
 
num = 42  -- 모든 수는 double 형입니다.
-- 겁먹지 마십시오, 64 bit double 형에는 정확한 정수 값을 저장할 수 있는 52 bit가 있습니다.
-- 52 bit 보다 작은 크기로 표현할 수 있는 정수에 대해서는 정밀도 문제가 생기지 않습니다.
 
= 'walternate'  -- 파이썬(Python) 같은 바꿀 수 없는 문자열.
= "쌍 따옴표도 쓸 수 있습니다."
= [[ 이중 대괄호는
       여러 줄 문자열의
       시작과 끝을 나타냅니다.]]
= nil  -- t를 정의되지 않은 변수로 만듭니다. 루아에는 가비지 컬렉션 기능이 있습니다.
 
-- 블록은 do와 end로 표기됩니다.
while num < 50 do
  num = num + 1      -- ‘++’ 또는 ’+=’ 연산자는 없습니다.
end
 
-- If 절:
if num > 40 then
  print('over 40')
elseif s ~= 'walternate' then  -- ‘~=’는 같지 않음을 뜻합니다.
  -- 파이썬 같이 같음을 확인하는 연산자는 ‘==’입니다. ‘==’는 문자열에도 사용될 수 있습니다.
  io.write('not over 40\n')  -- 기본적으로 stdout으로 출력됩니다.
else
  -- 변수들은 기본적으로 전역(global) 변수로 만들어집니다.
  thisIsGlobal = 5  -- 변수 이름을 표기할 때는 낙타 등 표기법이 흔히 사용됩니다.
 
  -- 변수를 지역(local) 변수로 만드는 방법:
  local line = io.read()  -- 다음 stdin 줄을 읽습니다.
 
  -- ‘..’ 연산자를 사용하여 문자열 잇기:
  print('Winter is coming, ' .. line)    -- Winter is coming + ‘stdin으로 입력한 문자열’ 출력.
end
 
-- 정의되지 않은 변수들은 nil을 리턴합니다.
-- 이것은 에러가 아닙니다:
foo = anUnknownVariable  -- foo에 anUnknownVariable(한 정의되지 않은 변수)를 넣습니다. 이제 foo = nil.
 
aBoolValue = false
 
-- 불(boolean) 연산에서는 오직 nil과 false만 거짓입니다. 0 과 '' 는 참입니다!
if not aBoolValue then print('twas false'end
 
-- 'or'와 'and'는 short-circuit 됩니다.
-- 다음은 C/자바스크립트에서의 a?b:c 연산자와 비슷합니다.
ans = aBoolValue and 'yes' or 'no'  --> 'no'
 
karlSum = 0
for i = 1100 do  -- 그 범위의 양 끝을 포함합니다.
  karlSum = karlSum + i
end
 
-- "100, 1, -1"를 쓰면 범위를 감소하도록 정할 수 있습니다.
fredSum = 0
for j = 1001-1 do
 
  fredSum = fredSum + j 
 
end
 
-- 일반적으로, 범위는 시작, 끝[, 증가 또는 감소량] 입니다.
 
-- 또 다른 루프 작성법: 
repeat
  print('the way of the future')
  num = num - 1
until num == 0
 
 
----------------------------------------------------
-- 2. 함수.
----------------------------------------------------
 
function fib(n)                        -- 피보나치 수
  if n < 2 then return 1 end
  return fib(n - 2+ fib(n - 1)    -- 재귀 함수 
end
 
-- 함수 안에 정의된 함수(closure)와 이름 없는 함수도 쓸 수 있습니다.
function adder(x)  -- 리턴되는 함수는 adder가 호출될 때 생성됩니다. 그리고 x의 값을 기억합니다.
  return function (y) return x + y end 
end
a1 = adder(9)    -- adder가 처음 호출되었으므로 a1에 9가 들어갑니다.
a2 = adder(36)  -- adder가 처음 호출되었으므로 a2에 36이 들어갑니다.
print(a1(16))     -- a1에는 9가 들어있습니다. 
 
                          -- 거기서 다시 a1 인스턴스 adder를 호출하였으므로, 9+16=25가 출력됩니다.
print(a2(64))     -- a2에는 36이 들어있습니다. 
 
                           -- 거기서 다시 a2 인스턴스 adder를 호출하였으므로, 36+64=100이 출력됩니다.
 
-- 리턴, 함수 호출, 그리고 할당은 모두 리스트로 동작합니다. 그 리스트의 길이는 다를 수도 있습니다.
-- 매치되지 않는 수신자들은 nil로 취급됩니다. 매치되지 않는 전송자들은 버려집니다.
 
x, y, z = 1234
-- x = 1, y = 2, z = 3입니다. 4 는 버려집니다.
 
function bar(a, b, c)
  print(a, b, c)
  return 4815162342
end
 
x, y = bar('zaphod')  --> "zaphod  nil nil"이 출력됩니다.
-- x = 4, y = 8이 할당됩니다. 값 15, 16, 23, 42 는 버려집니다.
 
-- 함수는 first-class입니다, 함수는 지역 또는 전역일 수 있습니다.
-- 다음 두 줄은 같습니다:
function f(x) return x * x end
= function (x) return x * x end
 
-- 그리고 다음 두 줄도 같습니다:
local function g(x) return math.sin(x) end
local g; g = function (x) return math.sin(x) end
-- 'local g' 선언은 g를 자기 참조 가능하게 만듭니다.
 
-- 삼각 함수들은 라디안으로 동작합니다.
 
-- 매개변수에 한 문자열만 들어갈 때는 (함수를 호출할 때) 괄호를 붙이지 않아도 됩니다.:
print 'hello'  -- 잘 동작합니다.
 
 
----------------------------------------------------
-- 3. 테이블.
----------------------------------------------------
 
-- 테이블은 루아의 유일한 합성 자료 구조입니다.
-- 테이블은 연관 배열(associative arrays)입니다.
-- php 배열 또는 자바스크립트 객체와 비슷합니다.
-- 테이블은 리스트로도 사용될 수 있는 해시 참조 사전입니다.
 
-- 테이블을 사전이나 맵(map)으로 사용하기.
 
-- 사전은 기본적으로 문자열 키(key)를 가집니다.
= {key1 = 'value1', key2 = false}
 
-- 문자열 키는 자바스크립트 같은 점 표기를 쓸 수 있습니다.
print(t.key1)  -- 'value1' 출력.
t.newKey = {}  -- 새로운 key/value 쌍 추가.
t.key2 = nil   -- 테이블 t에서 key2 제거.
 
-- 키로 (nil이 아닌) 임의의 표기를 사용할 수도 있습니다.
= {['@!#'= 'qbert', [{}] = 1729, [6.28= 'tau'}
print(u[6.28])  -- "tau" 출력
 
-- 키 매칭은 기본적으로 숫자와 문자열 값으로 수행됩니다.
-- 그러나 테이블은 동질성(identity)에 의해 수행됩니다.
= u['@!#']  -- a = 'qbert'
= u[{}]        -- 1729가 들어갈 것으로 기대했지만, 실제로 들어가는 값은 nil입니다. b = nil. 
-- 이유는 검색이 실패하기 때문입니다.
-- 검색 실패 이유는 우리가 사용한 키가 원래 값을 저장할 때 사용된 것과 같은 객체가 아니기 때문입니다.
-- 그래서 더 이식성 높은 키는 문자열과 숫자입니다.
 
-- 매개변수가 테이블 하나인 함수 호출에서는 괄호가 필요 없습니다.
function h(x) print(x.key1) end
h{key1 = 'Sonmi~451'}  -- 'Sonmi~451' 출력.
 
for key, val in pairs(u) do  -- 테이블 반복.
  print(key, val)
end
 
-- _G 는 모든 전역들(globals)을 위한 특별한 테이블입니다.
print(_G['_G'== _G)  -- 'true' 출력.
 
-- 테이블을 리스트 또는 배열로 사용하기.
 
-- 리스트는 암묵적으로 정수형 키를 설정합니다.
= {'value1''value2'1.21'gigawatts'}
for i = 1, #v do  -- #v 는 리스트 v의 크기(size)입니다.
  print(v[i])  -- 인덱스는 1부터 시작합니다.
end
-- 리스트는 실제 타입이 아닙니다. v는 그저 하나의 테이블입니다.
-- 이 테이블은 연속적인 정수 키를 가지며, 리스트로 취급됩니다.
 
 
 
----------------------------------------------------
-- 3.1 메타테이블과 메타메소드
----------------------------------------------------
-- 테이블 하나는 메타테이블 하나를 가질 수 있습니다.
-- 그 메타테이블은 연산자 오버로딩을 제공합니다.
-- 나중에 우리는 어떻게 메타테이블이 자바스크립트의 프로토타입 동작을 지원하는지 볼 것입니다.
 
f1 = {a = 1, b = 2}  -- 분수 a/b를 표현.
f2 = {a = 2, b = 3}
 
-- 이것은 실패할 것입니다. (분수에 대한 덧셈은 루아에 정의되어 있지 않기 때문입니다.)
-- s = f1 + f2
 
metafraction = {}
function metafraction.__add(f1, f2)
  sum = {}
  sum.b = f1.b * f2.b
  sum.a = f1.a * f2.b + f2.a * f1.b
  return sum
end
 
setmetatable(f1, metafraction)
setmetatable(f2, metafraction)
 
= f1 + f2  -- f1의 메타테이블에 있는 __add(f1,f2)를 호출합니다.
 
-- f1, f2는 자바스크립트의 프로토타입과 달리 메타테이블에 키가 없습니다.
-- 그래서 당신은 반드시 그 키들을 getmetatable(f1)과 같이 다시 받아와야 합니다.
-- 그 메타테이블은 루아가 그것에 대해 아는 키를 가진 보통 테이블입니다. __add 같이요.
 
-- 그러나 다음 줄은 실패합니다. 왜냐하면, s에는 메타테이블이 없기 때문입니다.
-- t = s + s
-- 아래 주어진 클래스 같은 패턴들이 이 문제를 해결합니다.
 
-- 메타테이블에서 __index는 (myFavs.animal에 있는 점 처럼) 점 참조를 오버로드합니다.
defaultFavs = {animal = 'gru', food = 'donuts'}
myFavs = {food = 'pizza'}
setmetatable(myFavs, {__index = defaultFavs})
eatenBy = myFavs.animal  -- 동작합니다! 메타테이블, 고마워요.
 
-- 직접적 테이블 검색이 실패하면, (검색은) 그 메타테이블의 __index 값을 사용하여 다시 시도됩니다.
-- 그리고 이것이 반복됩니다.
 
-- 한 __index 값은 또한 더 사용자가 원하는 대로 맞춰진(customized) 검색을 위한 함수(테이블, 키)일 수 있습니다.
 
-- (add 같은) __index의 값들은 메타메소드라 불립니다.
-- 메타메소드의 전체 목록입니다. 여기서 a는 메타메소드를 가진 한 테이블입니다.
 
-- __add(a, b)                  for a + b
-- __sub(a, b)                  for a - b
-- __mul(a, b)                  for a * b
-- __div(a, b)                  for a / b
-- __mod(a, b)                  for a % b
-- __pow(a, b)                  for a ^ b
-- __unm(a)                     for -a
-- __concat(a, b)               for a .. b
-- __len(a)                     for #a
-- __eq(a, b)                   for a == b
-- __lt(a, b)                   for a < b
-- __le(a, b)                   for a <= b
-- __index(a, b) <함수 또는 테이블>  for a.b
-- __newindex(a, b, c)          for a.b = c
-- __call(a, ...)               for a(...)
 
 
 
----------------------------------------------------
-- 3.2 클래스 같은 테이블 그리고 상속.
----------------------------------------------------
-- 클래스는 (루아에) 내장되어 있지 않습니다. 클래스는 테이블과 메타테이블을 사용하여 만들어집니다.
 
-- 그 예제와 설명은 아래와 같습니다.
 
Dog = {}                                                     -- 1.
 
function Dog:new()                                  -- 2.
  newObj = {sound = 'woof'}                       -- 3.
  self.__index = self                                    -- 4.
  return setmetatable(newObj, self)         -- 5.
end
 
function Dog:makeSound()                    -- 6.
  print('I say ' .. self.sound)
end
 
mrDog = Dog:new()                                  -- 7.
mrDog:makeSound()  -- 'I say woof'         -- 8.
 
-- 1. Dog는 클래스처럼 동작합니다. 사실 Dog는 테이블입니다.
-- 2. function 테이블이름:함수(...)는 function 테이블이름.함수(self,...)와 같습니다.
--    ‘:’은 단지 함수의 첫 인자에 self를 추가합니다.
--    어떻게 self가 값을 얻는지는 아래 7과 8을 읽으십시오.
-- 3. newObj(새 객체)는 클래스 Dog의 한 인스턴스가 될 것입니다.
-- 4. self = 인스턴스로 될 클래스.
--    흔히 self = Dog입니다, 그러나 상속으로 그것이 바뀔 수 있습니다.
--    우리가 newObj의 메타테이블과 self의 __index를 self로 설정하면,
--    newObj는 self의 함수들을 얻습니다.
-- 5. 기억하세요: setmetatable은 그것의 첫 인자를 리턴합니다.
-- 6. ‘:’는 2처럼 동작합니다. 그러나 이번에는 self가 클래스가 아닌 인스턴스가 되리라고 예상할 수 있습니다.
-- 7. Dog:new()는 Dog.new(Dog)와 같습니다. 그래서 new()에서 self=Dog입니다.
-- 8. mrDog:makeSound()는 mrDog.makeSound(mrDog)와 같습니다. 여기서 self=mrDog입니다.
 
 
----------------------------------------------------
 
-- 상속 예제:
 
LoudDog = Dog:new()                                        -- 1.
 
function LoudDog:makeSound()
  s = self.sound .. ' '                                             -- 2.
  print(s .. s .. s)
end
 
seymour = LoudDog:new()                                -- 3.
seymour:makeSound()  -- 'woof woof woof'      -- 4.
 
-- 1. LoudDog는 Dog의 메소드들과 변수들을 가져옵니다.
-- 2. self는 new()에서 온 ‘sound’ 키를 가집니다. 3을 보십시오.
-- 3. LoudDog:new()는 LoudDog.new(LoudDog)와 같습니다.
--    그리고 LoudDog.new(LoudDog)는 Dog.new(LoudDog)로 변환됩니다. 
 
--    LoudDog에 ‘new’ 키가 없기 때문입니다.
--    그러나 LoudDog는 그 메타테이블에 __index=Dog를 가집니다.
--    결과: seymour의 메타테이블은 LoudDog입니다, 그리고 LoudDog.__index = LoudDog. 
 
--    그래서 seymour.key는 seymour.key, LoudDog.key, Dog.key 중 
 
--    주어진 키를 가진 첫번 째 테이블일 것입니다. 
-- 4. 'makeSound' 키는 LoudDog에서 찾을 수 있습니다.
--     seymour:makeSound()는 LoudDog.makeSound(seymour)와 같습니다.
 
 
 
-- 만약 필요하면, 하위 클래스의 new()는 기본 클래스의 것처럼 만들 수 있습니다.
function LoudDog:new()
  newObj = {}
  -- newObj 설정
  self.__index = self
  return setmetatable(newObj, self)
end
 
 
 
----------------------------------------------------
-- 4. 모듈.
----------------------------------------------------
 
--[[ 저는 이 스크립트의 나머지 부분이 실행 가능한 상태로 남도록 
 
--   이 절(section)을 주석으로 처리하고 있습니다. 
 
 
-- mod.lua 파일이 다음과 같다고 가정합시다.
 
local M = {}
 
local function sayMyName()
  print('Hrunkner')
end
 
function M.sayHello()
  print('Why hello there')
  sayMyName()
end
 
return M
 
 
-- 다른 파일도 mod.lua 파일에 있는 기능을 사용할 수 있습니다.
local mod = require('mod')  -- mod.lua 파일 실행.
 
-- require는 모듈을 포함(include)하게 하는 표준 방법입니다.
-- require는 이렇게 동작합니다. (만약 캐쉬되지 않으면요. '캐쉬되다'의 뜻은 아래에서 다시 설명됩니다.)
local mod = (function ()
  <mod.lua 파일의 내용>
end)()
-- mod.lua는 한 함수에 들어있는 내용처럼 한 지역 변수 mod에 대입됩니다. 
 
-- 그래서 mod.lua 안에 있는 지역 변수와 지역 함수들은 그 함수 밖에서는 보이지 않게됩니다.
 
-- mod는 mod.lua의 M과 같기 때문에, 다음은 동작합니다.
mod.sayHello()  -- Hrunkner에게 안녕이라고 말합니다.
 
-- 지역 함수인 sayMyName은 오직 mod.lua 안에서만 존재하므로, 다음은 틀렸습니다.
mod.sayMyName()  -- 에러
 
-- require의 리턴 값들은 캐쉬되어 require가 여러 번 호출되더라도 한 파일은 한번만 실행됩니다.
-- 예를 들어, mod2.lua가 "print('Hi!')”를 포함한다고 가정합시다.
local a = require('mod2')  -- Hi! 출력
local b = require('mod2')  -- 출력 안함; a=b.
 
-- dofile은 require와 비슷하지만 캐싱을 하지 않습니다.
dofile('mod2.lua')  --> Hi!
dofile('mod2.lua')  --> Hi! (다시 실행합니다.)
 
-- loadfile은 루아 파일을 로드하지만 아직 실행하지는 않습니다.
= loadfile('mod2.lua')  -- mod2.lua를 실행하기 위해서는 f()를 호출해야 합니다.
 
-- loadstring은 문자열을 위한 loadfile입니다.
= loadstring('print(343)')  -- 한 함수를 리턴합니다.
g()  -- 343을 출력합니다; 이 함수가 호출되기 전까지는 아무것도 출력되지 않습니다.
 
--]]
 
----------------------------------------------------
-- 5. 참고 자료
----------------------------------------------------
 
 
--[[
 
 
저는 루아를 배우는 것이 정말 좋았습니다. 그래서 저는 Löve 2D 게임 엔진으로 게임들도 만들 수 있었습니다. 그것이 제가 루아를 공부한 이유입니다. 
 
 
저는 BlackBulletIV's Lua for programmers를 보며 루아 공부를 시작하였습니다. 그다음 Programming in Lua 책을 읽었습니다. 그것이 제가 루아를 공부한 방법입니다. 
 
 
lua-users.org에 있는 Lua short reference를 확인해보는 것도 도움이 될 수 있습니다.
 
 
여기서 다루지 않은 주요 주제들은 표준 라이브러리들입니다:
 * string library
 * table library
 * math library
 * io library
 * os library
 
 
어쨌든, 이 문서 파일 전체는 하나의 유효한 루아 파일입니다. 이 문서를 learn.lua로 저장하고 “lua learn.lua”로 실행해 보십시오! 
 
 
이 글은 tylerneylon.com을 위해 처음 쓰였습니다. 이 글은 또한 github gist로 보실 수도 있습니다. 이 글과 형식은 같지만 다른 언어로 쓰인 글들은 여기에서 보실 수 있습니다. 
 
 
http://learnxinyminutes.com/ 
 
루아와 함께 즐거운 시간 되십시오!
 
--]]
cs

 

 

원문: http://tylerneylon.com/a/learn-lua/

 

Learn Lua in 15 Minutes

 

tylerneylon.com

 

 

ref : https://roboticist.tistory.com/576

반응형
반응형
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
using namespace std;
 
template<typename T>
T f(T a) 
    return a + 1
}
 
 
class A {                            //f 함수 테스트시 A 를 제외하고 생각하면 된다
public:
};
 
template <typename ... Types>
void s1(char cc, Types ... args)
{
 
}
 
template <typename ... Types>
void s1(int cc, Types ... args)
{
 
}
 
template <typename ... Types>
void s1(A cc, Types ... args)
{
 
}
 
template <typename ... Types>
void foo(Types ... args)        //받는건 가변인자로 다 받는데
{
 
    s1(args...);                    //인자 첫번째 타입에 따라 s1 함수가 호출 된다
    //s1(f(args)...);                    //개별 인자들에 +1 을 다 한다음 기반 parameter pack 을 넘긴다
}
 
int main(int argc, char* argv[])
{
    foo('s', A(), 3);
    foo(A(), 's'3);
    foo(12.0f, 3);
    return 0;
}
 
 
cs
반응형

'프로그래밍(Programming) > c++, 11, 14 , 17, 20' 카테고리의 다른 글

[Modern C++] std::move , 간단 예시  (0) 2022.03.03
std::forward  (0) 2022.03.03
std::map::emplace_hint  (0) 2021.03.21
C++ 캐스팅 Static, Dynamic cast  (0) 2020.04.27
std::remove_reference  (0) 2019.12.31
반응형

 

CTRL + R 누른 후

gpedit.msc

 

 

 

 

사용 누르고 확인하면 됩니다

 

반응형

'유틸리티' 카테고리의 다른 글

화면 여러개 쓰기 (가상데스크톱)  (0) 2021.01.17
반응형

https://www.unrealengine.com/ko/download?install=true 

 

언리얼 엔진 | 가장 강력한 리얼타임 3D 창작 플랫폼

언리얼 엔진은 게임, 시뮬레이션, 시각화의 디자인 및 개발에 사용되는 통합 크리에이터용 툴세트입니다.

www.unrealengine.com

 

 

 

You can now get the UE5 launcher

 

 

But it's still early access.

 

 

 

https://youtu.be/kXYLq1apcok

 

 

 

Run UE5 and ShaderCompile..

 

 

UE5 Editor

ㅇㅇ

언리얼 엔진 로열티, 게임 프로젝트당 총 수익 백만 달러까지 면제

언제나 그랬듯이, 지금 바로 언리얼 엔진 4를 다운로드하여 무료로 게임을 개발하실 수 있습니다. 새로운 점이라면, 이제 게임 프로젝트당 총 수익이 백만 달러가 될때까지는 로열티가 면제됩니다. 2020년 1월 1일부터 소급 적용되는 새로운 언리얼 엔진 라이선스 조건은 게임 개발자들에게 다른 엔진 라이선스 모델에 비해 전례 없는 혜택을 제공합니다. 더 자세한 정보는 자주 묻는 질문을 확인해 주세요.

 

 

언리얼 엔진 4 & 5 출시 일정

언리얼 엔진 4.25는 이미 Sony 및 Microsoft의 차세대 콘솔 플랫폼을 지원합니다. 에픽은 언리얼 엔진 4를 활용하여 차세대 게임을 개발하려는 콘솔 제조사 및 다수의 게임 개발사와 퍼블리셔들과 긴밀하게 협업하고 있습니다.

언리얼 엔진 5는 2021년 초 프리뷰 버전 출시가 예정되어 있으며, 차세대 콘솔, 최신 콘솔, PC, Mac, iOS 및 Android를 지원합니다.

저희는 상위호환을 염두에 두고 엔진을 설계하고 있으므로, 지금 UE4로 차세대 게임개발을 시작하는 개발사라면, UE5가 준비되었을 때 큰 어려움없이 엔진을 변경하실 수 있습니다.

에픽게임즈는 UE4로 개발한 포트나이트를 차세대 콘솔로도 출시할 예정이며, 업계 최고의 기능들을 직접 검증해 보이기 위한 노력의 일환으로, 저희의 자체 제작 게임인 포트나이트를 2021년 중순에 UE5로 엔진 변경할 예정입니다.

 

 

 

나나이트

는 가상화된 마이크로폴리곤 지오메트리로서, 아티스트들로 하여금 육안으로 식별할 수 있는 최대치의 섬세한 디테일을 구현할 수 있도록 해줍니다. 나나이트 가상화된 지오메트리라는 것은, 수억 개 또는 수십억 개의 폴리곤으로 구성된 영화 수준의 아트 소스를 언리얼 엔진으로 직접 임포트하고 작업할 수 있게 된다는 것을 의미합니다. Zbrush 스컬프팅부터 사진측량 스캔과 CAD 데이터 등 어떠한 데이터라도 그렇게 가능합니다.  나나이트 지오메트리는 실시간으로 스트리밍되고 확장되기 때문에, 이제부터 폴리곤 수, 폴리곤 메모리 또는 드로 콜 버짓으로부터 자유로워지고, 노멀맵에 디테일을 굽거나 LOD를 수동으로 제작할 필요가 없습니다. 퀄리티가 저하되지 않음은 물론입니다.

 

 

 

 

 

 

 

루멘

은 완전한 다이내믹 글로벌 일루미네이션 솔루션으로서 장면과 라이팅의 변화에 즉각적으로 반응하며 특별한 레이 트레이싱 하드웨어가 필요하지 않습니다. 이 시스템은 킬로미터에서 밀리미터까지의 거대하고 세밀한 환경 속에서 무한한 숫자의 빛 반사와 간접 스페큘러 리플렉션으로 디퓨즈 인터리플렉션을 만들어 냅니다. 아티스트들과 디자이너들은 루멘을 활용하여 보다 역동적인 장면을 제작할 수 있습니다. 예를 들어, 하루의 특정 시간에 맞춰 태양의 각도를 바꾸거나, 손전등을 켜거나, 천장에 구멍을 내면 그에 따라 간접광이 적용됩니다. 루멘을 통해 앞으로는 라이트맵의 베이킹을 완료하고, 라이트맵 UV를 제작할 때까지 기다릴 필요가 없습니다. 언리얼 에디터에서 최종 버전의 게임에서 돌아가는 모습과 똑같이 실시간으로 라이트를 움직이며 개발을 하게 되므로, 아티스트로서는 상당한 시간절약을 할 수 있게 됩니다

 

 

수많은 개발팀과 기술들이 모여 이러한 비약적인 퀄리티의 도약을 가능하게 했습니다. 개발팀은 나나이트 지오메트리 기술을 활용하여 매우 방대한 규모의 환경을 제작하기 위해 퀵셀 메가스캔 라이브러리를 집중적으로 활용했으며, 이는 최대 수억 개의 폴리곤으로 구성된 영화 수준의 오브젝트를 제공합니다. 이러한 방대한 규모의 환경을 구현하기 위해, Playstation 5는 이전 세대에 비해 크게 늘어난 스토리지 대역폭을 제공합니다.

이 데모에서는 카오스 피직스 및 디스트럭션, 나이아가라 VFX, 컨볼루션 리버브와 앰비소닉 렌더링 등 기존 엔진 시스템도 선보입니다.

 

 

ref : https://www.unrealengine.com/ko/blog/a-first-look-at-unreal-engine-5

반응형
반응형

 

나나이트 : 공수가 적어져 게임 창작에만 집중할 수 있는 렌더링을 말합니다

 

CTO 인 KIM LIBRERI 는 나나이트를 자유라고 표현합니다

 

 

그도 그럴 것이  초고해상도를 모델을 쉽게말해 그냥 UE5 에 올리면 됩니다 아래 처럼요

이 전의 작업 공수에 비하면 굉장히 비약적인 발전이라 볼 수 있을것입니다

 

 

 

 

제약 사항과 물론 시간차는 있겠지만 더이상 저해상도 노우폴이나 노멀을 따로 만들지 않아도 되는 시기가 다가왔습니다

 

EPIC 에서 이런 저런 시도를 많이 했었지만 나나이트 뿐만 아니라 관련된것들이 이 전과는 상당히 의미 있는 변화라고 볼 수가 있습니다

시간이 갈 수록 그 변화의 폭은 클것으로 예상 되됩니다

 

 

 

 

퀵셀 메가스캔 : epic 에서 만든 실사 모델 스캔ㅊ라이브러리

 

사실 이것은 놀랍다기 보단 epic 에서 훨씬 오래전부터 계속 작업을 해왔던 것입니다

 

 

실제 스캔 장비들을 다각도에서 스캔하여 실제 모델을 만듭니다

이런 스캐닝된 모델 형태들과 같은것을 epic 에서 이미 제공을 하고 있었지요

 

 

이제 점점 이것이 빛을 발하는 날이 다가오고 있는것 같네요

실시간으로 UE 에서 초하이폴을 끌어다 배치 하는 하는 모습인데

 

이제 커스터마이징(LOD 기타 최적화 등등, 조립되어 있는 모델) 할 필요도 없이 UE 에서 알아서 처리해줍니다

 

즉 그냥 붙여 넣기만 하면 되는 것이죠 

 

지형 오브젝트 회전 배치

 

 

이런 식으로배치된 지형이 이미 잘 알려진 바로 이것입니다

 

 

각 개별 에셋인데 어떤각 개별 에셋에는 수천만개의 폴리곤(트라이앵글)로 이루어져 있기도 합니다

 

그래서 전체 씬의 개수는 셀수가 없게 된다 또는 세는것이 의미 없게 됩니다

 

하지만 이것이 이제 거의 바로 앞으로 다가왔다는 것이죠

 

 

이제 임포트하기만 하면 디테일은 UE 가 알아서 해주게 됩니다

 

 

 

 

 

 

작업 후..

 

 

 

 

ref : https://www.youtube.com/watch?v=OkfLh-laEww

반응형
반응형

언리얼 도큐먼트에 보면 게임모드가 리플리케이트 되지 않는 다는 내용을 볼수 있긴 하지만

실행을 하다보면 게임모드가 클라에 있는 경우를 볼 수 가있는데 왜 그런것인지 한번 파악을 해보자

 

 

용어 정리

새 에디터 창(PIE) : 새로운 창에서 실행 화면을 띄움 (Client, Server 를 구분하면서 보기에 유용하다)

스탠드 얼론(Stand alone) : 독립형 게임을 말한다

리슨서버 : 서버와 클라 동시에 실행되는 서버를 말한다

데디케이트 서버 : 렌더링 관련기능 등이 언리얼에서 빠진 오직 서버 기능만이 있는 서버를 말한다

 

 

 

멀티 환경 설정

보다 정확한 멀티 플레이 세팅을 하려면 아래 단일 프로세스 하 실행 옵션을 해제해야한다

옵션이 체크되면 하나의 프로세스에서 실행 되다보니 값이 중복되는 등 제대로된 상태를 보기 어렵게 된다

 

 

 

테스크

 

월드에 큐브를 하나 배치하고 이 큐브에 대한 메터리얼 세팅하는 테스트를 하기위해 다음과 같이 세팅한다

 

큐브를 레벨에 올리고 다음과 같이 블루프린트를 만들어준다

 

 

큐브의 리플리케이션 설정은 다음과 같다

Net Load On Client : 클라이언트에 맵이 로드되면서 동시에 이 항목이 체크된 해당 액터도 맵과 함께 클라이언트에게 보여지게 된다

 

 

 

 

게임모드의 실행여부를 확인하기 위해 게임모드 클래스를 상속받는다

 

void ANSGameMode::BeginPlay()
{
Super::BeginPlay();

GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Red, FString::Printf(TEXT("AGameMode::BeginPlay")));

 

 

 

 

Play Offiline 로 실행할경우 게임모드의 존재 여부를 살펴보면 

 

넷 모드를 Play Offline 으로 세팅하고 실행해보면

 

 

Play Offiline 으로 할 경우

 

Role 이 Autority 이고 게임모드의 BeginPlay 또한 호출 되는 것을 볼 수가 있다

이때에는 게임 모드가 클라이언트에서도 실행이 되며 존재한다(실행 자체가 클라임으로)

 

 

 

아래와 같이 클라이언트에서 실행 되었지만 게임모드는 클라에서 만들어졌기 때문에 Role 이 Authority 이며

게임모드 BeginPlay 또한 실행 된것을 볼 수 있으며 메터리얼 또한

노란색 무늬가 있는 메터리얼로 씌워진 것을 볼 수 있다

(멀티 플레이어 옵션에서 -> 플레이어 수 를 늘려도 마찬가지)

 

 

 

Play As Listen Server 로 플레이 하는 경우

 

 

 

 

서버에서는 GameMode 의 Role 가 Authority 이며 GameMode::BeginPlay 또한 호출 된것을 볼수 있으며 게임 모드가 존재 한다는 것을 알수 있다

 

 

 

하지만 클라이언트에서는 GameMode 의 Role 가 None 이며GameMode::BeginPlay 또한 호출 되지 않았다는 것을 알 수 있다(존재하지 않음으로) 

 

 

 

 

 

 

Play As Client 로 테스트를 하기 위해선 아래 과정들이 필요하다

 

 

 

먼저 서버를 위한 빌드를 하나 한다 

 

 

프로젝트 세팅에서 다음 처럼 세팅한다음 빌드를 한 후

 

 

아래 처럼 서버바로 가기를 세팅 한다

 

 

 ?Listen -Rex=500 -ReY=350 -WINDOWED

 

 

서버를 실행 .exe

서버(리슨서버)를 띄웠으니 당연히 Authority 에 큐브 또한 노란색 띄 메터리얼이 입혀졌다

게임모드의 BeginPlay 도 호출된것을 볼 수 있다

 

 

서버를 띄운 다음

 

또한 콘솔 명령으로 Open 1278.0.0.1 로 클라이언트에서 서버쪽으로 붙을 수가 있다

 

 

멀티 플레이 환경 세팅이 되었다는 가정 하에 게임 모드가 존재하는 상황이 있는데

 

서버 역할을 하는 경우와 

 

 

 ?Listen -Rex=500 -ReY=350 -WINDOWED

 

 

 

에디터에서 Play As Client 로 실행하면 

 

에디터에서 실행한 화면이 Server 가 아닌 Client 라는 것을 타이틀창에서 알수 있으며

게임모드의 Role 또한 None 이며 Beginplay 또한 호출되지 않은 즉 게임모드가 존재 하지 않는 다는 거을 알 수가 있다

 

 

 

추가로 붙은 클라이언트에서도 마찬가지인 상황을 알 수가 있다

 

 

 

 

 

게임 모드의 존재 유무 정리

 

Play as Offline 으로 실행 될때 게임 모드가 존재하며 Role 이 Authority 인것을 알수 있고

서버로 실행 되었을때에도 마찬가지로 Authority 이면서 BeginPlay 가 호출된것을 볼 수가 있다

 

 

멀티 환경에서 게임 모드는 서버에서 클라로  Replicated 되지 않고 서버에만 존재하지만

 

Play as Offline 인 클라이언트 단독으로만 실행 할 경우에는 게임모드가 클라이언트에서 생성 되고 삭제 되고 다른곳에 복제 시킬 일도 없음으로 클라이언트 자체가 GameMode 의 Authority 가 된다는 것을 알 수가 있다

 

 

Role_Authority 란 서버만을 얘기 하는 것이 아니라(보통은 서버) 해당 오브젝트가 생성되어 실질적으로 관리를 하고 있는 대상에 따라 Authority 가 된다

 

 

ex) 

1. 멀티 환경에서 서버에서 게임모드는 서버가 관리 함으로 서버에서 GameMode 는 Role_Authority 

하지만 클라에서는 존재자체를 하지 않음

 

2. Play As Offline 으로 서버 없이 실행할 경우 클라에 게임모드가 생성이 되며 이때 생성된 게임 모드는 Role 은 Role_Authority 가 된다, 여기서 관리 되고 삭제 됨으로

 

 

언리얼 도큐먼트 설명에 나와 있는 클라로 Replicated 하지 않는다,

즉 클라이언트중 게임모드가 존재하지 않는다는 것은

멀티 환경 구성이 갖추어 진상태에서 서버가 존재하지만 Play As Client 로 실행 하여 클라로 붙었을때 게임 모드가 존재하지 않는 것이다라는 것을 알 수 있다

반응형
반응형

EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());

이것을 호출 하면 instantiate 한 GameObject 가 에디터를 껐다 킨 이후에도 정상적으로 저장되어 있음

 

하단은 저장 관련한 내용들..

 

 

I am using Unity 2019.2.6f1

I have a single scene that I am using for the main field of play. All characters are prefabs. Each level is saved to a JSON file that controls which characters are to be loaded for the scene and where they are to be positioned.

I have an editor script (SaveLevel) that will create the JSON file based on how I have the scene configured in the editor. I have a second editor script (LoadLevel) that will read the JSON file and set up the scene for that level.

This is all done in the editor at design time. I can save and load levels fine. However, after I load a level, if I hit the play button, to test the level, the scene resets to an empty scene (how it was before I loaded the level).

How can I load my prefabs into my scene and save the scene so that I can test the level?

Here is my code for loading the level:

-- EDIT -- Based on the response by @Ron the fix is the code change in LoadLevel() below.

 

 

...

 

Are you saying that you run this code inside the editor, see the gameobjects created in the hierarchy and scene view, and when you hit play it resets to an empty scene? – Ron Nov 10 '19 at 20:48

  • Yes, except the scene's not completely empty. All of the gameobjects that are saved with the scene, before I run my script, are still there. Only the gameobjects added by my script are missing. – Don Shrout Nov 10 '19 at 22:22
  • C# != UnityScript (which is a Javascript derivative created for unity). – Llama Nov 11 '19 at 0:51
  • @John thanks for the clarification. I added the UnityScript tag because this is a question about code not just the editor. I didn't realize that UnityScript was the official title for Unity's version of JavaScript. I've only ever used C# with Unity. – Don Shrout Nov 11 '19 at 12:50
  • Can you try calling EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene()); before you call EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo(); – Ron Nov 13

 

 

 

stackoverflow.com/questions/58790108/load-prefabs-via-script-and-save-scene-in-unity-editor

반응형
반응형

아래 그림 처럼 부모가 Cube 자식이 비어 있는 Sphere 트리거 인 경우 

 

[상황 설정]

자식 오브젝트와 부모 오브젝트 각각에 BoxCollide (Trigger 가 켜진) 와 스크립트가 변로로 존재하고(OnTriggerEnter 가 각각 있는) 부모에만 Rigidbody 가 있다면

 

Sphere 에 충돌시 부모의 OnTriggerEnter 와 자식의 OnTriggerEnter 가 모두 불리는데 

이는 자식과 부모를 하나의 닫힌 Mesh 라고 판단하기 때문

 

그래서 각각 부모와 자식의 스크립트의 OnTriggerEnter 가 호출되게 하려면 

자식에도 Rigidbody 를 추가해줘야 한다

 

 

 

 

 

Trigger in child object calls OnTriggerEnter in parent object

The parent object is a small cube with a box collider trigger to fit and a kinematic rigidbody. the child of that object is an empty with a sphere collider trigger that is larger than the box collider.

different scripts are in both parent and child with OnTriggerEnter functions.

expected behavior: when the larger sphere collider (a component of the child) is triggered without triggering the parent, OnTriggerEnter is called in the child object's script.

observed behavior: when the larger sphere collider is triggered, OnTriggerEnter is called in both the parent and the child scripts.

 

 

 

 

Answer by hoy_smallfry · '13년 Mar월 04일 PM 09시 47분

Read the section labeled "Compound Colliders" on this page.

Long story short, collider shapes can't be concave and the only way to accomplish something concave is to treat all convex colliders in children under a parent as if they are one shape, if the parent is the only one with a rigidbody. So, your parent is treating it as if its a complex shape, hence OnTriggerEnter in your parent is getting called.

Try this: give the child a kinematic rigidbody. This will separate it from the parent collision, but still allow it to be moved by the parent's transform instead of physics.

However, be aware that if one touches or encompasses the other, now that they are seen as separate entities, a collision trigger will get registered between the two, even if it's just at the beginning of the scene. They won't bounce off each other since one is a trigger, but you may want to have each OnTriggerEnter function ignore the other Collider if it matches the tag of the other:

 

 

I hope that helps!

Add comment ·  Hide 11 · Share

buscommando · '13년 Mar월 05일 AM 02시 34분 1

 

I will experiment with this. Thank you much!

The parent's trigger matches the parent's mesh exactly, if something triggers it the parent dies.

The child's trigger is a spatial buffer - if something triggers the child's collider, the parent moves/runs away from the object that triggered it.

I had not considered giving both the parent and the child I$$anonymous$$ rigidbodies, currently only the parent has a rigidbody.

$$anonymous$$y solution in the interim was to remove the collider from the parent and add a second child with its own OnTriggerEnter script and a trigger collider identical to the parent's old collider. It worked but felt kludgey, your solution seems a bit more elegant.

kalibcrone  buscommando · '17년 Jul월 13일 PM 01시 06분 2

 

Just a friendly note, "I$$anonymous$$" stands for "Inverse $$anonymous$$inematics" and doesn't really mean the same thing in this context of a $$anonymous$$inematic RigidBody. The term I$$anonymous$$ is generally used when talking about rigging a model for animation.

pas0003 · '13년 Jun월 03일 AM 10시 27분 0

 

Thank you so much for that tip!! :D

filip_andry · '14년 Jul월 01일 AM 06시 58분 0

 

Thanks, It worked for me.

einzweidrei · '15년 Feb월 24일 AM 10시 42분 1

 

Yes, $$anonymous$$inematic Rigidbody did it exactly. Thanks, this made it work finally after long period of banging my head around. :-)

dgreedy · '15년 Apr월 29일 PM 11시 23분 0

 

Buscommando's solution of seperating the triggers and trigger scripts into separate children of the parent object worked well for me. Thanks.

 

 

ref : answers.unity.com/questions/410711/trigger-in-child-object-calls-ontriggerenter-in-pa.html

반응형
반응형

 

이름은 모르지만 알것 같은 이분?

 

 

반응형

+ Recent posts