유닛으로 카메라와 피사체 사이의 차폐물을 숨기는 스크립트를 만들어 봤어요.
13691 단어 Unity
이러면 어떻게 움직이는지도 몰라요.
카메라와 피사체 사이에서 Update를 사용하여 Ray를 건너뛸 때마다 객체 레이어 객체의 렌더기가 유효하지 않게 처리됩니다.
아래 스크립트 구성 요소를 사용하면 위gif처럼 벽을 잠시 숨기고 벽의 깊은 곳을 표시할 수 있습니다.
더 좋은 방법이 있지만 나 같은 3D 초보자도 쉽게 쓸 수 있는 방법으로 Qita에 미리 적어두고 싶다.
동작 확인 환경
소스 코드
이 소스 코드github의 gist도 공개됐다.
SCCameraCoverTransparent.cs/// License
///
/// NYSL Version 0.9982
///
/// A. 本ソフトウェアは Everyone'sWare です。このソフトを手にした一人一人が、
/// ご自分の作ったものを扱うのと同じように、自由に利用することが出来ます。
///
/// A-1. フリーウェアです。作者からは使用料等を要求しません。
/// A-2. 有料無料や媒体の如何を問わず、自由に転載・再配布できます。
/// A-3. いかなる種類の 改変・他プログラムでの利用 を行っても構いません。
/// A-4. 変更したものや部分的に使用したものは、あなたのものになります。
/// 公開する場合は、あなたの名前の下で行って下さい。
///
/// B. このソフトを利用することによって生じた損害等について、作者は
/// 責任を負わないものとします。各自の責任においてご利用下さい。
///
/// C. 著作者人格権は SakuraCrowd に帰属します。著作権は放棄します。
///
/// D. 以上の3項は、ソース・実行バイナリの双方に適用されます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq; // Except
/// <summary>
/// カメラと対象との間の遮蔽物(Cover)を透明化します。
/// カメラに付加してください。
/// 透明にする遮蔽物は Renderer コンポーネントを付加している必要があります。
/// </summary>
public class SCCameraCoverTransparent : MonoBehaviour {
/// <summary>
/// 被写体を指定してください。
/// </summary>
[SerializeField]
private Transform subject_;
/// <summary>
/// 遮蔽物のレイヤー名のリスト。
/// </summary>
[SerializeField]
private List<string> coverLayerNameList_;
/// <summary>
/// 遮蔽物とするレイヤーマスク。
/// </summary>
private int layerMask_;
/// <summary>
/// 今回の Update で検出された遮蔽物の Renderer コンポーネント。
/// </summary>
public List<Renderer> rendererHitsList_ = new List<Renderer>();
/// <summary>
/// 前回の Update で検出された遮蔽物の Renderer コンポーネント。
/// 今回の Update で該当しない場合は、遮蔽物ではなくなったので Renderer コンポーネントを有効にする。
/// </summary>
public Renderer[] rendererHitsPrevs_;
// Use this for initialization
void Start () {
// 遮蔽物のレイヤーマスクを、レイヤー名のリストから合成する。
layerMask_ = 0;
foreach(string _layerName in coverLayerNameList_)
{
layerMask_ |= 1 << LayerMask.NameToLayer(_layerName);
}
}
// Update is called once per frame
void Update () {
// カメラと被写体を結ぶ ray を作成
Vector3 _difference = (subject_.transform.position - this.transform.position);
Vector3 _direction = _difference.normalized;
Ray _ray = new Ray(this.transform.position, _direction);
// 前回の結果を退避してから、Raycast して今回の遮蔽物のリストを取得する
RaycastHit[] _hits = Physics.RaycastAll(_ray, _difference.magnitude, layerMask_);
rendererHitsPrevs_ = rendererHitsList_.ToArray();
rendererHitsList_.Clear();
// 遮蔽物は一時的にすべて描画機能を無効にする。
foreach (RaycastHit _hit in _hits)
{
// 遮蔽物が被写体の場合は例外とする
if (_hit.collider.gameObject == subject_)
{
continue;
}
// 遮蔽物の Renderer コンポーネントを無効にする
Renderer _renderer = _hit.collider.gameObject.GetComponent<Renderer>();
if (_renderer != null)
{
rendererHitsList_.Add(_renderer);
_renderer.enabled = false;
}
}
// 前回まで対象で、今回対象でなくなったものは、表示を元に戻す。
foreach (Renderer _renderer in rendererHitsPrevs_.Except<Renderer>(rendererHitsList_))
{
// 遮蔽物でなくなった Renderer コンポーネントを有効にする
if (_renderer != null)
{
_renderer.enabled = true;
}
}
}
}
주요 처리는 업데이트입니다. 매번 다음과 같은 일을 반복합니다.
/// License
///
/// NYSL Version 0.9982
///
/// A. 本ソフトウェアは Everyone'sWare です。このソフトを手にした一人一人が、
/// ご自分の作ったものを扱うのと同じように、自由に利用することが出来ます。
///
/// A-1. フリーウェアです。作者からは使用料等を要求しません。
/// A-2. 有料無料や媒体の如何を問わず、自由に転載・再配布できます。
/// A-3. いかなる種類の 改変・他プログラムでの利用 を行っても構いません。
/// A-4. 変更したものや部分的に使用したものは、あなたのものになります。
/// 公開する場合は、あなたの名前の下で行って下さい。
///
/// B. このソフトを利用することによって生じた損害等について、作者は
/// 責任を負わないものとします。各自の責任においてご利用下さい。
///
/// C. 著作者人格権は SakuraCrowd に帰属します。著作権は放棄します。
///
/// D. 以上の3項は、ソース・実行バイナリの双方に適用されます。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Linq; // Except
/// <summary>
/// カメラと対象との間の遮蔽物(Cover)を透明化します。
/// カメラに付加してください。
/// 透明にする遮蔽物は Renderer コンポーネントを付加している必要があります。
/// </summary>
public class SCCameraCoverTransparent : MonoBehaviour {
/// <summary>
/// 被写体を指定してください。
/// </summary>
[SerializeField]
private Transform subject_;
/// <summary>
/// 遮蔽物のレイヤー名のリスト。
/// </summary>
[SerializeField]
private List<string> coverLayerNameList_;
/// <summary>
/// 遮蔽物とするレイヤーマスク。
/// </summary>
private int layerMask_;
/// <summary>
/// 今回の Update で検出された遮蔽物の Renderer コンポーネント。
/// </summary>
public List<Renderer> rendererHitsList_ = new List<Renderer>();
/// <summary>
/// 前回の Update で検出された遮蔽物の Renderer コンポーネント。
/// 今回の Update で該当しない場合は、遮蔽物ではなくなったので Renderer コンポーネントを有効にする。
/// </summary>
public Renderer[] rendererHitsPrevs_;
// Use this for initialization
void Start () {
// 遮蔽物のレイヤーマスクを、レイヤー名のリストから合成する。
layerMask_ = 0;
foreach(string _layerName in coverLayerNameList_)
{
layerMask_ |= 1 << LayerMask.NameToLayer(_layerName);
}
}
// Update is called once per frame
void Update () {
// カメラと被写体を結ぶ ray を作成
Vector3 _difference = (subject_.transform.position - this.transform.position);
Vector3 _direction = _difference.normalized;
Ray _ray = new Ray(this.transform.position, _direction);
// 前回の結果を退避してから、Raycast して今回の遮蔽物のリストを取得する
RaycastHit[] _hits = Physics.RaycastAll(_ray, _difference.magnitude, layerMask_);
rendererHitsPrevs_ = rendererHitsList_.ToArray();
rendererHitsList_.Clear();
// 遮蔽物は一時的にすべて描画機能を無効にする。
foreach (RaycastHit _hit in _hits)
{
// 遮蔽物が被写体の場合は例外とする
if (_hit.collider.gameObject == subject_)
{
continue;
}
// 遮蔽物の Renderer コンポーネントを無効にする
Renderer _renderer = _hit.collider.gameObject.GetComponent<Renderer>();
if (_renderer != null)
{
rendererHitsList_.Add(_renderer);
_renderer.enabled = false;
}
}
// 前回まで対象で、今回対象でなくなったものは、表示を元に戻す。
foreach (Renderer _renderer in rendererHitsPrevs_.Except<Renderer>(rendererHitsList_))
{
// 遮蔽物でなくなった Renderer コンポーネントを有効にする
if (_renderer != null)
{
_renderer.enabled = true;
}
}
}
}
사용법
Camera에 위의 스크립트 구성 요소를 추가합니다.
다음 항목을 설정합니다.
주의점
땅이 다 사라졌어!
예를 들어 플레인을 전체적인 지면으로 하고 지형이 융기되면 움푹 패인 구덩이에 들어갈 때 지면이 모두 숨겨진다.
대책으로 CoverLayer NameList에 등록된 도면층 이름과 일치하지 않는 도면층입니다.
보이기 싫은 벽이 나와!
밖으로 떨어지지 않기 위해 보이지 않는 벽을 만드는 건 좋은 일이라고 생각해요.아마
이 스크립트 구성 요소는 보이지 않으려는 벽이라도 차폐물이 아니기 때문에 표시할 수 있을 정도로 복원됩니다.
대책으로 아까와 마찬가지로 CoverLayersNameList입니다.변경합니다.
겸사겸사 말씀드리겠습니다.
이 스크립트는 유닛룸 씨가 진행한 이벤트 "ProBuilder 게임 잼"에 참가했을 때 만든 것이다.
이때 참가한 작품인'마을 속의 p.b.j.a.m'는 아래 링크부터 놀 수 있습니다.
화살표 키와 스페이스 바만 조작되며 게임 시간은 2~5분입니다.
가능하면 놀아주세요.
무료 게임 투고 사이트 유닛룸
해바라기 기능 사용 가능...
2018/07/25 추기.유니티 카메라는 해바라기 교육 기능이 있어서 이걸로 할 수 있을 것 같아요.
부탄가 교육 - Unity 브로셔
사이트 축소판 그림
이 스크립트는 유닛룸 씨가 진행한 이벤트 "ProBuilder 게임 잼"에 참가했을 때 만든 것이다.
이때 참가한 작품인'마을 속의 p.b.j.a.m'는 아래 링크부터 놀 수 있습니다.
화살표 키와 스페이스 바만 조작되며 게임 시간은 2~5분입니다.
가능하면 놀아주세요.
무료 게임 투고 사이트 유닛룸
해바라기 기능 사용 가능...
2018/07/25 추기.유니티 카메라는 해바라기 교육 기능이 있어서 이걸로 할 수 있을 것 같아요.
부탄가 교육 - Unity 브로셔
사이트 축소판 그림
Reference
이 문제에 관하여(유닛으로 카메라와 피사체 사이의 차폐물을 숨기는 스크립트를 만들어 봤어요.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/sakura-crowd/items/3608b2fd6df8a953240a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)