Sigma Project Number : 1

Game Name : Sigma : Summerfield / Run

Reference Game : Cookie Run

Start Date : 2020-12-11

 

==========

 

[Using Asset]

 

 

==========

 

youtu.be/C7cKV__zgP4

 

2020-12-14

  • Make to Lose when collide the zombie
    • Attatch colliders in Player and Zombies
    • Log lose status and Do animation die
  • Test & Fix something
    • Change zombie idle animation more dynamic
    • When player die, stop the moving tile maps

==========

Testing APK : Test Version 0.1 | Risnworlds on Patreon

블로그 이미지

RIsN

,

[Unity Tutorial] 3Dキャラクターにアニメーションを追加する

:Unityの3Dアセットは色々と良いものがありますがアニメーションがいない時があります、

:その時AdobeのMixamoを使ってAnimationを簡単に入れるのが可能です。

:これはその方法の記録です。

 

[使用したアセット]

 

=====

 

1. Unityのアセットを買ったら、プロジェクトに追加(Import)しましょう。

2. そうしたらプロジェクトに該当アセットが見れるはず、

>> その中でキャラクター(Character)モデルを探しましょう。

>> Synty StudioのアセットならModelsにCharacter.fbxがあります。 

3. まずそれをフォルダーウィンドウで確認してください。

4. さ、確認(.fbx)したなら、今回はAdobeのMixamoサイトに行きましょう。

>> [Mixamo]

>> Mixamoに到着したら、まずAdobeログインしてAnimationsを開けてください。

5. そうすると下記の通り見えます。

>> そこで右のUPLOAD CHARACTERを押して、

>> さっき確認したキャラクターをアップロードしてください。

6. それじゃ右にキャラが見えます。

>> その状況で左のアニメーションを選択するとキャラが動きます。

>> アニメーションが気に入ったなら右のDOWNLOADを押してください。

7. それじゃ下記の通りDOWNLOAD SETTINGS出ます。

>> ここで重要なものはSkinです。

>> 最初にダウンロードするアニメーションはキャラクターSkinと一緒にDOWNLOADしましょう。

>> 2回目のアニメーションからはwith Skinではなくても良いんです。

>> さ、DOWNLOADしましょう。

8. そしてそのダウンロードしたファイルをプロジェクトに入れてください。

9. 入れたファイルを今回はHierarchyに入れます。

10. Synty Studioの場合すべてのキャラが重なっています。

>> 必要ないキャラはOffしましょう。

11. そうするとキャラが見えますが、白く見えます。

>> Materialが別のものなのでこう見えます。

>> キャラに合ったMaterialを入れましょう。

>> Synty Studioの場合アセット名にMaterial01~04などになっています。

12. さ、アニメーションを入れましょう。

>> キャラにアニメーションを動くアニメーター(Animator)を追加してください。

 

13. 次はアニメーターに入れるAnimator Controllerを生成します。

14. 作ったAnimator ControllerはキャラのAnimatorに入れます。

15. まだAnimator Controllerには何もありません。

16. 今回はAnimator Controllerに入れるAnimationを作ります。

17. だがこれも開けても何もありません。

>> さっきMixamoからダウンロードしてプロジェクトに追加したファイルを開けるとmixamo.comと言うアニメーションがあります。

>> これを開けてください。

18. そのアニメーションを全部コピーします。

19. コピーしたら、さっき新しく作ったアニメーションを開けて貼り付けてください。

20. さ、アニメーションは完了です。

>> さっき作ったAnimator Controllerを開けてそのAnimationをドラグして入れます。

21. 参考ですが、このアニメーション(New Animation)のInspectorでLoop Timeをチェックするとループで動きます。

22. さ、実行してみましょう。

23. キャラが動いたら成功です!

 

 

==========

 

블로그 이미지

RIsN

,

Dogma / Coin

Project : D2

Game Name : Dogma / Coin

Version : 0.4

 

Goal : 10 Downloads

 

Engine : Unity 2019.4.15f1

Made : 2020-12-10

Release : 2020-12-13

[Download]

 

==========

 

What did I learn?

  • Program structure
  • Attach Spine2D in Unity
  • Talk system
  • DoTween
  • Attach Admob

What is the Dogma?

  • Dogma is Apocalypse story, and that world ruled by crabs.
  • There are mutants, but something different like ghouls.

==========

 

Thank you for Playing!

 

'_Dogma' 카테고리의 다른 글

Dogma / Coin Expansion 0.1 is decided  (0) 2021.03.14
D3 : 1 Page Plan  (0) 2020.10.27
블로그 이미지

RIsN

,

【공모전】 : LEGO x Unity Micro Game

【프로젝트명】 : Blockfall

  • Waterfall(폭포)와 비슷한 어감

【게임】 : 하러가기

 

【목표】 : 최우수상

【결과】 : 진행중

 

【간단 설명】 : 연동되어 떨어지는 블록을 넘어 닭을 구출

【컨셉】

  • 고전 레고
  • 구출 스토리
  • 최대한 자극적, 폭력적, 경쟁적이지 않을 것
  • 난이도 하 ⇒ 난이도 중

【레퍼런스 게임】 : 없음

 

【현 상황:2020-11-16】 : 완료

youtu.be/IV6Fteb04gE

 

【리미트 설정】

  1. 레고 스크립트의 수정 없음
  2. 타 에셋 사용 없음

【구현 설계】

  1. 2차원 [2][2] 블록 맵 작성 : 완료
  2. [0][0]을 스타트 지점으로 [1][1]을 트로피 지점으로 작성 : 완료
  3. PlayerPrefs에 현재 스테이지를 저장, 트로피를 얻으면 승리 화면 : 완료
    1. 기존 튜토리얼 Scene을 수정해서 사용 : 완료
  4. 승리 화면에서 NextStage 버튼을 누르면 현재 스테이지 +1 상승 후 다시 Main 씬 로드 : 완료
  5. 현재 스테이지에 맞춰서 2차원 블록 맵이 확장 : 완료
  6. 밟으면 블록이 떨어져 제거
    1. 밟은 블록 확인 : 완료
    2. (테스트) 밟은 블록 색깔 변화 : 완료
    3. 새로이 색깔 변화 스크립트를 만들어서 블록에 붙임 : 완료
    4. 블록이 떨어져 제거 : 완료
  7. 2개의 블록 링크 및 링크된 블록 색깔 변화 : 완료
  8. :: [BUG] : 스테이지 재 로드 시 블록이 분해되어 작동 안함 : 해결 완료
    1. 블록 스크립트를 만들어서 Prefab에 저장? or Touch 블록을 사용해서 스크립트 실행이 되나 확인? : 실패
    2. Prefab에 LEGO Behaviour Block을 붙임 : 성공
      1. 해결 과정 : Behaviour Block이 붙어있는 것은 재 로드시 분해되지 않는 결과가 있었기에 그것을 활용
  9. 스타트 블록과 마지막 블록을 제외하고 모든 블록 링크 : 완료
  10. 링크 블록 같이 떨어져 제거 : 완료
  11. 최종 스코어 저장 : 완료
  12. 실패 시 PlayerPrefs 초기화 및 첫 스테이지부터 시작 : 완료
    1. :: [방향 수정] 하드코어 스테이지 작성, 하드코어 스테이지 이상일 시 다시 하드코어 스테이지 처음으로 초기화 : 완료
  13. 난이도 조절
    1. Enemy Low : 완료
    2. Enemy Mid : 완료
    3. Stage 7 이후 대각선 제거 : 완료
    4. Enemy High : 완료
      1. 닿으면 플레이어를 부수는 레고 캐릭터(하자드) : 완료
    5. BOSS, 거대 보스, 3개의 트로피도 모두 획득하라? : 완료
      1. :: [방향 수정] 보스만 존재 : 난이도 중하 : 완료
  14. 프로젝트 정리 및 코드 정리 : 완료
    1. In Game의 Touch the object를 Touch & Save the Chicken으로 변경 : 완료
    2. 한글화 : 완료
  15. <I want Elsa Lego!!!>가 들어간 Credit 만들기 : 스킵
  16. 승리 / 패배 씬 작성 : 완료
    1. :: [컨셉] 친구 닭들을 구하는 기사
  17. 레고를 사용한 심플 이펙트 설치 : 완료
  18. 4.11f로 다운그레이드 : 완료
  19. BGM  : 완료
  20. QA : 완료
  21. 빌드 및 제출 : 완료

 

【스크립트 구조】

Scripts.zip
0.03MB

 

 

Dictator(총괄)
: 사라지지 않음, 중복 불가
: 씬의 이동과 초기화를 관리

[Scene]_Ruler
: 씬의 지배자
: 기본적인 움직임과 시나리오, 각 치프들은 룰러가 지배함

[Scene]_GOCheif
: 씬의 UI를 제외한 것들의 움직임을 관리하는 팀장
: 다만 움직임을 설정만 해서 룰러에게 제공할 뿐, 실제로 움직이는 것은 룰러의 일

[Scene]_GOHolder
: 씬의 UI를 제외한 것들의 GameObject를 보관하고 있는 홀더

[Scene]_UIChief
: 씬의 UI의 움직임을 관리하는 팀장
: GOChief랑 거의 하는 일은 같음

[Scene]_UIHolder
: 씬의 UI GameObject를 보관하는 홀더

// [그 외 스크립트]
: 각 독립 오브젝트들의 움직임을 관리 : 룰러의 지배를 받지 않음 : 효용성과 구조에 대한 고찰 필요

【해당 프로젝트로 학습한 사항】

  • 스크립트 구조에 대한 설계
    • 움직이는 관리자(치프)와 갖고 있는 홀더를 나누고, 그 관리자를 지배하는 시나리오 메이커(룰러)와 모든 씬을 총괄하는 총괄(딕테이터)을 놓아 두는 구조
    • 장점 : 어디서 문제가 생기는 지, 코드를 다시 보았을 때 구조에 대한 이해가 빠름
    • 현재 개선점 : 독립적인 부분 등에 대한 관리가 필요
  • 작성한 스크립트가 아닌 타 스크립트와의 연계
블로그 이미지

RIsN

,

::目標まで移動してヒットするのを作ってみよう。

:2020-10-28

 

youtu.be/-pV261uo324

>>たくさん、コメントを入れよう!(自分及び相手が理解しやすいように!)

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

public class App : MonoBehaviour
{
    // :: Variables
    List<GameObject> unitz;

    // Start is called before the first frame update
    void Start()
    {
        Debug.Log("Hello Start");

        // :: Initialise
        unitz = new List<GameObject>();

        // :: Load Resource
        var prefab = Resources.Load<GameObject>("Prefabs/ch_03_01");

        // :: Render and Set Position with prefab : Character A
        unitz.Add(Object.Instantiate(prefab));
        unitz[0].transform.position = new Vector3(0.5f, 0, 0);
        unitz[0].transform.eulerAngles = new Vector3(0, -90, 0);
        unitz[0].AddComponent<Hero>();

        // :: Render and Set Position with prefab : Character B
        unitz.Add(Object.Instantiate(prefab));
        unitz[1].transform.position = new Vector3(-0.5f, 0, 0);
        unitz[1].transform.eulerAngles = new Vector3(0, 90, 0);
        unitz[1].AddComponent<Hero>();

        // :: Initialise Button Continuous Attack
        Button btnContinuous = GameObject.Find("ButtonA").GetComponent<Button>();
        btnContinuous.onClick.AddListener(() =>
        {
            // :: Start Attack
            unitz[0].GetComponent<Hero>().StartAttack();
        });

        // :: Initialise Button Go target and attack
        Button btnAttack = GameObject.Find("ButtonB").GetComponent<Button>();
        btnAttack.onClick.AddListener(() =>
        {
            // :: Start Attack
            unitz[0].GetComponent<Hero>().GoTargetAndAttack(unitz[1]);
        });

        // :: Initialise Button Get Back
        Button btnGetBack = GameObject.Find("ButtonC").GetComponent<Button>();
        btnGetBack.onClick.AddListener(() =>
        {
            // :: Get Back Base Position
            unitz[0].GetComponent<Hero>().GetBack();
        });

    }

    // Update is called once per frame
    void Update()
    {
    }
}
using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hero : MonoBehaviour
{
    // Start is called before the first frame update
    Vector3 basePosition;
    void Start()
    {
        // :: Initialise
        deadlineAttackTime = new float[continuousAttack.Length];
        for (int i = 0; i < continuousAttack.Length; i++)
        {
            // :: Remember Deadline Length in variable
            Animation anim = this.gameObject.GetComponent<Animation>();
            deadlineAttackTime[i] = anim[continuousAttack[i]].length;
        }
        // :: Remember Base Position
        basePosition = this.gameObject.transform.position;
    }

    // :: Get Back position
    public void GetBack()
    {
        // :: Reset Position
        this.gameObject.transform.position = basePosition;

        // :: Reset Target
        target = null;
        isNearTheTarget = false;
    }
    
    // :: Start Continuous Attack
    public void StartAttack()
    {
        // :: Start Update
        checkContinuousAttack = true;

        // :: Initialise
        continuousIndex = 1;
        elapsedTime = 0;
        this.didHit = false;
    }

    // :: Go There
    bool checkGo = false; // :: Check Go
    GameObject target; // :: Target
    bool isNearTheTarget = false; // :: Is near the Target;

    // :: Go Target And Attack
    public void GoTargetAndAttack(GameObject target)
    {
        // :: Input Target
        this.target = target;

        // :: Go
        checkGo = true;

        // :: Run Loop
        this.gameObject.GetComponent<Animation>().Play("run@loop");
    }

    bool checkContinuousAttack = false; // :: Check Continuous Attack;
    bool didHit; // :: Check Hit
    private int continuousIndex; // :: Continuous Attack Index
    private float[] hitTimeForContinuousAttack = { 0f, 0.34f, 0.5f, 0.5f };
    private string[] continuousAttack = { "idle@loop", "attack_sword_01", "attack_sword_02", "attack_sword_03" }; // :: Continuous Attack List
    private float[] deadlineAttackTime; // :: Deadline Lengths
    private float elapsedTime; // :: Elapsed Time

    // Update is called once per frame
    void Update()
    {        // :: Check Continuous is True
        if (this.checkContinuousAttack)
        {
            // :: Play Animation
            this.gameObject.GetComponent<Animation>().Play(continuousAttack[continuousIndex]);
            // :: Elapsed Time
            elapsedTime += Time.deltaTime;
            Debug.Log(elapsedTime);

            // :: When Near the Target & hitTiming
            if(this.isNearTheTarget == true && elapsedTime >= hitTimeForContinuousAttack[continuousIndex] && this.didHit == false)
            {
                // :: When hitTime is Exist
                if(hitTimeForContinuousAttack[continuousIndex] > 0)
                {
                    Debug.LogFormat("Hit! : {0}", continuousIndex);
                    Debug.Log(hitTimeForContinuousAttack[continuousIndex]);

                    // :: Animation Reset
                    target.GetComponent<Animation>().Rewind();

                    // :: Hit Animation
                    target.GetComponent<Animation>().Play("damage");

                    // :: Reset didHit
                    this.didHit = true;
                }
            }

            // :: If elapsedTime is bigger than deadlineAttackTime
            if (elapsedTime >= deadlineAttackTime[continuousIndex])
            {
                // :: ElapsedTime Reset
                elapsedTime = 0;

                // :: Next Index
                continuousIndex += 1;

                // :: If Continuous Index is Out of Range
                if (continuousIndex >= continuousAttack.Length)
                {
                    // :: Continuous Index Reset : idle@loop
                    continuousIndex = 0;

                    // :: Don't more
                    checkContinuousAttack = false;
                }

                // :: Show Next Animation;
                this.gameObject.GetComponent<Animation>().Play(continuousAttack[continuousIndex]);

                // :: didHit Reset
                this.didHit = false;
            }
        }

        // ::: Check Going
        if(this.checkGo)
        {
            // :: Check Target Distance
            float distance = Vector3.Distance(this.gameObject.transform.position, this.target.transform.position);
            // ::: when distance is near
            if(distance <= 0.35f)
            {
                // ::: Stop and Attack;
                this.checkGo = false;
                this.StartAttack();
                this.isNearTheTarget = true;
            }
            // :: Move Toward
            this.transform.position = Vector3.MoveTowards(this.transform.position, this.target.transform.position, 0.1f * Time.deltaTime);
        }
    }
}

>> 2nd Version : Vector3.MoveTowardsを使わずにTranslateでやってみよう。 

using JetBrains.Annotations;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Hero : MonoBehaviour
{
    // Start is called before the first frame update
    Vector3 basePosition;
    void Start()
    {
        // :: Initialise
        deadlineAttackTime = new float[continuousAttack.Length];
        for (int i = 0; i < continuousAttack.Length; i++)
        {
            // :: Remember Deadline Length in variable
            Animation anim = this.gameObject.GetComponent<Animation>();
            deadlineAttackTime[i] = anim[continuousAttack[i]].length;
        }
        // :: Remember Base Position
        basePosition = this.gameObject.transform.position;
    }

    // :: Get Back position
    public void GetBack()
    {
        // :: Reset Position
        this.gameObject.transform.position = basePosition;

        // :: Reset Target
        target = null;
        isNearTheTarget = false;
    }
    
    // :: Start Continuous Attack
    public void StartAttack()
    {
        // :: Start Update
        checkContinuousAttack = true;

        // :: Initialise
        continuousIndex = 1;
        elapsedTime = 0;
        this.didHit = false;
    }

    // :: Go There
    bool checkGo = false; // :: Check Go
    GameObject target; // :: Target
    bool isNearTheTarget = false; // :: Is near the Target;

    // :: Go Target And Attack
    public void GoTargetAndAttack(GameObject target)
    {
        // :: Input Target
        this.target = target;

        // :: Look at Target
        this.transform.LookAt(target.transform);

        // :: Go
        checkGo = true;

        // :: Run Loop
        this.gameObject.GetComponent<Animation>().Play("run@loop");
    }

    bool checkContinuousAttack = false; // :: Check Continuous Attack;
    bool didHit; // :: Check Hit
    private int continuousIndex; // :: Continuous Attack Index
    private float[] hitTimeForContinuousAttack = { 0f, 0.34f, 0.5f, 0.5f };
    private string[] continuousAttack = { "idle@loop", "attack_sword_01", "attack_sword_02", "attack_sword_03" }; // :: Continuous Attack List
    private float[] deadlineAttackTime; // :: Deadline Lengths
    private float elapsedTime; // :: Elapsed Time

    // Update is called once per frame
    void Update()
    {        // :: Check Continuous is True
        if (this.checkContinuousAttack)
        {
            // :: Play Animation
            this.gameObject.GetComponent<Animation>().Play(continuousAttack[continuousIndex]);
            // :: Elapsed Time
            elapsedTime += Time.deltaTime;
            Debug.Log(elapsedTime);

            // :: When Near the Target & hitTiming
            if(this.isNearTheTarget == true && elapsedTime >= hitTimeForContinuousAttack[continuousIndex] && this.didHit == false)
            {
                // :: When hitTime is Exist
                if(hitTimeForContinuousAttack[continuousIndex] > 0)
                {
                    Debug.LogFormat("Hit! : {0}", continuousIndex);
                    Debug.Log(hitTimeForContinuousAttack[continuousIndex]);

                    // :: Animation Reset
                    target.GetComponent<Animation>().Rewind();

                    // :: Hit Animation
                    target.transform.LookAt(this.transform);
                    target.GetComponent<Animation>().Play("damage");

                    // :: Reset didHit
                    this.didHit = true;
                }
            }

            // :: If elapsedTime is bigger than deadlineAttackTime
            if (elapsedTime >= deadlineAttackTime[continuousIndex])
            {
                // :: ElapsedTime Reset
                elapsedTime = 0;

                // :: Next Index
                continuousIndex += 1;

                // :: If Continuous Index is Out of Range
                if (continuousIndex >= continuousAttack.Length)
                {
                    // :: Continuous Index Reset : idle@loop
                    continuousIndex = 0;

                    // :: Don't more
                    checkContinuousAttack = false;
                }

                // :: Show Next Animation;
                this.gameObject.GetComponent<Animation>().Play(continuousAttack[continuousIndex]);

                // :: didHit Reset
                this.didHit = false;
            }
        }

        // ::: Check Going
        if(this.checkGo)
        {
            // :: Check Target Distance
            float distance = Vector3.Distance(this.gameObject.transform.position, this.target.transform.position);
            Debug.Log(distance);
            // ::: when distance is near
            if(distance <= 0.35f)
            {
                // ::: Stop and Attack;
                this.checkGo = false;
                this.StartAttack();
                this.isNearTheTarget = true;
            }

            // :: Move There with Translate
            this.transform.Translate(this.transform.forward * 0.1f * Time.deltaTime, Space.World);

            // :: Move Toward
            //this.transform.position = Vector3.MoveTowards(this.transform.position, this.target.transform.position, 0.1f * Time.deltaTime);
        }
    }
}
블로그 이미지

RIsN

,

《文法》

【Nullじゃないなら実行】

// :: Callback
Callback_CompletedFX?.Invoke();
// :: Same the above
/*if (Callback_CompletedFX != null)
{
	Callback_CompletedFX();
}*/

《EASY to USE》

【EnumのDescriptionを取得して使用】

// :: Enums : Animation Key
private enum eAnimation
{
  [Description("idle@loop")]
  IDLE,
  [Description("run@loop")]
  RUN,
  [Description("walk@loop")]
  WALK
}

// :: for use enum Description
// ::: Ref : http://kawakawa2000.jugem.jp/?eid=27
// ::: I don't understand perfectly yet.
private string GetEnumDescription(eAnimation value)
{
	FieldInfo fi = value.GetType().GetField(value.ToString());
	var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

	var descriptionString = attributes.Select(ele => ele.Description).FirstOrDefault();

	if(descriptionString != null)
	{
		return descriptionString;
	}
	return value.ToString();
}

void Update() 
{
	anim.Play(this.GetEnumDescription(eAnimation.RUN));
}

【Unity Editorにツールを登録

// :: for Using
using UnityEditor;

// :: Easy to use
public class MenuTest : MonoBehaviour
{
    // :: Location
    [MenuItem("MyMenu/Delete All PlayerPrefs")]
    // :: Program : Delete All PlayerPrefs
    static void DeleteAllPlayerPrefs()
    {
        PlayerPrefs.DeleteAll();
        Debug.Log("deleted all player prefs");
    }
}

《イベント》

【ボタンにイベントリスナーを追加】

>>クリックすると動くように

// :: Add Event Listener
btn.onClick.AddListener(this.ClickedButton);

【数秒後に実行】
>>Singletonに定義してそれを持ってきて使うのも可能

<<CT_Ruler>>
// :: Do Action after Waiting
UIController.WaitForSecondsAndDo(10f, (() => { UIController.FadeIn(GOHolder.SPRITE_handRight); }));

<<Sing_UIController>>
// :: Do Action after Waiting
public void WaitForSecondsAndDo(float time, System.Action action)
{
	this.StartCoroutine(WaitForSecondsAndDoImplement(time, action));
}
private IEnumerator WaitForSecondsAndDoImplement(float time, System.Action action)
{
	yield return new WaitForSeconds(time);
	action();
}

【ゲーム停止】

// :: Pause Game
Time.timeScale = 0;
// :: RePlay Game
Time.timeScale = 1;

《出力》

【PrefabをベースにGameObjectの複製を作ってそれを画面に出力】

// :: Make GameObject & Render
GameObject prefab =  Resources.Load<GameObject>("ch_03_01");
GameObject clone =  Instantiate<GameObject>(prefab);

【出力する際に親(Parent)と位置を設定】

// :: Render Chest Closed and Set Position
// ::: Use Transform Parent
// ::: 1. GameObject
// ::: 2. Position
// ::: 3. Rotation
// ::: 4. Parent transform
chestClosed = Object.Instantiate<GameObject>(chestPrefabA, // 1
            lastTarget.transform.position + new Vector3(0, 0, 0.5f), // 2 
            Quaternion.Euler(-90, -90, 0), // 3
            lastTarget.transform); // 4

【出力してから親(Parent)を設定】

// :: Create Weapon and Set Parent
GameObject spear = Object.Instantiate<GameObject>(Resources.Load<GameObject>("Spear_7"));
spear.transform.SetParent(dummyRHand);
// :: Change Position
spear.transform.localPosition = new Vector3(0, 0, 0);
spear.transform.localRotation = Quaternion.Euler(new Vector3(0, 0, 0));

【画面にいるGameObjectの出力を消す】

// :: Destroy Game Object
Destroy(itm);

【3Dのキャラ位置に合わせて2DキャンバスにHUDを出力】

// :: When Button Clicked : Show HUD
this.BUTTON_test.onClick.AddListener(() =>
{
	// :: Instantiate with Canvas
	var go = Instantiate<GameObject>(this.hudPrefab, this.canvas.transform);

	// :: Check Where do you want set the position
	// ::: Main Camera World Point => Screen Point
	var screenPoint = Camera.main.WorldToScreenPoint(playerGO.transform.position);

	// ::: Screen Point => Local(Canvas) Point
	Vector2 localPoint;
	// ::: ((RectTransform) Canvas Transform, Screen Point, Camera which you will set HUD, out local Point)
	RectTransformUtility.ScreenPointToLocalPointInRectangle((RectTransform)canvas.transform, screenPoint, this.uiCam, out localPoint);

	// :: Change HUD Local position
	go.transform.localPosition = localPoint;

	// :: Play and Destroy
	var hud = go.GetComponent<HUDText>();
	hud.Init(992);
	hud.Play();
	hud.Callback_Play = () => {
		Destroy(hud.gameObject);
	};
});

《方向と移動》

【1歩前に動く:マップ基準】

// :: Map Position
hero.transform.position += Vector3.forward;
//this.gameObject.transform.Translate(Vector3.forward, Space.Self);

1歩前に動く:自分基準】

// :: Self Position
hero.transform.position += hero.transform.forward;
//this.gameObject.transform.Translate(this.transform.forward, Space.World);

【目標の方向を見るように角度を修正】

// :: Look target Direction
Vector3 target = new Vector3(1, 0.49f, -2) - itm.transform.position;
itm.transform.rotation = Quaternion.LookRotation(target);

【目標を見てその方向に走る(結果:目標を通って走る)】

// :: Look at Target
this.transform.LookAt(target.transform);
// :: Move There with Translate
this.transform.Translate(this.transform.forward * 0.1f * Time.deltaTime, Space.World);

⇒まだ完全に理解していない。

【目標まで行く】

// :: Move Toward 
this.transform.position = Vector3.MoveTowards(this.transform.position, this.target.transform.position, 0.1f * Time.deltaTime);

《衝突》

【衝突無視】

// :: Find all BoxCollider2D
foreach (var itm in GameObject.FindObjectsOfType<BoxCollider2D>())
{
	// :: Player : Ignore it
	Physics2D.IgnoreCollision(playerRigidbody.gameObject.GetComponent<CircleCollider2D>(), itm, true);
}

【RayCastで衝突感知】

// :: Hit Checker
RaycastHit hit;
// :: When Racast Hit
// ::: (Start Position, Direction, Hit Object, Max Distance)
if (Physics.Raycast(this.player.transform.position, this.player.transform.forward, out hit, 1f))
{
	// :: Check Hit Object's Name
	Debug.Log(hit.transform.gameObject.name);
	// :: Show ray for Debug
	Debug.DrawRay(this.player.transform.position, this.player.transform.forward * 1f, Color.red);
}

《SCENE移動》

【SCENE移動時に完了をチェック、そしてその後に何かを実行】

// :: Load Scene with Done Checker
UnityEngine.AsyncOperation async = SceneManager.LoadSceneAsync(this.GetEnumDescription(sceneType));
// :: When Scene Load Completed
async.completed += Async_completed;

// :: Do Action
private void Async_completed(UnityEngine.AsyncOperation obj)
{
	if(obj.isDone)
	{
    	Debug.Log("Load Completed");
	}
}

 

블로그 이미지

RIsN

,