【问题标题】:Unity3d Line drawing with colourable materialUnity3d 用可着色材料绘制线条
【发布时间】:2018-02-03 16:05:24
【问题描述】:

我有一个客户多年前由另一位开发人员开发的项目。他们现在正在寻求使项目保持最新并进行新的更改等。项目的功能之一是着色屏幕,您可以在其中选择颜色和“笔大小”并在屏幕上绘图。

执行此操作的代码在最新的 Unity3D 下不再正常运行,并且没有正确设置颜色,而是仅绘制粉红色线条。据我了解,这是因为没有设置线的材质。

正在使用的脚本是:

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


/// <summary>
/// This class implements on-screen drawing as a post-render process.
/// </summary>



public class OnScreenDrawing : MonoBehaviour
{
    /// <summary>
    /// The color of the line.
    /// </summary>
    public Color lineColor = Color.black;

    public AudioClip Pressbutton;

    public bool clearing = false;

    /// <summary>
    /// The size of the line.
    /// </summary>
    [Range (-1, 20)] public int lineSize = 5;

    /// <summary>
    /// The line material (shader) used for drawing the lines.
    /// </summary>
    private Material lineMaterial;

    /// <summary>
    /// The previous mouse position.
    /// </summary>
    private Vector2 prevPos = Vector2.zero;

    /// <summary>
    /// The current mouse position.
    /// </summary>
    private Vector2 currPos = Vector2.zero;

    /// <summary>
    /// The list of continuous lines.
    /// </summary>
    private List<Line> lines;

    /// <summary>
    /// The current line being drawn.
    /// </summary>
    private Line currLine;

    public void coln () {
        lineColor = new Color(255.0f, 255.0f, 255.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void colq () {
        lineColor = new Color(11.0f, 148.0f, 68.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void colw () {
        lineColor = new Color(255.0f, 242.0f, 0.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void cole () {
        lineColor = new Color(101.0f, 153.0f, 255.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void cola () {
        lineColor = new Color(255.0f, 153.0f, 0.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void cols () {
        lineColor = new Color(237.0f, 28.0f, 36.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void cold () {
        lineColor = new Color(53.0f, 53.0f, 53.0f) / 255.0f;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void allgone () {
        clearing = true;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void smalls () {
        lineSize = 5;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void meds () {
        lineSize = 19;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void bigs () {
        lineSize = 35;
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
    }

    public void returns () {
        GetComponent<AudioSource>().PlayOneShot (Pressbutton);
        Application.LoadLevel ("PaintingMenu");
    }

    void Start()
    {
        lines = new List<Line>();
    }

    void Update()
    {
        // Left mouse button pressed.
        if (Input.GetButtonDown("Fire1")) {
            prevPos     = Input.mousePosition;
            currLine    = new Line(lineColor, lineSize, prevPos);

            lines.Add(currLine);
        }

        // Left mouse button held down.
        else if (Input.GetButton("Fire1")) {
            currPos = Input.mousePosition;
            if (currPos != prevPos) {
                currLine.AddPoint(currPos);
                prevPos = currPos;
            }
        }

        // Left mouse button released.
        else if (Input.GetButtonUp("Fire1")) {

        }

        // Spacebar pressed. Input.GetKeyDown(KeyCode.Space)
        else if (clearing == true) {
            for (int i = 0; i < lines.Count; i++)
                lines[i].ClearPoints();
            lines.Clear();
            clearing = false;
        }

        // Change sizes.
        else if (Input.GetKeyDown("1")) {
            lineSize = 1;
        }
        else if (Input.GetKeyDown("2")) {
            lineSize = 5;
        }
        else if (Input.GetKeyDown("3")) {
            lineSize = 15;
        }

        // Change colors
        else if (Input.GetKeyDown(KeyCode.Q)) {
            lineColor = new Color(9.0f, 112.0f, 84.0f) / 255.0f;
        }
        else if (Input.GetKeyDown(KeyCode.W)) {
            lineColor = new Color(255.0f, 222.0f, 0.0f) / 255.0f;
        }
        else if (Input.GetKeyDown(KeyCode.E)) {
            lineColor = new Color(101.0f, 153.0f, 255.0f) / 255.0f;
        }
        else if (Input.GetKeyDown(KeyCode.A)) {
            lineColor = new Color(255.0f, 153.0f, 0.0f) / 255.0f;
        }
        else if (Input.GetKeyDown(KeyCode.S)) {
            lineColor = new Color(210.0f, 67.0f, 60.0f) / 255.0f;
        }
        else if (Input.GetKeyDown(KeyCode.D)) {
            lineColor = new Color(0.0f, 0.0f, 0.0f) / 255.0f;
        }
    }

    void OnGUI()
    {
        //GUI.Label(new Rect(5.0f, 0.0f, 250.0f, 25.0f), "Press 'Space' to clear");
        //GUI.Label(new Rect(5.0f, 15.0f, 250.0f, 25.0f), "Press '1', '2' or '3' to change sizes...");
        //GUI.Label(new Rect(5.0f, 30.0f, 300.0f, 25.0f), "Press 'q', 'w', 'e', 'a', 's' or 'd' to change colors...");
    }

    void OnPostRender()
    {
        // Assign and set the current line material.
        Line.AssignLineMaterial(ref lineMaterial);
        lineMaterial.SetPass(0);

        // Setup the matrix stacks.
        GL.PushMatrix();
        GL.LoadPixelMatrix();

        // Setup the viewport.
        GL.Viewport(new Rect(0, 0, Screen.width, Screen.height));

        // Draw the lines.
        for (int i = 0; i < lines.Count; i++)
            lines[i].Draw();

        // Restore the matrix stacks.
        GL.PopMatrix();
    }
}

看着这个,我发现lineMaterial 从未设置为任何东西,所以假设这就是问题,但是当我设置基本材质并将其分配给 lineMaterial 时,我得到的只是黑线。如何正确设置材质以使用正确的颜色绘制线条?

谢谢

【问题讨论】:

  • Line.AssignLineMaterial 不是 Unity 的一部分。你为什么不发布呢?
  • 它来自一个组装打包的“ContinuousLineDLL”
  • 这很可能是问题所在......因为它包含在一个 dll 中它可能我将无法解决这个问题。但也欢迎任何关于替代方案的建议
  • 它仍然不是 Unity 的一部分。那是来自另一个人的插件。您可能想联系作者并询问他/她为什么它不起作用。同时,如果你在乎的话,还有另一种在 Unity 中画线的方法.....
  • 找到该插件的作者后,它看起来自 2013 年以来就没有被碰过,所以可以肯定地说它不再维护了。我宁愿将此功能的代码库移动到 Unity 原生或使用维护插件的东西是的。

标签: c# unity3d


【解决方案1】:

那个插件老了,很久没更新了。你甚至不需要一个插件来画一条线。 Unity 的GL API 可用于绘制线条,无需任何插件。使用GL.Color 指定线条的颜色。

GL API 是一种绘制线条的低级方法。不过,我建议您使用 Unity 的 LineRenderer 来执行此操作,因为它简化了绘图线。这意味着您必须重新编写在应用程序中绘制线条的整个代码。

下面是一个简单的函数,它根据您通过LineRenderer 传递给它的Vector3 数组绘制一条线。它绘制并关闭线(将第一个索引连接到最后一个索引)。无需插件。

//Draws lines through the provided vertices
void drawLine(Vector3[] verticesToDraw)
{
    Color beginColor = Color.yellow;
    Color endColor = Color.red;
    float lineWidth = 0.3f;

    //Create a Line Renderer Obj then make it this GameObject a parent of it
    GameObject childLineRendererObj = new GameObject("LineObj");
    childLineRendererObj.transform.SetParent(transform);

    //Create new Line Renderer if it does not exist
    LineRenderer lineRenderer = childLineRendererObj.GetComponent<LineRenderer>();
    if (lineRenderer == null)
    {
        lineRenderer = childLineRendererObj.AddComponent<LineRenderer>();
    }

    //Assign Material to the new Line Renderer
    //Hidden/Internal-Colored
    //Particles/Additive
    lineRenderer.material = new Material(Shader.Find("Hidden/Internal-Colored"));


    //Set color
    lineRenderer.startColor = beginColor;
    lineRenderer.endColor = endColor;

    //Set width
    lineRenderer.startWidth = lineWidth;
    lineRenderer.endWidth = lineWidth;

    //Convert local to world points
    for (int i = 0; i < verticesToDraw.Length; i++)
    {
        verticesToDraw[i] = gameObject.transform.TransformPoint(verticesToDraw[i]);
    }

    //5. Set the SetVertexCount of the LineRenderer to the Length of the points
    lineRenderer.positionCount = verticesToDraw.Length + 1;

    for (int i = 0; i < verticesToDraw.Length; i++)
    {
        //Draw the  line
        Vector3 finalLine = verticesToDraw[i];
        lineRenderer.SetPosition(i, finalLine);

        //Check if this is the last loop. Now Close the Line drawn
        if (i == (verticesToDraw.Length - 1))
        {
            finalLine = verticesToDraw[0];
            lineRenderer.SetPosition(verticesToDraw.Length, finalLine);
        }
    }
}

【讨论】:

  • 感谢您的代码,尽管我不确定如何以替换当前脚本的方式实现此代码
猜你喜欢
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多