Unity Material에 Multiple Sprite를 설정하고 싶어요!
7542 단어 Unity
묘사 부하를 줄이기 위해 스prite를 TexturePacker 등으로 모으면 내용을 직접 설정할 수 없습니다.UGUI라면 Image에 설치하면 해결되지만, Partical의 Material로 사용하려면 이게 번거롭습니다.
유니티 표준 팩킹 태그도 있지만 팩킹 후 이미지를 압축하고 최적화하는 등 가공하려고 할 때 힘들겠죠?
그래서 방법을 생각해 봤어요.
우선 Multiple Sprite를 Material에 설정해 보세요.
유닛 스피릿 참고서 한번 볼게요.
https://docs.unity3d.com/ja/current/ScriptReference/Sprite.html
rect와texture를 참조할 수 있습니다.
Material에 Sprite를 설정하면 texture로 처리되며 이texture를 설정하세요.
rect에는 이미지의 X 위치, 이미지의 Y 위치, X 크기, Y 크기 매개변수가 저장됩니다.
Texture는 width와 Height를 통해 그림 크기를 얻을 수 있습니다.
https://docs.unity3d.com/ja/current/ScriptReference/Texture.html
이런 느낌으로 Texture에서 Sprite를 줄일 수 있을 것 같아요.OffsetX = Sprite.rect.x/Sprite.texture.width
OffsetY = Sprite.rect.y/Sprite.texture.height
TilingX = Sprite.rect.width/Sprite.texture.width
TilingY = Sprite.rect.height/Sprite.texture.height
그럼 실제로 해보세요
· Shader의 실장 Partical Addive 사용
MultipleParticleAddtive.shaderShader "Unlit/MultipleParticleAddtive" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_MainTex ("Particle Texture", 2D) = "white" {}
_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
}
FallBack "Particles/Additive"
CustomEditor "MultipleParticleAddtiveView"
}
· Material의 Editor 확장
MultipleParticleAddtiveView.csusing UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEngine.UI;
using System.Linq;
public class MultipleParticleAddtiveView : MaterialEditor
{
[SerializeField]
Material material
{
get { return (Material)target; }
}
private Sprite _sprite;
public override void OnEnable()
{
//テクスチャ情報を確認
RestoreSprite();
base.OnEnable();
}
public override void OnInspectorGUI()
{
if (isVisible == false) { return; }
// 入力内容が変更されたかチェック
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("MultipleSpriteをMaterialにセットします");
_sprite = EditorGUILayout.ObjectField(_sprite,typeof(Sprite),true) as Sprite;
if (GUILayout.Button("SetTexture"))
{
var _rectSprite = SpriteToTextureRect(_sprite);
material.SetTexture("_MainTex", _sprite.texture);
material.SetTextureOffset("_MainTex", new Vector2(_rectSprite.x, _rectSprite.y));
material.SetTextureScale("_MainTex", new Vector2(_rectSprite.width, _rectSprite.height));
}
if (GUILayout.Button("ResetParam"))
{
material.SetTextureOffset("_MainTex", new Vector2(0f,0f));
material.SetTextureScale("_MainTex", new Vector2(1f,1f));
}
EditorGUILayout.EndVertical();
GUILayout.Space(20);
EditorGUILayout.BeginVertical(GUI.skin.box);
base.OnInspectorGUI();
EditorGUILayout.EndVertical();
}
/// <summary>
/// MainTexとOffset、ScaleからセットされているSpriteを見つけます
/// </summary>
private void RestoreSprite()
{
//今 Materialにセットされている画像を所得
var _setTexObject = material.mainTexture;
Rect _setTexRect = TexRect(material, _setTexObject);
//画像のInstanceIDを所得
var _texObjectID = AssetDatabase.GetAssetPath(_setTexObject.GetInstanceID());
//InstanceIDからMultipleSpriteかどうかを判定 nullなら単体のSpriteか普通の画像
Sprite[] _setSprites = AssetDatabase.LoadAllAssetsAtPath(_texObjectID).OfType<Sprite>().ToArray();
//Spriteではないということで何も処理しない 通常Textureです
if (_setSprites == null) return;
if (_setSprites.Length > 1)
{
for (var i = 0; i < _setSprites.Length; i++)
{
if (_setTexRect == _setSprites[i].rect)
{
_sprite = _setSprites[i];
}
}
}
else
{
//MultipleSpriteではないただのSpriteです
_sprite = _setSprites[0];
}
}
/// <summary>
/// OffsetとScaleからRectを生成します
/// </summary>
/// <param name="_mat">material</param>
/// <param name="_tex">texture</param>
/// <returns></returns>
private Rect TexRect(Material _mat,Texture _tex)
{
Vector2 _offset = _mat.GetTextureOffset("_MainTex");
Vector2 _Scale = _mat.GetTextureScale("_MainTex");
return new Rect(
_offset.x * _tex.width,
_offset.y * _tex.height,
_Scale.x * _tex.width,
_Scale.y * _tex.height);
}
/// <summary>
/// SpriteのRectからTextureのOffsetとScaleを生成します
/// </summary>
/// <param name="_sp">Sprite</param>
/// <returns></returns>
private Rect SpriteToTextureRect(Sprite _sp)
{
var offset_x = _sprite.rect.x / _sprite.texture.width;
var offset_y = _sprite.rect.y / _sprite.texture.height;
var tiling_x = _sprite.rect.width / _sprite.texture.width;
var tiling_y = _sprite.rect.height / _sprite.texture.height;
return new Rect(offset_x,offset_y,tiling_x,tiling_y);
}
}
설명
/SetTexture 버튼을 사용하여 Sprite 를 설정합니다.
· ResetParam 버튼, Reset에서 설정한 Tiling 및 Offset
Multiple이 아닌 Sprite와 텍스쳐는Particle Texture에 직접 설정할 수 있습니다.
메이터리얼 제작
· 설정
・MultipleSprite 설정
· 일반적인 Texture 설정
힘든 곳
RestoreSprite()에서 여기(↓)는 힘들었어요. //画像のInstanceIDを所得
var _texObjectID = AssetDatabase.GetAssetPath(_setTexObject.GetInstanceID());
//InstanceIDからMultipleSpriteかどうかを判定 nullなら単体のSpriteか普通の画像
Sprite[] _setSprites = AssetDatabase.LoadAllAssetsAtPath(_texObjectID).OfType<Sprite>().ToArray();
Editor 확장 설정의 값을 유지하지 않으면 Material의 Inspector를 닫을 때(MultipleSprite) 정보가 손실됩니다.
이번에는 머티리얼즈, 세리라이즈의 target은 머티리얼즈가 유지한다.
"Multiple Sprite 설정은 무엇입니까?"이런 Sprite 형식의 Object는 Material에 저장되지 않았습니다.
또 새로 제작된 스크립트테이블 Object 때는 이곳이 독특한 Object가 되지 않았기 때문에 이를 사용한 확장된 모든 머티리얼즈가 정보를 공유한다.
그 결과 멀티플렉스 스프릿을 유지하는 정보를 포기하고 머티리얼에 설정된 Texture에서 인스타그램 ID를 얻었고, Asse Database를 통해 이 인스타그램 ID를 유지하는 Object에 스프릿형ary가 있는지 확인하고 멀티플렉스 스프릿이 있는지 판단과 멀티플렉스 스프릿의 정보 복원을 결정했다.
이 더 좋은 방법을 아는 사람이 있다면 알려주세요.
사이트 축소판 그림
Reference
이 문제에 관하여(Unity Material에 Multiple Sprite를 설정하고 싶어요!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/chikanobuitoh/items/0921bfaee7ba5c7823a7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
OffsetX = Sprite.rect.x/Sprite.texture.width
OffsetY = Sprite.rect.y/Sprite.texture.height
TilingX = Sprite.rect.width/Sprite.texture.width
TilingY = Sprite.rect.height/Sprite.texture.height
· Shader의 실장 Partical Addive 사용
MultipleParticleAddtive.shader
Shader "Unlit/MultipleParticleAddtive" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_MainTex ("Particle Texture", 2D) = "white" {}
_InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0
}
FallBack "Particles/Additive"
CustomEditor "MultipleParticleAddtiveView"
}
· Material의 Editor 확장MultipleParticleAddtiveView.cs
using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEngine.UI;
using System.Linq;
public class MultipleParticleAddtiveView : MaterialEditor
{
[SerializeField]
Material material
{
get { return (Material)target; }
}
private Sprite _sprite;
public override void OnEnable()
{
//テクスチャ情報を確認
RestoreSprite();
base.OnEnable();
}
public override void OnInspectorGUI()
{
if (isVisible == false) { return; }
// 入力内容が変更されたかチェック
EditorGUI.BeginChangeCheck();
EditorGUILayout.BeginVertical(GUI.skin.box);
EditorGUILayout.LabelField("MultipleSpriteをMaterialにセットします");
_sprite = EditorGUILayout.ObjectField(_sprite,typeof(Sprite),true) as Sprite;
if (GUILayout.Button("SetTexture"))
{
var _rectSprite = SpriteToTextureRect(_sprite);
material.SetTexture("_MainTex", _sprite.texture);
material.SetTextureOffset("_MainTex", new Vector2(_rectSprite.x, _rectSprite.y));
material.SetTextureScale("_MainTex", new Vector2(_rectSprite.width, _rectSprite.height));
}
if (GUILayout.Button("ResetParam"))
{
material.SetTextureOffset("_MainTex", new Vector2(0f,0f));
material.SetTextureScale("_MainTex", new Vector2(1f,1f));
}
EditorGUILayout.EndVertical();
GUILayout.Space(20);
EditorGUILayout.BeginVertical(GUI.skin.box);
base.OnInspectorGUI();
EditorGUILayout.EndVertical();
}
/// <summary>
/// MainTexとOffset、ScaleからセットされているSpriteを見つけます
/// </summary>
private void RestoreSprite()
{
//今 Materialにセットされている画像を所得
var _setTexObject = material.mainTexture;
Rect _setTexRect = TexRect(material, _setTexObject);
//画像のInstanceIDを所得
var _texObjectID = AssetDatabase.GetAssetPath(_setTexObject.GetInstanceID());
//InstanceIDからMultipleSpriteかどうかを判定 nullなら単体のSpriteか普通の画像
Sprite[] _setSprites = AssetDatabase.LoadAllAssetsAtPath(_texObjectID).OfType<Sprite>().ToArray();
//Spriteではないということで何も処理しない 通常Textureです
if (_setSprites == null) return;
if (_setSprites.Length > 1)
{
for (var i = 0; i < _setSprites.Length; i++)
{
if (_setTexRect == _setSprites[i].rect)
{
_sprite = _setSprites[i];
}
}
}
else
{
//MultipleSpriteではないただのSpriteです
_sprite = _setSprites[0];
}
}
/// <summary>
/// OffsetとScaleからRectを生成します
/// </summary>
/// <param name="_mat">material</param>
/// <param name="_tex">texture</param>
/// <returns></returns>
private Rect TexRect(Material _mat,Texture _tex)
{
Vector2 _offset = _mat.GetTextureOffset("_MainTex");
Vector2 _Scale = _mat.GetTextureScale("_MainTex");
return new Rect(
_offset.x * _tex.width,
_offset.y * _tex.height,
_Scale.x * _tex.width,
_Scale.y * _tex.height);
}
/// <summary>
/// SpriteのRectからTextureのOffsetとScaleを生成します
/// </summary>
/// <param name="_sp">Sprite</param>
/// <returns></returns>
private Rect SpriteToTextureRect(Sprite _sp)
{
var offset_x = _sprite.rect.x / _sprite.texture.width;
var offset_y = _sprite.rect.y / _sprite.texture.height;
var tiling_x = _sprite.rect.width / _sprite.texture.width;
var tiling_y = _sprite.rect.height / _sprite.texture.height;
return new Rect(offset_x,offset_y,tiling_x,tiling_y);
}
}
설명
/SetTexture 버튼을 사용하여 Sprite 를 설정합니다.
· ResetParam 버튼, Reset에서 설정한 Tiling 및 Offset
Multiple이 아닌 Sprite와 텍스쳐는Particle Texture에 직접 설정할 수 있습니다.
메이터리얼 제작
· 설정
・MultipleSprite 설정
· 일반적인 Texture 설정
힘든 곳
RestoreSprite()에서 여기(↓)는 힘들었어요. //画像のInstanceIDを所得
var _texObjectID = AssetDatabase.GetAssetPath(_setTexObject.GetInstanceID());
//InstanceIDからMultipleSpriteかどうかを判定 nullなら単体のSpriteか普通の画像
Sprite[] _setSprites = AssetDatabase.LoadAllAssetsAtPath(_texObjectID).OfType<Sprite>().ToArray();
Editor 확장 설정의 값을 유지하지 않으면 Material의 Inspector를 닫을 때(MultipleSprite) 정보가 손실됩니다.
이번에는 머티리얼즈, 세리라이즈의 target은 머티리얼즈가 유지한다.
"Multiple Sprite 설정은 무엇입니까?"이런 Sprite 형식의 Object는 Material에 저장되지 않았습니다.
또 새로 제작된 스크립트테이블 Object 때는 이곳이 독특한 Object가 되지 않았기 때문에 이를 사용한 확장된 모든 머티리얼즈가 정보를 공유한다.
그 결과 멀티플렉스 스프릿을 유지하는 정보를 포기하고 머티리얼에 설정된 Texture에서 인스타그램 ID를 얻었고, Asse Database를 통해 이 인스타그램 ID를 유지하는 Object에 스프릿형ary가 있는지 확인하고 멀티플렉스 스프릿이 있는지 판단과 멀티플렉스 스프릿의 정보 복원을 결정했다.
이 더 좋은 방법을 아는 사람이 있다면 알려주세요.
사이트 축소판 그림
Reference
이 문제에 관하여(Unity Material에 Multiple Sprite를 설정하고 싶어요!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/chikanobuitoh/items/0921bfaee7ba5c7823a7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
RestoreSprite()에서 여기(↓)는 힘들었어요.
//画像のInstanceIDを所得
var _texObjectID = AssetDatabase.GetAssetPath(_setTexObject.GetInstanceID());
//InstanceIDからMultipleSpriteかどうかを判定 nullなら単体のSpriteか普通の画像
Sprite[] _setSprites = AssetDatabase.LoadAllAssetsAtPath(_texObjectID).OfType<Sprite>().ToArray();
Editor 확장 설정의 값을 유지하지 않으면 Material의 Inspector를 닫을 때(MultipleSprite) 정보가 손실됩니다.이번에는 머티리얼즈, 세리라이즈의 target은 머티리얼즈가 유지한다.
"Multiple Sprite 설정은 무엇입니까?"이런 Sprite 형식의 Object는 Material에 저장되지 않았습니다.
또 새로 제작된 스크립트테이블 Object 때는 이곳이 독특한 Object가 되지 않았기 때문에 이를 사용한 확장된 모든 머티리얼즈가 정보를 공유한다.
그 결과 멀티플렉스 스프릿을 유지하는 정보를 포기하고 머티리얼에 설정된 Texture에서 인스타그램 ID를 얻었고, Asse Database를 통해 이 인스타그램 ID를 유지하는 Object에 스프릿형ary가 있는지 확인하고 멀티플렉스 스프릿이 있는지 판단과 멀티플렉스 스프릿의 정보 복원을 결정했다.
이 더 좋은 방법을 아는 사람이 있다면 알려주세요.
사이트 축소판 그림
Reference
이 문제에 관하여(Unity Material에 Multiple Sprite를 설정하고 싶어요!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/chikanobuitoh/items/0921bfaee7ba5c7823a7
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Unity Material에 Multiple Sprite를 설정하고 싶어요!), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/chikanobuitoh/items/0921bfaee7ba5c7823a7텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)