유니티3D 프로그래밍
Unity NGUI 클릭 움직임 구현 (21.04.28) 본문
화면을 클릭해 클릭한 방향으로 움직이는 것을 구현한다.
현재 화면을 구성하는 오브젝트. 비활성화된 오브젝트는 현재 상황에 필요없는 UI들이다.
이 3가지 스크립트 중 Hero, Test가 움직임을 구현하는 스크립트다.
Hero 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hero : MonoBehaviour
{
public Transform hudGaugeTrans;
public GameObject gaugeGo;
public Animator anim;
public float speed = 2f;
private Coroutine routine;
private void Start()
{
this.anim.Play("idle");
}
void Update()
{
//https://www.tasharen.com/forum/index.php?topic=14754.0
//https://www.tasharen.com/ngui/docs/class_n_g_u_i_math.html
Vector3 overlay = NGUIMath.WorldToLocalPoint(this.hudGaugeTrans.position, Camera.main, UICamera.mainCamera, gaugeGo.transform);
overlay.z = 0.0f;
//Debug.Log(overlay);
gaugeGo.transform.localPosition = overlay;
}
public void Move(Vector3 tpos)
{
if (this.routine != null)
{
StopCoroutine(this.routine);
}
this.routine = StartCoroutine(this.MoveImpl(tpos));
}
private IEnumerator MoveImpl(Vector3 tpos)
{
this.anim.Play("run");
if (this.transform.position.x < tpos.x)
{
this.transform.localScale = Vector3.one;
}
else
{
this.transform.localScale = new Vector3(-1f, 1f, 1f);
}
while (true)
{
var dir = (tpos - this.transform.position).normalized;
this.transform.Translate(dir * speed * Time.deltaTime);
var distance = Vector3.Distance(tpos, this.transform.position);
if (distance <= 0.1f)
{
this.anim.Play("idle");
break;
}
yield return null;
}
}
}
overlay를 통해 Hp바의 위치가 Hero의 움직임을 따라간다. Coroutine을 이용하여 파라미터로 입력 받은 벡터 값으로 가야할 위치를 계산 후 움직인다.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject gaugeGo;
public Hero hero;
void Start()
{
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red, 1.0f);
var hit = Physics2D.Raycast(ray.origin, ray.direction, 1000);
Debug.Log(hit);
if (hit)
{
Debug.Log(hit.point);
this.hero.Move(hit.point);
}
}
}
}
마우스를 화면에 클릭하면 ray를 통해 그 위치를 받아오고 Raycast로 벡터 값을 구한 뒤 그 값을 Hero 스크립트가 있는 오브젝트로 그 값을 넘겨준다.
캐릭터 동적 생성
위의 내용을 바탕으로 캐릭터를 미리 만들어 둔 것이 아닌 Json파일을 통해 캐릭터의 특성을 정해두고 그 특성을 바탕으로 동적 생성을 한다.
동적 생성 전
동적 생성 후
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterData
{
public int id;
public string name;
public int max_hp;
public int damage;
public float move_speed;
public float attack_range;
public string prefab_name;
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hero : MonoBehaviour
{
//public Transform hudGaugeTrans;
//public Transform hudDamageTrans;
//public GameObject gaugeGo;
public Animator anim;
//public float speed = 2f;
private Coroutine routine;
private GameObject model;
private CharacterData data;
public void Init(GameObject model, CharacterData data)
{
this.data = data;
this.model = model;
this.anim = this.model.GetComponent<Animator>();
this.anim.Play("idle");
}
void Update()
{
//https://www.tasharen.com/forum/index.php?topic=14754.0
//https://www.tasharen.com/ngui/docs/class_n_g_u_i_math.html
//Vector3 overlay = NGUIMath.WorldToLocalPoint(this.hudGaugeTrans.position, Camera.main, UICamera.mainCamera, gaugeGo.transform);
//overlay.z = 0.0f;
//Debug.Log(overlay);
//gaugeGo.transform.localPosition = overlay;
}
public void Move(Vector3 tpos)
{
if (this.routine != null)
{
StopCoroutine(this.routine);
}
this.routine = StartCoroutine(this.MoveImpl(tpos));
}
private IEnumerator MoveImpl(Vector3 tpos)
{
this.anim.Play("run");
if (this.transform.position.x < tpos.x)
{
this.transform.localScale = Vector3.one;
}
else
{
this.transform.localScale = new Vector3(-1f, 1f, 1f);
}
while (true)
{
var dir = (tpos - this.transform.position).normalized;
this.transform.Translate(dir * this.data.move_speed * Time.deltaTime);
var distance = Vector3.Distance(tpos, this.transform.position);
if (distance <= 0.1f)
{
this.anim.Play("idle");
break;
}
yield return null;
}
}
}
using DG.Tweening;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class HudText : MonoBehaviour
{
public UILabel label;
public void Init(int damage)
{
this.label.text = damage.ToString();
var endpos = this.label.transform.position.y + 200;
float myFloat = 1f;
var color = this.label.color;
DOTween.To(() => myFloat, x => myFloat = x, 0f, 0.5f).onUpdate = () => {
color.a = myFloat;
this.label.color = color;
};
this.label.transform.DOScale(2, 0.2f).onComplete = () => {
this.label.transform.DOScale(1, 0.2f);
};
this.label.transform.DOLocalMoveY(endpos, 0.5f).SetEase(Ease.OutQuad).onComplete = () => {
Debug.Log("easing complete!");
Destroy(this.gameObject);
};
}
}
using Newtonsoft.Json;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Test : MonoBehaviour
{
public GameObject gaugeGo;
public Hero hero;
// public UIButton btn;
// public GameObject labelPrefab;
// public UIPanel panel;
//public GameObject labelGo;
private Dictionary<int, CharacterData> dicCharacterDatas;
private Dictionary<int, GameObject> dicPrefabs = new Dictionary<int, GameObject>();
void Start()
{
var json = Resources.Load<TextAsset>("hero_data").text;
this.dicCharacterDatas = JsonConvert.DeserializeObject<CharacterData[]>(json).ToDictionary(x => x.id);
foreach(var pair in this.dicCharacterDatas)
{
var go = Resources.Load<GameObject>(pair.Value.prefab_name);
this.dicPrefabs.Add(pair.Value.id, go);
}
this.CreateHero(100);
//this.btn.onClick.Add(new EventDelegate(() => {
// GameObject go = NGUITools.AddChild(this.panel.gameObject, labelPrefab);
// Vector3 overlay = NGUIMath.WorldToLocalPoint(
// this.hero.hudDamageTrans.position,
// Camera.main,
// UICamera.mainCamera,
// go.transform);
// overlay.z = 0.0f;
// go.transform.localPosition = overlay;
// var hud = go.GetComponent<HudText>();
// hud.Init(9999);
//}));
}
public void CreateHero(int id)
{
GameObject go = new GameObject();
var data = this.dicCharacterDatas[id];
go.name = data.prefab_name;
var model = Instantiate<GameObject>(this.dicPrefabs[id]);
model.transform.SetParent(go.transform);
model.name = "model";
this.hero = go.AddComponent<Hero>();
this.hero.Init(model, data);
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
Debug.DrawRay(ray.origin, ray.direction * 1000, Color.red, 1.0f);
var hit = Physics2D.Raycast(ray.origin, ray.direction, 1000);
Debug.Log(hit);
if (hit)
{
Debug.Log(hit.point);
this.hero.Move(hit.point);
}
}
}
}
'Unity > 수업내용' 카테고리의 다른 글
Unity Shader 연습 (21.05.03, 21.05.06~07) (0) | 2021.05.06 |
---|---|
Unity 간단한 게임 구현 (21.04.29~30) (0) | 2021.04.30 |
Unity UGUI 상점 창 구현 (21.04.23) (0) | 2021.04.23 |
Unity UGUI 미션 창 구현 (21.04.23) (0) | 2021.04.23 |
Unity UGUI Test 2 (21.04.20~21) (0) | 2021.04.20 |