본문 바로가기
가상세계 산사VR

가상현실 산사VR, 하우스 뿅! 스크립트

길을 가다가 바닥에 떨어진 물체의 버튼을 누르면 앞에 집이 짜잔 나타난다면?
가상현실 산사VR에서는 가능하지요 :)
비록 미니어쳐이긴 하지만요 ㅎ..

등장하는 이펙트 효과도 한번 주어 보았습니다.
이 이펙트 효과 만드느라 온 종일 걸렸네요 ㅎ.. 간단하게 봤다가 시행착오가 많아 생각보다 힘들었다는.

작동 영상입니다.

앞에 좀 알아야 할 선행지식들이 있어서 소스 설명은 어려울것 같고 그냥 소스내용만 공개합니다.
깊이 파실분 참조해 주세요 :)

using System;
using Sansar;
using Sansar.Script;
using Sansar.Simulation;
using System.Collections.Generic;
using System.Linq;

public class Cluster2Script : SceneObjectScript
{
    public ClusterResource EffectBox;  // 0.1x0.1  크기의 이펙트 효과내는 상자 오브젝트
    public ClusterResource RezObject;  // 생성할 최종 오브젝트
    public float RezX;  // 생성할 X, Y, Z 좌표 위치
    public float RezY;
    public float RezZ;
    public int countx;  // 효과상자 갯수 x, y, z
    public int county;
    public int countz;
    public double DelayTime = 1.0;
    
    public override void Init()
    {
        // 인터렉션 오브젝트 생성
        ObjectPrivate.AddInteractionData addData =
            (ObjectPrivate.AddInteractionData)WaitFor(
                ObjectPrivate.AddInteraction,
                "터치레즈", true);

        // 터치 이벤트
        addData.Interaction.Subscribe((InteractionData data) =>
        {
            Vector calc = new Vector();
            Vector zeroVec = new Vector(0, 0, 0);
            Quaternion zeroRot = Quaternion.FromEulerAngles(new Vector(0, 0, 0));

            // x, y, z  축으로 이펙트 오브젝트 생성
            for (int z = 0; z < countz;++z )
            {
                for (int x = 0; x < countx; ++x)                
                {
                    Wait(TimeSpan.FromSeconds(0.1));
                    for (int y = 0; y < county; ++y)
                    {
                        calc.X = RezX + (x - countx/2.0f) * 0.2f;
                        calc.Y = RezY + (y - county/2.0f) * 0.2f;
                        calc.Z = (RezZ + 0.2f) + z * 0.2f;

                        // 생성이 끝난 오브젝트마다 CreateClusterHandler 콜백 실행
                        ScenePrivate.CreateCluster(
                          EffectBox,
                          calc,
                          zeroRot,
                          zeroVec,
                          CreateClusterHandler
                        );
                    }
                }
            }

            // 최종 오브젝트 생성
            // 역시 끝나면 CreateClusterHandler2 콜백 실행
            calc.X = RezX;
            calc.Y = RezY;
            calc.Z = RezZ;
            ScenePrivate.CreateCluster(
                RezObject,
                calc,
                zeroRot,
                zeroVec,
                CreateClusterHandler2
            );
        });        
    }

    // 이펙트 오브젝트 콜백 함수
    private void CreateClusterHandler(
      bool Success, string Message, Cluster ClusterReference
    )
    {
        try
        {
            // 자신 오브젝트 제거함수 실행
            StartCoroutine(DestroyCluster, ClusterReference);
        }
        catch (Exception Ex)
        {
            ScenePrivate.Chat.MessageAllUsers("Error: " + Ex.Message);
        }
    }

    // 이펙트 오브젝트 삭제 콜백 함수
    private void DestroyCluster(Cluster ClusterReference)
    {
        // 오브젝트 정보를 얻고,
        ObjectPrivate ClusterObj = ClusterReference.GetObjectPrivate(0);
        MeshComponent meshComponent;
        ClusterObj.TryGetFirstComponent(out meshComponent);

        // 메터리얼 정보 취득
        IEnumerable<Sansar.Simulation.RenderMaterial> mats = meshComponent.GetRenderMaterials();
        Sansar.Simulation.RenderMaterial mat = mats.ElementAt(0);

        // Emissive 속성을 서서히 조정
        MaterialProperties p = mat.GetProperties();
        p.EmissiveIntensity = 6.0f;
        mat.SetProperties(p, 3.0f, InterpolationMode.Linear, (data1) =>
            {
                Wait(TimeSpan.FromSeconds(DelayTime));
                p.EmissiveIntensity = 0;
                mat.SetProperties(p, 3.0f, InterpolationMode.Linear, (data2) =>
                    {
                        // 끝나면 오브젝트 삭제
                        ClusterReference.Destroy(); // Delete the cluster from the scene
                    });
            });
    }

    // 메인 오브젝트 생성 콜백 함수
    private void CreateClusterHandler2(
      bool Success, string Message, Cluster ClusterReference
    )
    {
        // 오브젝트 정보 취득
        ObjectPrivate ClusterObj = ClusterReference.GetObjectPrivate(0);
        MeshComponent meshComponent;
        ClusterObj.TryGetFirstComponent(out meshComponent);

        // 메트리얼 정보 취득
        IEnumerable<Sansar.Simulation.RenderMaterial> mats = meshComponent.GetRenderMaterials();
        Sansar.Simulation.RenderMaterial mat = mats.ElementAt(0);

        // 밝기 조정
        MaterialProperties p = mat.GetProperties();
        p.EmissiveIntensity = 0.0f;
        Wait(TimeSpan.FromSeconds(DelayTime));
        mat.SetProperties(p, 6.0f, InterpolationMode.Linear, (data1) =>
        {
            
        });

        // 인터렉션 요소 생성
        ObjectPrivate.AddInteractionData addDataCluster =
            (ObjectPrivate.AddInteractionData)WaitFor(
                ClusterObj.AddInteraction,
                "", true);
        // 터치하면 오브젝트 삭제
        addDataCluster.Interaction.Subscribe((InteractionData data) =>
        {
            ClusterReference.Destroy();
        });
    }

}

효과에 사용된 X 무늬 큐브 오브젝트 모델 파일입니다.
그냥 산사에 업로드하면 빛이 나지는 않고 산사에서 뭔가 해주어야 하는데요, 추후 차분히 다루어보겠습니다.

cube_x.fbx
0.02MB

오늘도 방문해주셔서 감사합니다 :)

반응형