object pooling이라는 빈 게임오브젝트를 만든다. 
(pooling되는 오브젝트를 넣을 폴더를 만든다고 생각하면 된다.)

object pooling(미리 저장 꺼내 쓸 수 있도록 저장소) + 
singleton(다른 곳에서 호출하여 사용할 때 사용. 단순한 작업일 때는 static class를 사용할 수도 있음.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class ObjectPooling : MonoBehaviour {
 
    public static ObjectPooling instance = null;
 
    [Header("Object Pool")]
    public GameObject[] children;
    public int maxPool = 100;
    public List<GameObject> childPool = new List<GameObject>();
 
    // Use this for initialization
    void Awake () {
        if(instance == null)
        {
            instance = this;
        }
        else if(instance != this)
        {
            Destroy(this.gameObject);
        }
 
        DontDestroyOnLoad(this.gameObject);
 
        CreatePooling();
    }
    
    //오브젝트 풀에서 사용가능한 게임오브젝트 가져오는 함수 
    public GameObject GetChild()
    {
        for (int i = 0; i < childPool.Count; i++)
        {
            if(childPool[i].activeSelf == false)
            {
                return childPool[i];
            }
        }
        return null;
    }
 
    //오브젝트 풀에 게임오브젝트 생성하는 함수 
    public void CreatePooling()
    {
        gameObject.transform.SetParent(transform);
 
        for (int i = 0; i < maxPool; i++)
        {
            GameObject child = children[Random.Range(0, children.Length)];
 
            var obj = Instantiate<GameObject>(child, this.transform);
            obj.name = child + i.ToString("00");
 
            obj.SetActive(false);
            childPool.Add(obj);
        }
    }
}
 
cs


저장된 오브젝트를 가져와서 사용하는 코드

호출 후에 호출 값이 null이 아닌지를 확인하고 생성할 위치와 방향을 정해준 후에 활성화시켜준다.


1
2
3
4
5
6
7
8
//objectpoolng 스크립트를 호출하여 자식 생성 
            GameObject baby = ObjectPooling.instance.GetChild();
            if(baby != null)
            {
                baby.transform.position = this.position;
                baby.transform.rotation = this.rotation;
                baby.SetActive(true);
            }
cs


Posted by 도이(doi)
,

metaball

세포가 결합되고 분열되는 현실적인 느낌을 위해서 metaball을 사용해보고 싶었다.

생각보다 어려운 알고리즘을 사용함에 놀랐다. 


이 기능은 처음 분자 모델을 시뮬레이션하기 위해서 생겨났다고 한다.



개요

Marching Cubes는 체적 데이터의 등면을 렌더링하는 알고리즘입니다. 기본 개념은 입방체의 8 개 모서리에있는 픽셀 값으로 복셀 (입방체)을 정의 할 수 있다는 것입니다. 큐브의 하나 이상의 픽셀이 사용자 지정 등가 값보다 작은 값을 갖고 하나 이상의 값이이 값보다 큰 경우, 복셀이 등면의 일부 구성 요소에 기여해야한다는 것을 알 수 있습니다. 큐브의 어느 에지가 등면에 의해 교차되는지를 결정함으로써 등고선 내의 영역과 바깥 영역 사이의 큐브를 나누는 삼각형 패치를 생성 할 수 있습니다. 등고선 경계에있는 모든 큐브의 패치를 연결하여 표면 표현을 얻습니다.


솔직히 잘 이해할 수 없었다.

다만, 오늘 배운 것은 cube 입방체를 배열로 표현하는 것이었다.(입방체 정의하는 것까지 이해 + 16진수로 데이터 표기하는 것 배움.)


꼭짓점이 8개인 입방체는 8자리 수로 표현된다. 

(일반적으로 1부터 시작하는데 여기는 0부터 시작하더라...그래서 경우의 수가 128가지) ??왜그런지 질문

if (grid.val [0] <isolevel) cubeindex | = 1; if (grid.val [1] <isolevel) cubeindex | = 2; if (grid.val [2] <isolevel) cubeindex | = 4; if (grid.val [3] <isolevel) cubeindex | = 8; if (grid.val [4] <isolevel) cubeindex | = 16; if (grid.val [5] <isolevel) cubeindex | = 32; if (grid.val [6] <isolevel) cubeindex | = 64;

if (grid.val [7] <isolevel) cubeindex | = 128; 



76543210

ㅁㅁㅁㅁㅁㅁㅁㅁ

128 64 32 16 8 4 2 1


자릿수는 진수로 표현된다.(2에 0승, 2에 1승...)


이 각값을 꼭짓점으로 준다고 생각할 때


1000 | 0100

8번째 꼭짓점과 3번째 꼭짓점의 연결이라 생각하면 된다. => 선분(1-3)

오늘 공부한 다른 것은 


GetVertx, 

try catch(예외처리), 

anim random(재생위치 랜덤)


세 가지를 이용하여 구의 표면을 변형시키는 것이었다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
 
public class GetVertX3 : MonoBehaviour
{
    public GameObject[] someObjects;
    public Vector3 thePosition;
 
    List<GameObject> pin = new List<GameObject>();
 
    void Start()
    {
        MeshGenerator();
    }
 
    void MeshGenerator()
    {
        Mesh mesh = GetComponent<MeshFilter>().mesh;
        //점의 좌표를 가져옴 
        Vector3[] vertices = mesh.vertices;
 
        int v = 0;
 
        while (v < vertices.Length)
        {
            thePosition = transform.TransformPoint(vertices[v]);
            //vector3 방향 !
            Quaternion rot = Quaternion.LookRotation(transform.position - thePosition);
            //someObject는 랜덤하게 생성
            var someObject = someObjects[Random.Range(0, someObjects.Length)];
           //quad는 점의 위치에 중심을 바라보고 someObject를 생성시킨 gameObject
            GameObject quad = Instantiate(someObject, thePosition, rot);
            //새롭게 생성된 quad를 현재 gameObject에 차일드 시킴 (하위항목으로)
            quad.transform.SetParent(transform);
            //pin이라는 리스트에 quad 추가함 
            pin.Add(quad);
            v++;
        }
 
        foreach(GameObject tmp in pin)
        {
            try// 예외처리
            {
                //추가된 someobject인 quad가 pin의 리스트 그 pin 중 하나의 gameobject가 tmp 
                //여기에서 tmp의 하위항목을 가져오는 것은 someobject의 animation이 빈게임 오브젝트 
                //하위항목에 있기 때문 일반적인 경우에는 getchild를 할 필요 없음 
                Animation anim = tmp.transform.GetChild(0).GetComponent<Animation>();
 
                //anim길이 받아옴 
                float p = anim["anim"].length;
                //anim 길이까지 랜덤하게 키 생성
                float t = Random.Range(0, p);
                //anim 시간을 랜덤 키 위치에 생성 (시작키)
                anim["anim"].time = t;
                anim.Play();
            } catch{
                Debug.Log("no animation");
            }
        }
 
    }
}
cs



완성된 결과



reference
http://paulbourke.net/geometry/polygonise/

http://www.moon-sun.com/main/article/metaeffect/metaeffect.htm

Posted by 도이(doi)
,