ほのぼのでべろっぷめんと

ゆる〜く興味があることについてやるだけのブログ

BlenderとUnityで現代のキリストを作った

本記事はFUN Advent Calender 2019の最終日の記事です。

昨日はおっとりさんの 約半月で-15kgしたのでダイエットについて語る でした

僕も一ヶ月グリーンスムージーで生活してみたいです。

この先センシティブな内容が含まれます。
キリスト教を信仰している方はこの記事を見ないでください。



 


12/25に生まれたとされるキリストの正体は、神でもあり、人間でもあるとされています。
神でもあり、人間でもある....
弊学にも同じような存在が居ますよね?

そう、僕です。

f:id:dalushimu2000:20191225022124j:plain


しかしこのままでは既に現代のキリストが誕生しているため、題意を満たすことができません。
なので磔にします。
キリストは一度死んで蘇るのです。

キリストの磔刑

f:id:dalushimu2000:20191225021049j:plain縁起でもないですが、御存知の通りイエスはエルサレム神殿を頂点とするユダヤ教体制を批判したため、死刑の権限のないユダヤ人の指導者たちによって、その権限のある支配者ローマ帝国へ反逆者として渡され、公開処刑死刑である十字架になって処刑されました。

では、再現します。

素体の用意

まずはどこにでもある自分の3Dモデルを用意します。

f:id:dalushimu2000:20191225020509p:plain

都合よくT Poseになってますね。

十字架の用意

f:id:dalushimu2000:20191225024029p:plain
Cubeを拡大縮小して十字架を作成します。


ボーンの調整

f:id:dalushimu2000:20191225025051p:plain


ボーンを調整して磔にします。


テクスチャはろう

無事に磔にできたのですが、これだと十字架に味がありません。
テクスチャを貼って木目を出しましょう

f:id:dalushimu2000:20191225031208p:plain

いい感じになりましたね

いい感じなのでUnityにimportします


import失敗

f:id:dalushimu2000:20191225032043p:plain
FBXでblenderから書き出したのですが設定をミスりました。

  • テクスチャが足りなかった
  • オブジェクトを選択し忘れた
  • アニメーションをimportし忘れた

f:id:dalushimu2000:20191225033305p:plain

 

設定を見直したので無事にimportできました


現世に降臨させる。

ARcoreを使って現世に降臨させます。
ARcoreをimportしてARController.csをサクッと書いてあげます

 using System.Collections.Generic;
    using GoogleARCore;
    using UnityEngine;
    using UnityEngine.Rendering;
    using UnityEngine.SceneManagement;


    public class ARController : MonoBehaviour
    {	

        public Camera FirstPersonCamera;

        public GameObject TrackedPlanePrefab;

        public GameObject GodPrefab;
        public GameObject SearchingForPlaneUI;
        private List<TrackedPlane> m_NewPlanes = new List<TrackedPlane>();
        private List<TrackedPlane> m_AllPlanes = new List<TrackedPlane>();
        private bool m_IsQuitting = false;

	
        public void Update()
        {
			int a = button.b;
            if (Input.GetKey(KeyCode.Escape))
            {
                Application.Quit();
            }

            _QuitOnConnectionErrors();

            if (Frame.TrackingState != TrackingState.Tracking)
            {
                const int lostTrackingSleepTimeout = 15;
                Screen.sleepTimeout = lostTrackingSleepTimeout;
                return;
            }

            Screen.sleepTimeout = SleepTimeout.NeverSleep;

            Frame.GetPlanes(m_NewPlanes, TrackableQueryFilter.New);
            for (int i = 0; i < m_NewPlanes.Count; i++)
            {
                GameObject planeObject = Instantiate(TrackedPlanePrefab, Vector3.zero, Quaternion.identity,
                    transform);
                planeObject.GetComponent<TrackedPlaneVisualizer>().Initialize(m_NewPlanes[i]);
            }

            Frame.GetPlanes(m_AllPlanes);
            bool showSearchingUI = true;
            for (int i = 0; i < m_AllPlanes.Count; i++)
            {
                if (m_AllPlanes[i].TrackingState == TrackingState.Tracking)
                {
                    showSearchingUI = false;
                    break;
                }
            }

            SearchingForPlaneUI.SetActive(showSearchingUI);

            Touch touch;
            if (Input.touchCount < 1 || (touch = Input.GetTouch(0)).phase != TouchPhase.Began)
            {
                return;
            }

            TrackableHit hit;
            TrackableHitFlags raycastFilter = TrackableHitFlags.PlaneWithinBounds | TrackableHitFlags.PlaneWithinPolygon;

            if (Session.Raycast(touch.position.x, touch.position.y, raycastFilter, out hit))
            {
				
				
		var god = Instantiate(GodPrefab, hit.Pose.position, hit.Pose.rotation);
				
                var anchor = hit.Trackable.CreateAnchor(hit.Pose);

               
                god.transform.LookAt(FirstPersonCamera.transform);
                god.transform.rotation = Quaternion.Euler(0.0f,
                god.transform.rotation.eulerAngles.y, god.transform.rotation.z);

                god.transform.parent = anchor.transform;
			

            }
        }

        private void _QuitOnConnectionErrors()
        {
            if (m_IsQuitting)
            {
                return;
            }

            if (Session.ConnectionState == SessionConnectionState.UserRejectedNeededPermission)
            {
                _ShowAndroidToastMessage("Camera permission is needed to run this application.");
                m_IsQuitting = true;
                Invoke("DoQuit", 0.5f);
            }
            else if (Session.ConnectionState == SessionConnectionState.ConnectToServiceFailed)
            {
                _ShowAndroidToastMessage("ARCore encountered a problem connecting.  Please start the app again.");
                m_IsQuitting = true;
                Invoke("DoQuit", 0.5f);
            }
        }

      
        private void DoQuit()
        {
            Application.Quit();
        }

        private void _ShowAndroidToastMessage(string message)
        {
            AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
            AndroidJavaObject unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

            if (unityActivity != null)
            {
                AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");
                unityActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
                {
                    AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", unityActivity,
                        message, 0);
                    toastObject.Call("show");
                }));
            }
        }
    }
}

 

GodPrefabに先程の十字架をアタッチしてあげれば...

f:id:dalushimu2000:20191225041140j:plain

上手に磔できました。



配布

僕一人だけがキリストを降臨させていても埒が明かないので配布します。

github.com

GithubのReleaseにapkファイルを置いておいたので
ARcoreの対応端末にinstallして使ってください

SNS等への投稿は許可しますが、常識の範囲内でお願いします。

<おわり>

無事にキリストを降臨させることができました。
次回は復活祭の時期にお会いしましょう。

Twitter

twitter.com


明日はnullさんのnullです!
undefinedについて書かれるそうなので楽しみです!

adventar.org

adventar.org