반응형

안드로이드 스튜디오 gradle에서 Gson 라이브러리 등록하는 방법입니다.

 

- 안으로이드 스튜디오에서 라이브러리 추가 방법

1. 라이브러리 추가

2. 검색

com.google.code.gson:gson:2.8.7

3. 해당 버전 확인 후 OK

1. 아래 사이트 접속.

2. build.gradle 에 Dependency 추가

3. Project Structure에서 라이브러리 적용

-끝-

 


1. https://mvnrepository.com/artifact/com.google.code.gson/gson

2. 원하는 버전선택

Gson 버전선택

3. Build Tool(빌드 관리 프로그램)을 선택

4. build.gradle의 dependancies에 추가

5. File -> Proejct Structure 들어가기

6. Dependencies 탭-> app -> Gson 선택 -> 적용(apply) -> OK

7. 코드 작성해보기

@Test
public void toSJON() {
    Gson g = new Gson();
    Circle a = new Circle(10f, 20f, 40f);
    String json = g.toJson(a);
    Circle b = g.fromJson(json, Circle.class);
    assertTrue(10f == b.getX());
    assertTrue(20f == b.getY());
    assertTrue(40f == b.getRadius());
}
반응형
반응형

1. Board.cs 코드

using UnityEngine;
using System.Collections;

public class Board : MonoBehaviour {

	public int width;
	public int height;

	public int borderSize;
  	void Start () 
	{
		m_allTiles = new Tile[width,height];
		m_allGamePieces = new GamePiece[width,height];

		SetupTiles();
		SetupCamera();
	}
    
    	void SetupCamera()
	{
		Camera.main.transform.position = new Vector3((float)(width - 1)/2f, (float) (height-1) /2f, -10f);

		float aspectRatio = (float) Screen.width / (float) Screen.height;
		float verticalSize = (float) height / 2f + (float) borderSize;
		float horizontalSize = ((float) width / 2f + (float) borderSize ) / aspectRatio;

		Camera.main.orthographicSize = (verticalSize > horizontalSize) ? verticalSize: horizontalSize;
	}
}

2. Canvas, Image 추가하기

Hierachy에 Canvas와 Image를 추가하고, Canvas에 Image 개체를 위치시킵니다.(가장 오른쪽 그림 참고)

 

3. Canvas의 Camera 설정 하기

Hierachy에서 Canvas를 선택한다음 'Render Camera'의 설정값을 Main Camera로 설정합니다.

위 그림처럼 빨간 네모를 선택하세요.

 

4. 배경색 넣기

Canvas안에 있는 Image를 꽉찬 화면비율로 변경하고, 색을 지정합니다.

Hierachy에서 Image개체를 선택합니다.

Rect Transform에서 왼쪽에 위치한 'stretch'를 클릭하면 'Anchor Presets'창이 뜹니다.

가장 오른쪽 아래 있는 꽉채우기 를 선택하시면 됩니다.

 

그다음 Iamge의 색을 변경하기 위해 오른쪽 그림에 있는 빨간 네모쪽을 클릭하여 원하는 색으로 지정합니다.

 

5. 결과물

보기와 같이 중앙에 카메라가 위치하여 적절한 화면을 보입니다.


원리 이해하기

Main camera의 Projection이 Orthographic일 때를 기준으로 합니다.

(2D 게임은 주로 Orthographic 입니다.)

보드의 세로, 가로 크기에 따라 자동적으로 카메라가 적절히 세팅합니다.

보드의 타일 갯수상관없습니다.

5x10, 5x5, 10x5 각 크기에 맞추어 자동으로 세팅합니다.

 

카메라가 화면의 중심에 위치하는데 5개의 변수가 영향을 미칩니다.

Board.borderSize, Board.width, Board.height, Screen.width, Screen.height

Board.borderSize: 보드에서 화면까지의 여백의 크기

Board.width: 가로축 타일의 갯수

Board.height: 게로축 타일의 갯수

Screen.width: 게임 화면의 밑변

Screen.height: 게임 화면의 높이

1. Aspect ratio 구하기

Aspect Ratio(종횡비): 가로(Width)와 세로(Height)의 비율

종횡비: 화면 높이 / 화면 밑변

화면 밑변: 화면 높이 x 종횡비

화면 높이: orthographic 길이

 

카메라가 정중앙 위치하려면 화면(Screen)의 높이와 밑변의 반씩 되는 값만 있으면 될것 같지만,

메인 카메라의 위치를 Board 타일의 갯수에 따라 자동적으로 중앙에 위치하도록 합니다.

그래야 타일 양옆 위아래로 여백이 생겨서 안정감 있는 화면이 구성됩니다.

	void SetupCamera()
	{
		Camera.main.transform.position = new Vector3((float)(width - 1)/2f, (float) (height-1) /2f, -10f);
		float aspectRatio = (float) Screen.width / (float) Screen.height;
	}

width -1, height -1로 설정한 이유는, 배열이 0Base 이기 때문입니다.

높이와 밑변의 반값으로 x, y축 값을 지정합니다. (z 값은 -10을 디폴트 값으로합니다.)

2. 수직, 수평 orthographic 크기 구하기

void SetupCamera()
{
// --------------------------------생략---------------------------------------------------
	float verticalSize = (float) height / 2f + (float) borderSize;
	float horizontalSize = ((float) width / 2f + (float) borderSize ) / aspectRatio;
	Camera.main.orthographicSize = (verticalSize > horizontalSize) ? verticalSize: horizontalSize;
}

게임 화면이 세로 이기 때문에 verticalSize는 y축(height)의 절반 + 여백(borderSize)로 쉽게 구할 수 있습니다.

 

horizontal은 x축이 y축 보다 많은 10x5와 같은 경우에 사용됩니다.

border의 unit: board의 타일 1개로 정해집니다.

수직(vertical)

수평(horizontal)

 

반응형

'프로그래밍 > Unity' 카테고리의 다른 글

Grid - Puzzle Game in Unity 그리드 만들기  (0) 2022.10.18
간접등 만들기 - particular System  (0) 2022.01.03
씬 생성 및 이동  (1) 2020.05.15
반응형

유니티에서 위의 그림과 같은 그리드를 만들어 보도록하겠습니다.

(가운데 있는 GamePiece는 다른 포스트에서 다루도록하겠습니다.)

 

5x5 퍼즐 게임에서 그리드는 만드는 방법입니다.

 

해당 포스팅을 따라해도 화면이 생각과 다르게 나옵니다.

이러한 문제는 카메라 세팅을 만지면 해결할 수 있으니 다음 글에서 확인해주세요.


0. 용어설명

GamePiece: 동그라미 Game Object로써, 사용자가 움직일 대상입니다.

GamePiece

Tile: 그리드에서 각 칸에 해당되는 Game Object로써, Board안에서 배열로 위치합니다.

Tile

Board: Tile과 GamePiece prefab에 위치(좌표)를 설정하는 Game Object입니다. 

1. 보드 (Board)

1. GameObject 생성

Hierarchy에서 Create Empty를 선택하여 GameObject를 생성합니다.

생성된 Game Object의 이름을 "Board"로 변경합니다.

 

2. 스크립트 추가

Project-Assets에서 C#Script를 생성합니다.

파일 이름을 "Board"로 변경합니다.

using UnityEngine;
using System.Collections;

public class Board : MonoBehaviour {

  public int width; // 
  public int height;
  public GameObject tilePrefab;
  private Tile[,] m_tiles;

  void Start () 
  {
    m_tiles = new Tile[width,height];
    SetupTiles();
  }

  void SetupTiles()
  {
    for (int i=0; i < width; i++)
    {
      for (int j=0; j < height; j++)
      {
        GameObject tile = Instantiate (tilePrefab, new Vector3(i, j, 0), Quaternion.identity) as GameObject;
        tile.name = "Tile ("+i+","+j+")";
        m_tiles[i,j] = tile.GetComponent<Tile>();
        tile.transform.parent = transform;
      }
    }
  }
}

width: 타일의 갯수, height: 타일의 갯수.

tilePrefab: 보드에 배치하는 Game Object.

m_tiles: 좌표에 필요한 tilePrefab의 배열.

 

SetupTiles(): 

tilePrefab을 이용하여 Game Object 인스턴스를 생성하여 보드에 나열합니다.

보드에 나열할때는 Tile이라는 prefab을 이용하여 나란히 정렬합니다.

좌표는 for문으로 i는 x축을, j는 y축으로 합니다.

 

해당 작업이 끝났다면, Board GameObject를 선택하여 Inspector에서

Add Component를 이용하여 Board.cs를 추가합니다.

2. 타일(Tile)

1. GameObject 생성

Hierarchy에서 Create Empty를 선택하여 GameObject를 생성합니다.

생성된 Game Object의 이름을 "Tile"로 변경합니다.

 

2. Rendering 추가

"Tile" Game Object의 Inspector에서 Add Component를 누릅니다.

Rendering > Sprite Renderer를 선택합니다.

흰색 테두리 그림

위 그림과 같이 안쪽이 비어있는 흰택 테두리 png파일을

Inspector>Sprite Renderer의 Sprite에 추가합니다.

Tile의 Sprite Renderer에 Sprite추가 하는 장면

3. 스크립트 추가

Project-Assets에서 C#Script를 생성합니다.

파일 이름을 "Tile"로 변경합니다.

using UnityEngine;

public class Tile : MonoBehaviour {

  public int xIdx;
  public int yIdx;

  private Board m_board;

  void Start () {}

  public void Init(int x, int y, Board board)
  {
    xIdx = x;
    yIdx = y;
    m_board = board;
  }
}

해당 작업이 끝났다면, Tile GameObject를 선택하여 Inspector에서

Add Component를 이용하여 Tile.cs를 추가합니다.

 

 

방금 만든<Tile> Game Object를 재사용하기 위해

Assets으로 드래그&드랍하여 prefab으로 변경합니다.

 


해당 프로젝트를 실행합니다.

그리드 완성된 모습

그리드가 화면 중심에 오지 않은 상태입니다.

 

다음은 퍼즐을 위한 그리드가 화면 중심에 위치시키는 글을 작성해보겠습니다.

 

다음에 만나요~

반응형
반응형

불이 바닥이나 벽에 반사되는 간접등과 같은 효과입니다.

혹은 디아블로의 팔라딘 캐릭터 바닥에서 뿜어져 나오는 오러(아우라) 같습니다.

파티클 시스텝 객채 생성

1. [Hierarchy] -> {Effects} -> {Particle System}

[Hierarchy]에서 +를 눌러, 파티클 시스템을 생성합니다.

파티클 시스템 추가 방법 및 추가 결과 확인

오른쪽 처럼 [Scene]에 주황색으로 마킹된 파티클이 움직이면 정상적으로 생성이 완료되었습니다.

 

1.5 'Circle Light'로 생성된 파티클 시스템의 이름을 바꿉니다.


2. 설정 변경하기

2.1. 기본 설정 변경

[Inspector] -> {Particle System}에서 속성을 변경합니다.

Duration: 방출되는 파티클의 시간을 나타냅니다. [1 싸이클 단위] 

Start Lifetime: 0이 되면 사라집니다. [초 단위] (Duration과 1:1 비율로 세팅했습니다.)

Start Speed: 방출 되는 속도를 나타냅니다.(Lifetime과 비교하면서 조절해보세요!)

Start Size: 파티클의 시작 크기입니다. (적용할 오브젝트 크기에 맞춥니다.)

 

2.2. Emission 변경

[Inspector] -> {Emission}에서 속성을 변경합니다.

Emission을 클릭하고, Bursts의 +를 눌러  Bursts를 추가합니다.

Rate over Time: 초당 방출되는 파티클 수

Rate over Distance: 거리당 방출되는 파티클 수

 

Bursts: 추가적으로 파티클의 갯수, 사이클 등을 컨트롤 합니다.

 

2.3. 한곳에서만 방출하기

* 이번 포스트의 목표는 캐릭터 아래에서 일정하게 나오는 모양임으로, 파티클이 한개의 에서만 나와야 합니다.

[Inspector] -> {Shape} 끄기

Shape: 방출되는 모양을 나타냅니다.

사각형, 원과 같은 일정한 모양 안에서 방출합니다.

 

2.4. 색 추가하기

체크박스 선택 후 색을 눌러 변경을 합니다

시작/종료 색: FF7500

중간지점 alpha값: 128, location: 50%


3. 프리팹 및 Lights 추가

Range Multiplier: 범위 설정값

Intensity Multiplier: 강도 설정값

Maximum Lights: 최대 갯수

 

최적화된 프리팹을 추가합니다.

점모양으로 된 프로팹으로, 그림자나 다른 영향을 미치지 않도록 최적화되었습니다.

 

프리팹 다운로드:

https://assetstore.unity.com/packages/essentials/asset-packs/unity-particle-pack-5-x-73777?_ga=2.162642300.1737033803.1641185812-723993449.1640589127

 

Unity Particle Pack 5.x | 에셋팩 | Unity Asset Store

Get the Unity Particle Pack 5.x package from Unity Technologies and speed up your game development process. Find this & other 에셋팩 options on the Unity Asset Store.

assetstore.unity.com

사용할 프리팹 경로:

 Assets > EffectExamples > Shared > Prefabs > ParticlesLight

오른쪽 위 최럼 Light에 프리팹을 추가합니다.

 

 

해당 영상을 간소화하여 만들었습니다.

https://youtu.be/yhXGAb7ku8M

 

조금더 깊숙히 배우고 싶으신 분은

https://learn.unity.com/tutorial/visual-effects-with-particles#5c7f8528edbc2a002053b57e

 

Visual Effects with Particles - Unity Learn

In this Live Training Session, we will look at creating visual effects for games using Particle Systems. The techniques we will learn include using trail effects, adding noise to Particle Systems and creating particles which shed light on the scene.

learn.unity.com

여기를 참고하세요~

반응형
반응형

*주의: 현재 빌드잇의 맵 또는 템플릿을 가져와 구현 불가능합니다.

제페토에 질의 응답 결과입니다.

github
제페토 스크립트 맥버전 설치 링크

제페토 월드는 Unity 2020.3.9f1 버전에서만 개발 가능합니다

제페토 유니티 설치 링크

https://studio.zepeto.me/kr/guides/installing-unity-and-registering-zepeto-template

ZEPETO Studio

ZEPETO 크리에이터가 되어보세요!

studio.zepeto.me


유니티 허브 - Mac

---사이트

https://unity.com/download

--- 맥 버전 다운로드 링크

https://public-cdn.cloud.unity3d.com/hub/prod/UnityHubSetupBeta.dmg

---사이트

https://unity3d.com/unity/whats-new/2020.3.9

--- Unity 2020.3.9 다운리드 링크

https://download.unity3d.com/download_unity/108be757e447/MacEditorInstaller/Unity.pkg?_ga=2.113063108.1512932317.1640583689-1051985377.1640583689

--- ZEPETO 월드 템플릿 다운로드 링크

https://upm.zepeto.run/setup/package

공식 사이트에서 mac링크가 잘 작동하지 않아서 모아 놓았습니다.

반응형

'프로그래밍' 카테고리의 다른 글

Chrome DevTools, JavaScript Event Handling / Binding  (0) 2021.02.15
반응형

1. JSON.stringify()

2. IONIC template rendering


import { Recoder } from "./recoder.model";

export class Recoders extends Array<Recoder> {
  recoders: Recoder[];
  isEmpty: boolean;

  constructor(recoders?: Array<Recoder>) { 
    super(...recoders);
  }
}

Array<T>를 extends 할 경우 모든 배열의 기능을 사용할 수 있다.

 

하지만 JSON.stringify()를 사용할 경우, isEmpty와 같은 변수가 없어지는 것을 알 수 있었다.

 

그래서 extends 없이 기능을 구현해 보았다.

import { Recoder } from "./recoder.model";

export class Recoders {
  recoders: Recoder[];
  isEmpty: boolean;

  constructor(recoders?: Recoder[]) { 
    this.recoders = recoders;
  }

  push(recoder: Recoder) {
    this.recoders.push(recoder);
  }
  
}

이럴 경우, Template Rendering 시 오류(문제)가 발생했다.

*ngFor을 사용하여 HTML에 리스트를 뿌릴 수 없다.

반응형

'프로그래밍 > Ionic' 카테고리의 다른 글

Ionic singleton 싱글턴 패턴 [싱글톤]  (0) 2021.07.15
ionic-modal tutorial 예제  (0) 2021.07.03
ion-input 안드로이드 작동  (0) 2021.06.07
Ionic 어플 - 아이폰 앱 설치(배포)  (0) 2021.05.04
아이오닉 form handling  (0) 2020.02.14
반응형

service나 module은 기보적으로 싱글턴으로 작동한다.

하지만 여기서는 클래스 단위의 싱글턴을 사용할 것이다.

 

시간을 yyyyMMdd패턴으로 바꾸어주는 클래스를 예시로 들어보겠다.

namespace 와 export 키워드를 반드시 사용한다.

// date-formatter.ts

export namespace DateFormatterSingleton {  

    export function nowYYYYmmDD():string {
        let _temp = new Date();
        return _yyyyMMdd(_temp);
    }

    export function toYYYYmmDD(date: string):string {
        let _temp = new Date(date);
        return _yyyyMMdd(_temp);
    }

    function _yyyyMMdd(date: Date) {
        return date.getFullYear()+'-'
        +_toTwoDigits((date.getMonth()+1).toString())+'-'
        +_toTwoDigits(date.getDate().toString());
    }

    function _toTwoDigits(numeric: string):string {
        return numeric.length == 1 ? "0"+numeric : numeric;
    }
}

 

사용방법

import { DateFormatterSingleton } from 'src/app/model/date-formatter';

datePicker: string = DateFormatterSingleton.nowYYYYmmDD();

위 코드와 같이 사용하면된다. Java에서와 같이 getInstance()와 같은 호출은 필요없다.

반응형
반응형

1. Module로 만들기

2. Module에 export추가하기

3. 원하는 여러 모듈에 import


isDayTime 이라는 boolean 타입의 값을 한글로 변환해 주는 파이프입니다.

true면 주간으로

false면 야간으로 변경합니다.

 

최종 형태:

// day-time.pipe.module.ts

import { NgModule } from "@angular/core";
import { DayTimePipe } from "./day-time.pipe";

@NgModule({
    imports: [],
    declarations: [DayTimePipe],
    exports: [DayTimePipe]
})
export class DayTimePipeModule { }
// day-time.pipe.ts

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({
  name: 'dayTime'
})
export class DayTimePipe implements PipeTransform {

  transform(value: boolean): string {
    return !!value ? '주간' : '야간';
  }

}

사용 예:

<!-- 어디가.html -->
<ion-item>
  <ion-label>근무 시간 선택: {{recoderTemplate.info.isDayTime | dayTime}}점검</ion-label>
  <ion-toggle color="success" [(ngModel)]="recoderTemplate.info.isDayTime"></ion-toggle>
</ion-item>

주의사항: 'day-time.pipe.module.ts'가 아래 코드와 같이 다른 모듈이 imports 되어있다면 애러가 발생합니다.

그러니 꼭 다른 imports가 없도록 만들어야합니다.

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { IonicModule } from '@ionic/angular';
import { RouterModule, Routes } from '@angular/router';
import { FormsModule } from '@angular/forms';
import { TimeReadComponent } from './time-read.component';

const routes: Routes = [
  {
    path: '',
    component: DayTimePipe
  }
];

@NgModule({
  imports: [
    CommonModule,
    IonicModule,
    FormsModule,
    RouterModule.forChild(routes)
  ],
  declarations: [DayTimePipe],
  exports: [DayTimePipe]
})
export class DayTimePipeModule { }

 

반응형
반응형

1. modal page 생성

2. 상위 module에 import 'modal page'

3. modal page 코드 작성

 

Ionic5 Angular 기반으로 작성하였습니다.


1. modal page 생성

// cli로 하는 경우, 명령어를 입력해 생성합니다.
ionic generate page modal-exam

generate page를 사용하면, 4개의 파일이 생성됩니다.

module.ts, html, scss, ts

// modal-exam.module.ts

const routes: Routes = [
  {
    path: 'modal-exam',
    component: ModalExamPage
  }
];

@NgModule({
  imports: [
	...
  ],
  declarations: [ModalExamPage],
  exports: [ModalExamPage]
})
export class ModalExamPageModule {}

[route 사용하는 경우]

반드시 path에 위치를 기입해주세요.


2. 상위.module에 NgModule에 등록하기

// home.module.ts

... 
@NgModule({
  imports: [
	...
    ModalExamPage
  ],
})
export class HomeModule { }

3. modal page 코드 작성

<!-- modal-exam.html -->

<div class="ion-page">
  <ion-header>
    <ion-toolbar>
      <ion-buttons slot="end">
        <ion-button (click)="closeModal()">닫기</ion-button>
      </ion-buttons>
      <ion-title>{{data}}</ion-title>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding">
    <ion-item>
      내용을 추가하세요
    </ion-item> 
  </ion-content>
</div>
// modal-exam.page.ts

import { Component, Input, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';

@Component({
  selector: 'app-modal-exam',
  templateUrl: './modal-exam.page.html',
  styleUrls: ['./modal-exam.page.scss'],
})
export class EditInfoPage implements OnInit {
  
  @Input() data: string;

  constructor(public modalController: ModalController) { }

  ngOnInit() {}

  closeModal() {
    this.modalController.dismiss({
      'dismissed': true
    });
  }

}
<!-- home.component.html -->
<div class="ion-page">
  <ion-header [translucent]="true">
    <ion-toolbar>
    <ion-title>
      모달 예제
    </ion-title>
    </ion-toolbar>
  </ion-header>
  <ion-content class="ion-padding" [fullscreen]="true">
    <ion-item >
      <ion-label>수정하기</ion-label>
      <ion-button color="success" slot="end" (click)="editLocation()">
        <ion-icon name="arrow-forward"></ion-icon>
      </ion-button>
    </ion-item>
  </ion-content>
</div>
// home.component.ts

import { Component, OnInit } from '@angular/core';
import { ModalController } from '@ionic/angular';

@Component({
  selector: 'app-template',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss'],
})
export class TemplateComponent implements OnInit {

constructor(public modalController: ModalController) { }

  ngOnInit() {}
  
  async presentModal() {
    const modal = await this.modalController.create({
      component: EditInfoPage,
      componentProps: {
        'data': 'modal-example'
      }
    });

    modal.onDidDismiss().then((res:any) => {
      if (res !== null) {
        console.log('Modal Sent Data : '+ res.data);
      }
    });

    return await modal.present();
  }

}
반응형
반응형

ionic serve를 이용한 웹 버전에서는 아무런 문제가 없던 기능이

android에서 작동하면 의도와는 다르게 데이터가 바인딩이 안되는 경우가 있었습니다.

 

안드로이드에서는 Ion-input 태그가 의도와는 다르게 작동하는 것을 발견하였습니다.

 

제가 추측하기에는 안드로이드의 경우,

ion-input > input 태그의 값을 가져오도록 설정되어 있는것 같습니다.

 

ion-input아래 input태그 화면

캐패시터에서 바인딩을 어떤식으로 해주는지 몰라서 여러 시도를 해보았습니다.

결국 dom을 만질 때 처럼 직접 element의 attr을 접근해야 했습니다.

constructor(private el: ElementRef) {}

  onkeyup() {
    const _el = this.el.nativeElement.firstElementChild;
    if (_el.value != _el.value.trim() || !this.isHHmm(_el.value)){
      this._removeLastString(_el);
      return;
    }
    if (_el.maxLength < _el.value.length) {
      this._removeLastString(_el);
      return;
    }
  }

constructor 불러올 때, Element로 반인딩 합니다.

 

ion-input태그는 nativeElement입니다.

input은 firstElementChild입니다.

 

위 사진과 같이 저는 input child로 되어 있기 때문에 firstElementChild를 사용했습니다.

 

그럼 input에 직접 접근할 수 있게 됩니다.

value의 값을 가져오고, 직접 수정할 수 있습니다.

반응형

'프로그래밍 > Ionic' 카테고리의 다른 글

Ionic singleton 싱글턴 패턴 [싱글톤]  (0) 2021.07.15
ionic-modal tutorial 예제  (0) 2021.07.03
Ionic 어플 - 아이폰 앱 설치(배포)  (0) 2021.05.04
아이오닉 form handling  (0) 2020.02.14
Ionic 4 배포하기  (0) 2019.11.08

+ Recent posts