UnityのRhinoceros Model内をFPS風に歩き回る

Rhinocerosで作成したモデルがUnity内で奇麗に見えるようになってきたので、その中をFPS風に歩きたいと思い、トライしてみました。参考にしたのは(もろパクですが)下の公式チュートリアルです。

この動画で使用しているプレイヤーキャラクターをそのままRhinocerosのモデルが入っているUnityファイルに持ってくるにはどうしたら良いかという事を考えました。このFirstPersonCharacterというのが別ファイルでも動けば成功です。

まず、試したのはFirstPersonCharacterのプレファブをそのままドラッグアンドドロップで、Rhinomodelファイルのプロジェクトウィンドウに落とし込んで使えないかという事です。やってみましたが、見事にありとあらゆるエラーが沢山出ました。これで気付いたことは、このPrefabは単独で機能しているのではなく、色々な他のファイルを参照しているという事です。

よって、次に試したのは、Prefabを含む上層のフォルダであるStandardAssetsフォルダごと別ファイルのプロジェクトウィンドウにコピーするということでした。(ネットワーク上で動かしたかったので予めPHOTONはインポートしてあります。)

コピーすると上記の通りにStandardAsset以下のフォルダが全てコピーされているのが確認できます。ゲームウィンドウで挙動を確認しようとすると、3つのエラーが出ました。

1つはUnityの現在のバージョンではサポートされいないWindowsWebPlayerという何かが使われているそうなので、その部分を削除しました。

	void RenderInterpolationTexture(Vector4 lightPos)
	{
		Graphics.SetRenderTarget(m_InterpolationEpi.colorBuffer, m_RaymarchedLightEpi.depthBuffer);
		if (!m_DX11Support && (Application.platform == RuntimePlatform.WindowsEditor || Application.platform == RuntimePlatform.WindowsPlayer || Application.platform == RuntimePlatform.WindowsWebPlayer))
		//この上の文の最後|| Application.platform == RuntimePlatform.WindowsWebPlayerが何やら問題であるそうなので削除しました。

{
			// Looks like in dx9 stencil is not cleared properly with GL.Clear()
			// Edit: fixed in 4.5, so this hack can be removed
			m_DepthBreaksMaterial.SetPass(1);
			RenderQuad();
		}
		else
		{
			GL.Clear(true, true, new Color(0, 0, 0, 1));
		}
		m_DepthBreaksMaterial.SetFloat("_InterpolationStep", m_InterpolationStep);
		m_DepthBreaksMaterial.SetFloat("_DepthThreshold", GetDepthThresholdAdjusted());
		m_DepthBreaksMaterial.SetTexture("_DepthEpi", m_DepthEpi);
		m_DepthBreaksMaterial.SetVector("_DepthEpiTexDim", new Vector4(m_DepthEpi.width, m_DepthEpi.height, 1.0f / m_DepthEpi.width, 1.0f / m_DepthEpi.height));
		m_DepthBreaksMaterial.SetPass(0);
		RenderQuadSections(lightPos);
	}

それから、残りの二つはParticleCollisionEventに関して、attachedRigidbodyというところが問題になっているという事だったので、恐らくはFPSで使用するFirstPersonCharacterに関係ないだろうと踏んで、それを含んでいるIF文ごと削除しました。

using UnityEngine;

namespace UnitySampleAssets.Effects
{
    public class WaterHoseParticles : MonoBehaviour
    {
        private ParticleCollisionEvent[] collisionEvents = new ParticleCollisionEvent[16];

        public static float lastSoundTime;
        public float force = 1;

        private void OnParticleCollision(GameObject other)
        {

            int safeLength = GetComponent<ParticleSystem>().GetSafeCollisionEventSize();

            if (collisionEvents.Length < safeLength)
            {
                collisionEvents = new ParticleCollisionEvent[safeLength];
            }

            int numCollisionEvents = GetComponent<ParticleSystem>().GetCollisionEvents(other, collisionEvents);
            int i = 0;

            while (i < numCollisionEvents)
            {

                if (Time.time > lastSoundTime + 0.2f)
                {
                    lastSoundTime = Time.time;
                }

                var col = collisionEvents[i].colliderComponent;

                if (col.attachedRigidbody != null)
                {
                    Vector3 vel = collisionEvents[i].velocity;
                    col.attachedRigidbody.AddForce(vel*force, ForceMode.Impulse);
                }

                //この上のattachedRigidbodyが問題になっているようなので、IF文ごとコメントアウト

                other.BroadcastMessage("Extinguish", SendMessageOptions.DontRequireReceiver);

                i++;
            }
        }
    }
}

読んでも何が書いてあるのかよくわからないのですが、FPSのキャラクターとは無関係に思えたので、少なくとも文法上正しい状態にして、エラーを回避することにしました。

3つ目のエラーは2番目の物と同様だったので、これだけで、すべてのエラーを回避できました。そして、結果、ゲームの中を動き回ることが出来るようになりました。

おすすめの記事