「毎日Unity」の技術ブログ

開発で役立つ情報を発信する

【UnityC#】カメラが壁を貫通しないようにする方法

カメラが壁にめり込まないようにする方法について記事を書きました。

[ 問題 ]

TPS視点のカメラを作ってると、下記のようにカメラがオブジェクトにめり込んでしまうんですよね...。
f:id:EDunity:20201029032838p:plain

[ 解決方法 ]

まず、プレイヤーとカメラを親子関係にする必要があります。下記の画像のように、プレイヤーが親オブジェクトで、カメラが子オブジェクトになるようにしてください。
f:id:EDunity:20201029133314p:plain
次に、「Player」というレイヤーを作成し、下記の画像ように親オブジェクトであるプレイヤーのレイヤーを作成した「Player」にしてください。
f:id:EDunity:20201029132357p:plain
最後に、下記のスクリプトを作成してカメラにアタッチすれば完了です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ScriptTest : MonoBehaviour
{
    private GameObject Parent;

    private Vector3 Position;

    private RaycastHit Hit;

    private float Distance;

    private int Mask;

    void Start()
    {
        Parent = transform.root.gameObject;

        Position = transform.localPosition;

        Distance = Vector3.Distance(Parent.transform.position, transform.position);

        Mask = ~(1 << LayerMask.NameToLayer("Player"));
    }

    void Update()
    {
        if(Physics.CheckSphere(Parent.transform.position, 0.3f, Mask))
        {
            transform.position = Vector3.Lerp(transform.position, Parent.transform.position, 1);
        }
        else if (Physics.SphereCast(Parent.transform.position, 0.3f, (transform.position - Parent.transform.position).normalized, out Hit, Distance, Mask))
        {
            transform.position = Parent.transform.position + (transform.position - Parent.transform.position).normalized * Hit.distance;
        }
        else
        {
            transform.localPosition = Vector3.Lerp(transform.localPosition, Position, 1);
        }
    }
}

[ 仕組み ]

青色がプレイヤー、赤色がカメラ、黄色がその他のオブジェクトを示しています。
壁や床等のその他のオブジェクトがカメラに接触していない時、カメラは下記の画像の状態になっています。
f:id:EDunity:20201029132434p:plain
その他のオブジェクトがカメラに接触すると、下記の画像のようにカメラはプレイヤーに近づくことでその他のオブジェクトへのめり込みを回避します。
その他のオブジェクトが接触しなくなると、上記の画像の状態に戻ります。
f:id:EDunity:20201029132442p:plain