简单的贴花系统只在编辑器中工作

时间:2015-02-18 16:42:36

标签: c# unity3d assets

我开发了Web Player应用程序。 在场景中我有一些3D模型(例如:框)。 在运行时我上传* .png图像,在Decal上使用此图像到我的车上。 我使用这个包:https://www.assetstore.unity3d.com/en/#!/content/13889用于贴花系统。 我编辑工作正常,但在运行时我不能在贴花系统中使用我的图片。 任务:需要随时更换图片,它在贴花系统中变得很好。 请帮我。 谢谢!

public GameObject decal;
public Material mat;
Texture2D texTmp;
Sprite spr;
string settingsContent;
string[] settingsSplit;

int texWidth,texHeight;

void Awake()
{
    StartCoroutine(DownloadSettings());
}

IEnumerator DownloadSettings()
{
    WWW www = new WWW("http://585649.workwork.web.hosting-test.net/Logo1/settings.txt");
    yield return www;
    settingsContent = www.text;
    settingsSplit = settingsContent.Split('\n');
    if (www.isDone)
    {
        texWidth = int.Parse(settingsSplit[1]);
        texHeight = int.Parse(settingsSplit[2]);
        texTmp = new Texture2D(texWidth,texHeight);
        StartCoroutine(DownloadLogos());
    }
}

IEnumerator DownloadLogos()
{
    WWW www = new WWW(settingsSplit[0]);
    yield return www;
    www.LoadImageIntoTexture(texTmp);
    if (www.isDone)
    {
        spr = Sprite.Create(texTmp, new Rect(0, 0, texTmp.width, texTmp.height), Vector2.zero, 100);
        spr.texture.wrapMode = TextureWrapMode.Clamp;
        mat.mainTexture = spr.texture;
        Color clr = new Color32(255,255,255,255);
        clr.a = float.Parse(settingsSplit[3]);
        mat.color = clr;
        decal.AddComponent("Decal");
        decal.GetComponent<Decal>().material = mat;
        decal.GetComponent<Decal>().sprite = spr;
    }
}

3 个答案:

答案 0 :(得分:1)

我明白了。谢谢大家!

public Decal decal;
public Material mat;
Texture2D texTmp;
Sprite spr;
string settingsContent;
string[] settingsSplit;

int texWidth,texHeight;
float sizeX, sizeY;

void Awake()
{
    StartCoroutine(DownloadSettings());
}

IEnumerator DownloadSettings()
{
    WWW www = new WWW("http://sitesman.com/logotypes/Logo1/settings.txt");
    yield return www;
    settingsContent = www.text;
    settingsSplit = settingsContent.Split('\n');
    if (www.isDone)
    {
        texWidth = int.Parse(settingsSplit[1]);
        texHeight = int.Parse(settingsSplit[2]);
        texTmp = new Texture2D(texWidth,texHeight);

        if(texWidth > texHeight)
        {
            sizeX = texWidth / texHeight;
            sizeY = 1;
        }
        else if (texWidth < texHeight)
        {
            sizeX = 1;
            sizeY = texHeight / texWidth;
        }
        else
        {
            sizeX = 1;
            sizeY = 1;
        }

        float multipier = 1;

        if(settingsSplit[4] != null)
        {
            multipier = float.Parse(settingsSplit[4]);
        }

        decal.transform.localScale = new Vector3(sizeX*multipier,sizeY*multipier,2f);

        StartCoroutine(DownloadLogos());
    }
}

IEnumerator DownloadLogos()
{
    WWW www = new WWW(settingsSplit[0]);
    yield return www;
    www.LoadImageIntoTexture(texTmp);
    if (www.isDone)
    {
        spr = Sprite.Create(texTmp, new Rect(0, 0, texTmp.width, texTmp.height), Vector2.zero, 100);
        spr.texture.wrapMode = TextureWrapMode.Clamp;
        mat.mainTexture = spr.texture;
        Color clr = new Color32(255,255,255,255);
        clr.a = float.Parse(settingsSplit[3]);
        mat.color = clr;
        decal.material = mat;
        decal.sprite = spr;
        BuildDecal(decal);
    }
}

GameObject go;
private GameObject[] affectedObjects;

private void BuildDecal(Decal decal)
{
    MeshFilter filter = decal.GetComponent<MeshFilter>();
    if (filter == null) filter = decal.gameObject.AddComponent<MeshFilter>();
    if (decal.renderer == null) decal.gameObject.AddComponent<MeshRenderer>();
    decal.renderer.material = decal.material;

    if (decal.material == null || decal.sprite == null)
    {
        filter.mesh = null;
        return;
    }

    affectedObjects = GetAffectedObjects(decal.GetBounds(), decal.affectedLayers);
    foreach (GameObject go in affectedObjects)
    {
        DecalBuilder.BuildDecalForObject(decal, go);
    }
    DecalBuilder.Push(decal.pushDistance);

    Mesh mesh = DecalBuilder.CreateMesh();
    if (mesh != null)
    {
        mesh.name = "DecalMesh";
        filter.mesh = mesh;
    }
}

private static GameObject[] GetAffectedObjects(Bounds bounds, LayerMask affectedLayers)
{
    MeshRenderer[] renderers = (MeshRenderer[])GameObject.FindObjectsOfType<MeshRenderer>();
    List<GameObject> objects = new List<GameObject>();
    foreach (Renderer r in renderers)
    {
        if (!r.enabled) continue;
       // if (!IsLayerContains(affectedLayers, r.gameObject.layer)) continue;
        if (r.GetComponent<Decal>() != null) continue;

        if (bounds.Intersects(r.bounds))
        {
            objects.Add(r.gameObject);
        }
    }
    return objects.ToArray();
}

答案 1 :(得分:1)

通过以下链接或通过Unity Asset Store将免费资产“基本贴花系统”导入Unity。

https://assetstore.unity.com/packages/tools/particles-effects/simple-decal-system-13889

根据需要为贴花准备合适的图像,并具有透明性。以TARGA(.tga)格式保存文件,然后在合适的位置导入Unity。

***注意。创建一个包含一张纸作为贴图的图像文件比较整洁。

从图像创建精灵 在Assets中选择图像文件,然后在检查器中将Texture类型更改为Sprite(2D和UI),然后按Apply。

如果图像文件仅包含一张图像,请从检查器中将其作为精灵模式选择单张。如果创建了一张图像,则选择“多个”,然后可以选择“ Sprite编辑器”并通过在图像上的每个图像周围绘制边界并提供合适的名称来创建多个Sprite。精灵将以飞出的形式出现在原始图像下。

创建材料 创建一个新材料。然后,材料名称必须以“贴花”开头。在检查器中,将着色器更改为“旧式着色器/透明度/漫反射”,然后单击“选择”,然后选择包含精灵的图像。

创建贴图 在场景中创建一个多维数据集,重命名为合适的名称,然后从Assets> DecalSystem> Plugins> Decalsystem中,将脚本“ Decal”拖放到多维数据集上。多维数据集现在将是线框外观。在“贴图脚本”部分的检查器中,选择之前创建的材质,然后从下拉列表中选择精灵。

将立方体放置在要投影的网格上(您可能必须旋转立方体以对齐投影面)。

贴花在运行时不渲染。要贴花贴图,请执行以下步骤。

创建一个空的游戏对象,并用“ Pos”后缀将其与贴花有关。选择贴花立方体对象,然后单击检查器的“变换”部分中的设置图标,然后复制组件。选择一个空的游戏对象,然后在检查器的“转换”部分中单击设置图标,并粘贴组件值,然后将xyz比例值更改为“ 1”。在层次结构中,将贴花立方体对象拖放到空位置对象上。

选择空位置对象,然后从检查器中单击添加组件,然后选择“ Decal_Script”脚本。 Decal_Script

在检查器中,将Decal Cube对象拖动(或从右侧的按钮中选择)到“ This Decal”框。

贴花现在应该在运行时出现。

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

public class Decal_Script : MonoBehaviour
{
   public GameObject ThisDecal;

    // Start is called before the first frame update
    void Start()
    {

         CreatePrefab();

    }

    // Update is called once per frame
    void Update()
    {

    }

    void CreatePrefab()
    {
       // instantiate decal

        GameObject obj = Instantiate(ThisDecal, ThisDecal.transform.position, ThisDecal.transform.rotation);

        //decal implementation!!
        var decal = obj.GetComponent<Decal>();
        if (decal) //if this obj has decal script
        {
            var filter = decal.GetComponent<MeshFilter>();
            var mesh = filter.mesh;
            if (mesh != null)
            {
                mesh.name = "DecalMesh";
                filter.mesh = mesh;
            }
            DecalBuilder.Build(decal);

        }

   }
}

答案 2 :(得分:0)

我决定在@ NoIQ的答案基础上再创造一些更便携的东西:

.fullsize {
  position: absolute;
  left: 40vw;
}

要使用,您需要将Editor文件夹中的脚本移动到父目录。以下是我使用脚本添加动态枪贴的方法:

using UnityEngine;
using System.Collections.Generic;

/*
  http://stackoverflow.com/a/28603035/3990396
*/
public class DecalDynamic {
    public static void BuildDecal(Decal decal) {
        MeshFilter filter = decal.GetComponent<MeshFilter>();
        if (filter == null) filter = decal.gameObject.AddComponent<MeshFilter>();
        if (decal.GetComponent<Renderer>() == null) decal.gameObject.AddComponent<MeshRenderer>();
        decal.GetComponent<Renderer>().material = decal.material;

        if (decal.material == null || decal.sprite == null) {
            filter.mesh = null;
            return;
        }

        GameObject[] affectedObjects = GetAffectedObjects(decal.GetBounds(), decal.affectedLayers);
        foreach (GameObject go in affectedObjects) {
            DecalBuilder.BuildDecalForObject(decal, go);
        }
        DecalBuilder.Push(decal.pushDistance);

        Mesh mesh = DecalBuilder.CreateMesh();
        if (mesh != null) {
            mesh.name = "DecalMesh";
            filter.mesh = mesh;
        }
    }

    public static GameObject[] GetAffectedObjects(Bounds bounds, LayerMask affectedLayers) {
        MeshRenderer[] renderers = (MeshRenderer[])GameObject.FindObjectsOfType<MeshRenderer>();
        List<GameObject> objects = new List<GameObject>();

        foreach (Renderer r in renderers) {
            if (!r.enabled || r.GetComponent<Decal>() != null) continue;
            if (bounds.Intersects(r.bounds)) objects.Add(r.gameObject);
        }
        return objects.ToArray();
    }
}