1. Spine2D의 MecaAnim(Animator)에서 <MeshRenderer> 컴퍼넌트를 빼옴
  2. <MeshRenderer> 컴퍼넌트의 마테리얼들을 sharedMaterials로 가져옴
    • materials가 아니라 sharedMaterials를 사용하는 이유
      : 왜인지 모르겠지만 적용이 안되는 경우가 있음
      : 이쪽이 확실함
  3. 해당 Shader를 상황에 맞게 변경
    • 기본 Shader : Spine/Skeleton
    • 기본 Outline Shader : Spine/Outline/Skeleton
    // :: 중복 방지
    private bool iOutline = false;
    public void ShowOutline(bool check)
    {
        // :: 중복 실행 방지
        if (iOutline == check)
            return;

        this.iOutline = check;

        // :: 메쉬 렌더러 확인
        var meshRenderer = this.Animator.GetComponent<MeshRenderer>();

        // :: 상황에 따라 쉐이더 변경
        foreach (var mat in meshRenderer.sharedMaterials)
        {
            if(check)
            {
                mat.shader = Shader.Find("Spine/Outline/Skeleton");
            } else
            {
                mat.shader = Shader.Find("Spine/Skeleton");
            }
        }
    }

 

블로그 이미지

RIsN

,
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

/// <summary>
/// Alpha값(0.1f) 이상만 버튼 클릭되도록 하는 부착 스크립트
/// </summary>
public class ATTACHAlphaButton : MonoBehaviour
{
    public float iAlphaThreshhold = 0.1f;

    private void Start()
    {
        this.GetComponent<Image>()
            .alphaHitTestMinimumThreshold = this.iAlphaThreshhold;
    }
}
블로그 이미지

RIsN

,
GameObject goRaw = new GameObject(typeof(T).Name);

: typeof(T).Name으로 게임오브젝트의 이름을 사용

블로그 이미지

RIsN

,

Input.multiTouchEnabled

Unity 2021. 5. 4. 22:21

Input.multiTouchEnabled

: 멀티 터치 허용 / 비허용

private void InitApplication_Setting()
{
	Application.targetFrameRate = 60;
	Input.multiTouchEnabled = false;
}

 

블로그 이미지

RIsN

,

Application.targetFrameRate

: 어플리케이션의 Frame Rate 설정

private void InitApplication_Setting()
{
	Application.targetFrameRate = 60;
	Input.multiTouchEnabled = false;
}

'Unity' 카테고리의 다른 글

[typeof] T(제네릭)를 게임 이름으로 쓰고 싶을 때  (0) 2021.06.30
Input.multiTouchEnabled  (0) 2021.05.04
DOTween 관련 정리  (0) 2021.03.06
[My Style] Dictator 구조  (0) 2021.03.05
[My Style] 유니티 씬 구조  (0) 2021.03.05
블로그 이미지

RIsN

,

DOTween 관련 정리

Unity 2021. 3. 6. 12:54

메모

  • Scene을 전환할 때마다 DOTween을 전부 제거(KillAll)할 것
    • 제거하지 않으면 Warning이 뜰 때가 있음

'Unity' 카테고리의 다른 글

Input.multiTouchEnabled  (0) 2021.05.04
Application.targetFrameRate  (0) 2021.05.04
[My Style] Dictator 구조  (0) 2021.03.05
[My Style] 유니티 씬 구조  (0) 2021.03.05
[My Style] 유니티 프로젝트 구조  (0) 2021.03.05
블로그 이미지

RIsN

,

[My Style] Dictator 구조

Unity 2021. 3. 5. 18:38

중복되는 구조

  • 어플리케이션 실행 도중 하나만 존재하고, 사라지지 않는 독재자(Dictator) 스크립트
  • 씬을 로드하는 것은 이 독재자의 행동
  • 각 씬의 Ruler를 로드하는 것도 이 독재자의 행동
  • 각 씬 간의 이동에서 사용하는 스테이터스 변수도 가지고 있을 때가 있음
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Dictator : MonoBehaviour
{
    // : 0 Awake
    private void Awake()
    {
        // :: Check Overlap
        int hashThis = this.GetHashCode();
        Dictator dictatorFound = GameObject.FindObjectOfType<Dictator>();
        int hashFound = dictatorFound.GetHashCode();
        if (hashThis != hashFound)
            Object.Destroy(dictatorFound.gameObject);

        // ::
        DontDestroyOnLoad(this.gameObject);

        // :: Init
        this.Init();
    }

    // : Status

    // : Init
    private void Init()
    {
        // :: Debug
        Debug_AppName();
        Debug_AppVersion();

        // :: Init Complete
        Debug_Init(this.ToString());

        // :: Load Scene
        LoadScene(Enum.eScene.INTRO);
    }

    // : Load
    public static void LoadScene(Enum.eScene eScene)
    {
        int sceneID = (int)eScene;
        AsyncOperation sync = SceneManager.LoadSceneAsync(sceneID);
        sync.completed += scene =>
        {
            if (scene.isDone)
                switch(eScene)
                {
                    case Enum.eScene.INTRO:
                        InitScene<Intro_Ruler>();
                        break;
                }
        };
    }

    // : Init
    public static void InitScene<T>() where T : Ruler
    {
        var Ruler = GameObject.FindObjectOfType<T>();
        Ruler.Init();
    }

    // : Debug
    public static void Debug_AppName()
    {
        string log = string.Format(":: App Name : {0}", Application.productName);
        Debug.Log(log);
    }
    public static void Debug_AppVersion()
    {
        string log = string.Format(":: App Version : {0}", Application.version);
        Debug.Log(log);
    }
    public static void Debug_CheckDictator()
    {
        Dictator dictator = GameObject.FindObjectOfType<Dictator>();
        if (dictator == null)
            SceneManager.LoadScene((int)Enum.eScene.DICTATOR);
    }
    public static void Debug_Init(string scriptName)
    {
        string log = string.Format(":: {0} Init Complete", scriptName);
        Debug.Log(log);
    }
}

 

'Unity' 카테고리의 다른 글

Application.targetFrameRate  (0) 2021.05.04
DOTween 관련 정리  (0) 2021.03.06
[My Style] 유니티 씬 구조  (0) 2021.03.05
[My Style] 유니티 프로젝트 구조  (0) 2021.03.05
[Unity] 로컬 서버 연결 테스트 케이스  (0) 2021.02.21
블로그 이미지

RIsN

,

중복되는 구조

  • Ruler : Ruler 상속
    • 모든 것을 관리하는 관리자
    • 실제 기능을 가지고 있지는 않음
    • Dictator에 의해 Init 됨
  • UIChief : Chief 상속
    • UI를 관리하는 관리자
    • 실제 UI의 기능이 정의되어 있음
    • Ruler에 의해 Init 됨
  • GOChief : Chief 상속
    • 게임 오브젝트(2D 혹은 3D)를 관리하는 관리자
    • 실제 게임 오브젝트의 기능이 정의되어 있음
    • Ruler에 의해 Init 됨

'Unity' 카테고리의 다른 글

DOTween 관련 정리  (0) 2021.03.06
[My Style] Dictator 구조  (0) 2021.03.05
[My Style] 유니티 프로젝트 구조  (0) 2021.03.05
[Unity] 로컬 서버 연결 테스트 케이스  (0) 2021.02.21
0 : UNITY=SPINEの記憶するべきもの  (0) 2020.12.12
블로그 이미지

RIsN

,

중복되는 구조

  • Dictator
    • 독재자
    • Don't Destroy로 게임 실행시 사라지지 않도록 함
  • Intro
    • 인트로
블로그 이미지

RIsN

,

<환경 설정>

// : Express 사용
const express = require('express');
const router = express.Router();

// : 데이터베이스 커넥트
const connectPool = require('../connectPool');

router.post('/', async (require, response) => {

    // :: 받아옴
    const { userName } = require.body;

    // :: 쿼리 생성
    const query = "select * from users where userName = ?";

    // :: 쿼리 적용
    try {
        let[rows, fields] = await connectPool.promise()
        .query(query, [userName]); // :: 적용

		// :: 결과 테스트
        const name = rows[0].userName;
        const email = rows[0].userEmail;
        const time = rows[0].userConnectedTime;
        console.log(`이름 : ${name}, 이메일 : ${email}, 시간 : ${time}`);

        response.json({userData: rows});
    } catch(error) {
        
        response.sendStatus(500);
    }
});

module.exports = router;

<테스트>

  1. 빈 유니티 3D 프로젝트 생성
    • 이름 : LocalTest00
  2. Asset 추가
    • JSON .NET For Unity : JSON 쉽게 쓰기 위한 것
  3. Scene 이름 변경
    • SampleScene ⇒ App
  4. App 오브젝트 및 스크립트 제작
    • 빈 오브젝트 생성 및 이름 변경 : App
    • Scripts 폴더를 만들고 그 안에 App 스크립트 제작
    • App 스크립트를 App 오브젝트에 부착
    • using System.Collections;
      using UnityEngine;
      using UnityEngine.UI;
      using UnityEngine.Networking;
      using Protocols;
      using Newtonsoft.Json;
      using System.Text;
      
      public class App : MonoBehaviour
      {
          // : Objects
          public Button BUTTON_Send;
          public InputField IFIELD_Name;
          public Text TEXT_Output;
      
          // : Status
          const string SERVER_HOST = "http://localhost:";
          const int SERVER_PORT = 3000;
      
          // Start is called before the first frame update
          void Start()
          {
              this.BUTTON_Send.onClick.AddListener(() =>
              {
                  // :: 객체 생성
                  string userName = IFIELD_Name.text;
                  Packets.find_req findRequest = new Packets.find_req(userName);
      
                  // :: 요청
                  this.StartCoroutine(this.RequestFind(findRequest));
              });
          }
      
          // : Request
          // :: IEnumerator 사용 이유 : SendWebRequest를 비동기 전송으로 하려고
          private IEnumerator RequestFind(Packets.find_req packet)
          {
              // :: 직렬화
              string json = JsonConvert.SerializeObject(packet);
      
              // :: 요청객체 생성
              string url = string.Format("{0}{1}", SERVER_HOST + SERVER_PORT, "/find");
              UnityWebRequest webRequest = new UnityWebRequest(url, "POST");
      
              // :: 바디
              var bodyRaw = Encoding.UTF8.GetBytes(json); // :: 한글 처리를 위해 UTF8 설정
      
              // :: 이벤트
              webRequest.uploadHandler = new UploadHandlerRaw(bodyRaw); // :: 이 부분 좀 더 이해 필요
              webRequest.downloadHandler = new DownloadHandlerBuffer(); // :: Response 받아오는 애 : 이해 필요
      
              // :: 헤더 설정
              webRequest.SetRequestHeader("Content-Type", "application/json"); // :: JSON이라고 알려줌
      
              // :: 비동기 전송
              yield return webRequest.SendWebRequest();
      
              // :: 응답 : 에러 처리
              if(webRequest.isNetworkError || webRequest.isHttpError)
              {
                  Debug.Log("www error");
              } else // :: 응답 : 결과 처리
              {
                  Debug.LogFormat("responseCode: {0}", webRequest.responseCode);
      
                  // :: 데이터 받기
                  byte[] resultRaw = webRequest.downloadHandler.data; // :: 왜인지 바이트로 전달함
                  string resultJSON = Encoding.UTF8.GetString(resultRaw); // :: 바이트를 문자열로 변경
                  
                  Debug.Log(resultJSON);
      
                  // :: 역직렬화 ⇒ find_req
                  Packets.find_res result = JsonConvert.DeserializeObject<Packets.find_res>(resultJSON);
      
                  // :: UI 출력
                  string userOutput = "";
                  foreach(Packets.info_userData data in result.userData)
                  {
                      userOutput += string.Format("이름 : {0}\n", data.userName);
                      userOutput += string.Format("이메일 : {0}\n", data.userEmail);
                      userOutput += string.Format("접속 시간 : {0}\n", data.userConnectedTime);
                  }
                  this.SetText_Output(userOutput);
              } 
          }
      
          // : Set
          private void SetText_Output(string text)
          {
              this.TEXT_Output.text = text;
          }
      }
      
  5. Protocols 스크립트 제작
    • Scripts 폴더에 Protocols 스크립트 제작
    • using System.Collections;
      using System.Collections.Generic;
      using UnityEngine;
      
      namespace Protocols
      {
          public class Packets
          {
              // : 직렬화
              // : 클라이언트 ⇒ 서버
              public class find_req
              {
                  public string userName;
                  public find_req(string userName)
                  {
                      this.userName = userName;
                  }
              }
      
              // : 역직렬화
              // : 서버 ⇒ 클라이언트
              public class find_res
              {
                  public List<info_userData> userData;
              }
      
              // : 역직렬화 대상
              public class info_userData
              {
                  public string userID;
                  public string userName;
                  public string userEmail;
                  public string userPassword;
                  public string userConnectedTime;
              }
          }
      }
  6. 전송 Button 생성
    1. 이름 : Button_Send
  7. 이름을 전송할 Input Field 생성
    1. 이름 : InputField_Name
  8. 정보가 나올 Text 생성
    1. 이름 : Text_Output
  9. Button, Input Field, Text를 App에 연결
  10. 테스트 결과 확인
  • 추가 테스트 : 좀 더 UI
블로그 이미지

RIsN

,