[Unity] 2019-11-11 Study002 캐릭터의 이동, 애니메이션, grandchild 찾기
APP 2019. 11. 12. 08:46App에서
Charactetr0201, Character0301, Sword 게임오브젝트 생성.
Character0201의 grandchild 중 하나인 dummyRHand 게임오브젝트를 찾아서 Sword를 자식으로 설정.
Character0301의 dymmyRHand 게임오브젝트를 찾아서 Character0201이 가지고 있는 Sword를 옮김.
App.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Newtonsoft.Json;
public class App : MonoBehaviour
{
//private Dictionary<int, CharacterData> dicCharacterData;
//private Hero hero;
//private Monster monster;
GameObject character0201Prefab;
GameObject character0301Prefab;
GameObject swordPrefab;
// Start is called before the first frame update
private void Awake()
{
//this.dicCharacterData = new Dictionary<int, CharacterData>();
character0201Prefab = Resources.Load<GameObject>("Prefabs/ch_02_01");
character0301Prefab = Resources.Load<GameObject>("Prefabs/ch_03_01");
swordPrefab = Resources.Load<GameObject>("Prefabs/ch_sword_01");
}
private void Start()
{
//Character0201 생성
GameObject character0201Go = new GameObject("Character0201");
GameObject character0201Model = Instantiate(character0201Prefab);
character0201Model.transform.SetParent(character0201Go.transform, false);
//Sword 생성
GameObject swordGo = new GameObject("Sword");
GameObject swordModel = Instantiate(swordPrefab);
swordModel.transform.SetParent(swordGo.transform, false);
swordModel.transform.position = Vector3.zero;
GameObject aGo = Resources.Load<GameObject>("Prefabs/A");
var dummy = GameUtils.SearchHierarchyForBone(aGo.transform, "F");
//Character0201의 dummyRHand찾기
var dummyRHandOfCh0201 = TransformDeepChildExtension.FindDeepChild(character0201Go.transform, "DummyRHand");
//Debug.Log(dummyRHandOfCh0201);
//var dummy3 =GameUtils.SearchHierarchyForBone(character0201Go.transform, "DummyRHand");
//Debug.Log(dummy3);
//Sword의 부모로 Character0201의 dummyRHand 지정
swordGo.transform.SetParent(dummyRHandOfCh0201.transform, false);
//Character0301 생성
GameObject character0301Go = new GameObject("Character0301");
character0301Go.transform.position = new Vector3(2, 0, 0);
GameObject character0301Model = Instantiate(character0301Prefab);
character0301Model.transform.SetParent(character0301Go.transform, false);
//Character0301의 dummyRHand찾기
var dummyRHandOfCh0301 = TransformDeepChildExtension.FindDeepChild(character0301Go.transform, "DummyRHand");
//Debug.Log(dummyRHandOfCh0301);
//Sword의 부모로 Character0301의 dummyRHand 지정
swordGo.transform.SetParent(dummyRHandOfCh0301.transform, false);
//var cube = character0201Go.transform.FirstChildOrDefault(x => x.name == "ch_02_01(Clone)");
//Debug.Log(cube);
}
//재귀적으로 자식을 찾는 방법인데 동작에 오류가 있음
GameObject RecursiveFindChild(Transform parent, string childName)
{
foreach (Transform child in parent)
{
if (child.name == childName)
return child.gameObject;
else
return RecursiveFindChild(child, childName);
}
return null;
}
//public GameObject FindGrandChild(string name,GameObject go)
//{
// var findResult = go.transform.Find(name);
// if (findResult)
// {
// for(int i =0; i <go.transform.childCount; i)
// }
//}
/* 몬스터 & 히어로 Box모양 캐릭터 두개 생성 후 지정된 좌표로 움직이고 서로를 바라봄
//void Start()
//{
//string path = "Data/character_data";
//var json = Resources.Load<TextAsset>(path).text;
//Debug.Log(json);
//var arrCharacterDatas = JsonConvert.DeserializeObject<CharacterData[]>(json);
//foreach (CharacterData data in arrCharacterDatas)
//{
// dicCharacterData.Add(data.id, data);
//}
//var hero = CreateCharcter(200);
//hero.Init(Vector3.zero);
//this.hero = hero;
//var monster = CreateCharcter(100);
//monster.Init(new Vector3(2, 0, 0));
//this.monster = monster;
//var dist = Vector3.Distance(monster.transform.position, hero.transform.position);
//var normal = (monster.transform.position - hero.transform.position).normalized;
//Debug.Log(normal.magnitude);
//}
//public T CreateCharcter(int id) where T : Character
//{
//var data = this.dicCharacterData[id];
////캐릭터 객체의 생성
////Shell GameObject(해당 스크립트가)
//GameObject characterGo = new GameObject(data.name);
//var character = characterGo.AddComponent();
////Model
//var path = string.Format("Prefabs/{0}", data.prefab_name);
//var prefab = Resources.Load<GameObject>(path);
//var model = Instantiate(prefab);
////Data(정확히는 Info)
//CharacterInfo info = new CharacterInfo()
//{
// id = data.id,
// hp = data.hp
//};
//character.SetModel(model);
//character.SetInfo(info);
//return character;
//}
// Update is called once per frame
void Update()
{
//var speed = 1f;
//var heroEndPositon = new Vector3(3, 0, 5);
//hero.transform.position = Vector3.MoveTowards(hero.transform.position, heroEndPositon, speed*1.5f* Time.deltaTime);
//hero.transform.forward = heroEndPositon;
////hero의 위치가 최종위치가 아니면 달리는 모션으로 설정
//hero.transform.GetComponentInChildren().SetBool("Run Forward", hero.transform.position != heroEndPositon);
//if (hero.transform.position == heroEndPositon)
//{
// hero.transform.LookAt(monster.transform);
//}
//var monsterEndPosition = new Vector3(2, 0, 7);
//monster.transform.position = Vector3.MoveTowards(monster.transform.position, monsterEndPosition, speed*1* Time.deltaTime);
//monster.transform.forward = monsterEndPosition;
//monster.transform.GetComponentInChildren().SetBool("Walk Forward", monster.transform.position != monsterEndPosition);
//if(monster.transform.position == monsterEndPosition)
//{
// monster.transform.LookAt(hero.transform);
//}
}
*/
}
Character.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Character : MonoBehaviour
{
private GameObject model;
private CharacterInfo info;
// Start is called before the first frame update
void Start()
{
}
public void Init(Vector3 pos)
{
this.transform.position = pos;
}
public void SetModel(GameObject model)
{
this.model = model;
this.model.name = "model";
var oldModel = this.transform.Find("model");
if (oldModel != null)
{
Destroy(oldModel.gameObject);
}
this.model.transform.SetParent(this.transform, false);
this.model.transform.localPosition = Vector3.zero;
}
public void SetInfo(CharacterInfo info)
{
this.info = info;
}
// Update is called once per frame
void Update()
{
}
}
CharcterData.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterData
{
public int id;
public string name;
public int hp;
public int damage;
public float attack_range;
public string prefab_name;
}
CharacterInfo.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharacterInfo
{
public int id;
public int hp;
}
Hero.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Hero : Character
{
// Start is called before the first frame update
void Start()
{
}
}
Monster.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Monster : Character
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}
grandchild를 찾는 API No.1
GameUtils.cs
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public static class GameUtils
{
//HOW TO USE
//var cube = this.transform.FirstChildOrDefault(x => x.name == "deeply_nested_cube");
public static Transform FirstChildOrDefault(this Transform parent, Func<Transform, bool> query)
{
if (parent.childCount == 0)
{
return null;
}
Transform result = null;
for (int i = 0; i < parent.childCount; i++)
{
var child = parent.GetChild(i);
if (query(child))
{
return child;
}
result = FirstChildOrDefault(child, query);
}
return result;
}
public static Transform SearchHierarchyForBone(Transform current, string name)
{
//sb.Append(current.name + "\n");
// check if the current bone is the bone we're looking for, if so return it
if (current.name == name)
return current;
// search through child bones for the bone we're looking for
for (int i = 0; i < current.childCount; ++i)
{
// the recursive step; repeat the search one step deeper in the hierarchy
var child = current.GetChild(i);
Transform found = SearchHierarchyForBone(child, name);
// a transform was returned by the search above that is not null,
// it must be the bone we're looking for
if (found != null)
return found;
}
// bone with name was not found
return null;
}
}
grandchild를 찾는 API No.2
TraTransformDeepChildExtension.cs
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public static class TransformDeepChildExtension
{
//Breadth-first search
public static Transform FindDeepChild(this Transform aParent, string aName)
{
Queue<Transform> queue = new Queue<Transform>();
queue.Enqueue(aParent);
while (queue.Count > 0)
{
var c = queue.Dequeue();
if (c.name == aName)
return c;
foreach (Transform t in c)
queue.Enqueue(t);
}
return null;
}
}
/*로 주석처리된 몬스터 & 히어로 부분 실행결과
App의 멤버변수 dicCharacterData, hero, monster 도 주석처리 해제 하고,
Awake 메서드의 this.dicCharacterData = new Dictionary<int, CharacterData>(); 도 주석처리 해제해야함
'APP' 카테고리의 다른 글
[Unity] 코루틴으로 이동하는것 해볼것 (0) | 2019.11.13 |
---|---|
[Unity] 2019-11-13 Study_002 역직렬화(캐릭터,웨폰) 인게임(캐릭터,웨폰 생성) (0) | 2019.11.13 |
[Unity] 화살표 그리기 3종류 (0) | 2019.11.07 |
[Unity] Study_002 (0) | 2019.11.05 |
[Unity] Study_001 (0) | 2019.11.05 |